소스 검색

fix some bug and update rtt driver

luobeihai 2 년 전
부모
커밋
9b85f8ac06
35개의 변경된 파일7166개의 추가작업 그리고 930개의 파일을 삭제
  1. 325 79
      project_0/.config
  2. 4 0
      project_0/.cproject
  3. 2 2
      project_0/.settings/projcfg.ini
  4. 1 1
      project_0/board/Kconfig
  5. 1 0
      project_0/board/board.h
  6. 4 3
      project_0/board/linker_scripts/link.lds
  7. 1424 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/inc/apm32f4xx_eth.h
  8. 2308 0
      project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/src/apm32f4xx_eth.c
  9. 9 4
      project_0/libraries/APM32F4xx_Library/SConscript
  10. 7 3
      project_0/libraries/Drivers/SConscript
  11. 105 36
      project_0/libraries/Drivers/drv_adc.c
  12. 1 1
      project_0/libraries/Drivers/drv_common.c
  13. 47 15
      project_0/libraries/Drivers/drv_dac.c
  14. 780 0
      project_0/libraries/Drivers/drv_eth.c
  15. 92 0
      project_0/libraries/Drivers/drv_eth.h
  16. 238 111
      project_0/libraries/Drivers/drv_gpio.c
  17. 230 115
      project_0/libraries/Drivers/drv_hwtimer.c
  18. 27 0
      project_0/libraries/Drivers/drv_log.h
  19. 149 135
      project_0/libraries/Drivers/drv_pwm.c
  20. 76 31
      project_0/libraries/Drivers/drv_rtc.c
  21. 22 22
      project_0/libraries/Drivers/drv_soft_i2c.c
  22. 175 165
      project_0/libraries/Drivers/drv_spi.c
  23. 16 0
      project_0/libraries/Drivers/drv_spi.h
  24. 209 20
      project_0/libraries/Drivers/drv_usart.c
  25. 18 6
      project_0/libraries/Drivers/drv_wdt.c
  26. 6 1
      project_0/libraries/Kconfig
  27. 2 2
      project_0/project.ewp
  28. 760 4
      project_0/project.uvoptx
  29. 76 154
      project_0/project.uvprojx
  30. 43 10
      project_0/rtconfig.h
  31. 1 2
      project_0/rtconfig_preinc.h
  32. 2 2
      project_0/template.ewp
  33. 2 2
      project_0/template.uvoptx
  34. 3 3
      project_0/template.uvprojx
  35. 1 1
      sdk-bsp-apm32f407vg-geehy-mini.yaml

+ 325 - 79
project_0/.config

@@ -8,8 +8,9 @@
 #
 CONFIG_RT_NAME_MAX=8
 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+# CONFIG_RT_USING_SMART is not set
 # CONFIG_RT_USING_SMP is not set
-CONFIG_RT_ALIGN_SIZE=4
+CONFIG_RT_ALIGN_SIZE=8
 # CONFIG_RT_THREAD_PRIORITY_8 is not set
 CONFIG_RT_THREAD_PRIORITY_32=y
 # CONFIG_RT_THREAD_PRIORITY_256 is not set
@@ -59,6 +60,7 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
 #
 # Memory Management
 #
+CONFIG_RT_PAGE_MAX_ORDER=11
 CONFIG_RT_USING_MEMPOOL=y
 CONFIG_RT_USING_SMALL_MEM=y
 # CONFIG_RT_USING_SLAB is not set
@@ -77,16 +79,19 @@ CONFIG_RT_USING_HEAP=y
 #
 CONFIG_RT_USING_DEVICE=y
 # CONFIG_RT_USING_DEVICE_OPS is not set
+# CONFIG_RT_USING_DM is not set
 # CONFIG_RT_USING_INTERRUPT_INFO is not set
 CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
-CONFIG_RT_VER_NUM=0x40101
-CONFIG_ARCH_ARM=y
+CONFIG_RT_VER_NUM=0x50000
+# CONFIG_RT_USING_CACHE is not set
+# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 CONFIG_RT_USING_CPU_FFS=y
+CONFIG_ARCH_ARM=y
 CONFIG_ARCH_ARM_CORTEX_M=y
 CONFIG_ARCH_ARM_CORTEX_M4=y
-# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 
 #
 # RT-Thread Components
@@ -121,14 +126,16 @@ CONFIG_DFS_FD_MAX=16
 # CONFIG_RT_USING_DFS_ELMFAT is not set
 # CONFIG_RT_USING_DFS_DEVFS is not set
 # CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_CROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_TMPFS is not set
 # CONFIG_RT_USING_FAL is not set
-# CONFIG_RT_USING_LWP is not set
 
 #
 # Device Drivers
 #
 CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_UNAMED_PIPE_NUMBER=64
 # CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
 CONFIG_RT_USING_SERIAL=y
 CONFIG_RT_USING_SERIAL_V1=y
@@ -143,10 +150,14 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
 CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_ADC is not set
 # CONFIG_RT_USING_DAC is not set
+# CONFIG_RT_USING_NULL is not set
+# CONFIG_RT_USING_ZERO is not set
+# CONFIG_RT_USING_RANDOM is not set
 # CONFIG_RT_USING_PWM is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
+# CONFIG_RT_USING_FDT is not set
 # CONFIG_RT_USING_RTC is not set
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SPI is not set
@@ -154,10 +165,13 @@ CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_AUDIO is not set
 # CONFIG_RT_USING_SENSOR is not set
 # CONFIG_RT_USING_TOUCH is not set
+# CONFIG_RT_USING_LCD is not set
 # CONFIG_RT_USING_HWCRYPTO is not set
 # CONFIG_RT_USING_PULSE_ENCODER is not set
 # CONFIG_RT_USING_INPUT_CAPTURE is not set
+# CONFIG_RT_USING_DEV_BUS is not set
 # CONFIG_RT_USING_WIFI is not set
+# CONFIG_RT_USING_VIRTIO is not set
 
 #
 # Using USB
@@ -302,6 +316,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_AGILE_FTP is not set
 # CONFIG_PKG_USING_EMBEDDEDPROTO is not set
 # CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_RYANMQTT is not set
+# CONFIG_PKG_USING_RYANW5500 is not set
 # CONFIG_PKG_USING_LORA_PKT_FWD is not set
 # CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
 # CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
@@ -309,6 +325,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SMALL_MODBUS is not set
 # CONFIG_PKG_USING_NET_SERVER is not set
 # CONFIG_PKG_USING_ZFTP is not set
+# CONFIG_PKG_USING_WOL is not set
 
 #
 # security packages
@@ -377,12 +394,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_MP3PLAYER is not set
 # CONFIG_PKG_USING_TINYJPEG is not set
 # CONFIG_PKG_USING_UGUI is not set
-
-#
-# PainterEngine: A cross-platform graphics application framework written in C language
-#
-# CONFIG_PKG_USING_PAINTERENGINE is not set
-# CONFIG_PKG_USING_PAINTERENGINE_AUX is not set
 # CONFIG_PKG_USING_MCURSES is not set
 # CONFIG_PKG_USING_TERMBOX is not set
 # CONFIG_PKG_USING_VT100 is not set
@@ -398,9 +409,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_EASYLOGGER is not set
 # CONFIG_PKG_USING_SYSTEMVIEW is not set
 # CONFIG_PKG_USING_SEGGER_RTT is not set
+# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set
 # CONFIG_PKG_USING_RDB is not set
 # CONFIG_PKG_USING_ULOG_EASYFLASH is not set
-# CONFIG_PKG_USING_ULOG_FILE is not set
 # CONFIG_PKG_USING_LOGMGR is not set
 # CONFIG_PKG_USING_ADBD is not set
 # CONFIG_PKG_USING_COREMARK is not set
@@ -434,8 +445,8 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_CBOX is not set
 # CONFIG_PKG_USING_SNOWFLAKE is not set
 # CONFIG_PKG_USING_HASH_MATCH is not set
-# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
 # CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
+# CONFIG_PKG_USING_VOFA_PLUS is not set
 
 #
 # system packages
@@ -471,7 +482,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_UC_CLK is not set
 # CONFIG_PKG_USING_UC_COMMON is not set
 # CONFIG_PKG_USING_UC_MODBUS is not set
-# CONFIG_PKG_USING_RTDUINO is not set
 # CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
 # CONFIG_PKG_USING_CAIRO is not set
 # CONFIG_PKG_USING_PIXMAN is not set
@@ -506,19 +516,95 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_KMULTI_RTIMER is not set
 # CONFIG_PKG_USING_TFDB is not set
 # CONFIG_PKG_USING_QPC is not set
+# CONFIG_PKG_USING_AGILE_UPGRADE is not set
+# CONFIG_PKG_USING_FLASH_BLOB is not set
 
 #
 # peripheral libraries and drivers
 #
-# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
-# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+
+#
+# sensors drivers
+#
+# CONFIG_PKG_USING_LSM6DSM is not set
+# CONFIG_PKG_USING_LSM6DSL is not set
+# CONFIG_PKG_USING_LPS22HB is not set
+# CONFIG_PKG_USING_HTS221 is not set
+# CONFIG_PKG_USING_LSM303AGR is not set
+# CONFIG_PKG_USING_BME280 is not set
+# CONFIG_PKG_USING_BME680 is not set
+# CONFIG_PKG_USING_BMA400 is not set
+# CONFIG_PKG_USING_BMI160_BMX160 is not set
+# CONFIG_PKG_USING_SPL0601 is not set
+# CONFIG_PKG_USING_MS5805 is not set
+# CONFIG_PKG_USING_DA270 is not set
+# CONFIG_PKG_USING_DF220 is not set
+# CONFIG_PKG_USING_HSHCAL001 is not set
+# CONFIG_PKG_USING_BH1750 is not set
+# CONFIG_PKG_USING_MPU6XXX is not set
+# CONFIG_PKG_USING_AHT10 is not set
+# CONFIG_PKG_USING_AP3216C is not set
+# CONFIG_PKG_USING_TSL4531 is not set
+# CONFIG_PKG_USING_DS18B20 is not set
+# CONFIG_PKG_USING_DHT11 is not set
+# CONFIG_PKG_USING_DHTXX is not set
+# CONFIG_PKG_USING_GY271 is not set
+# CONFIG_PKG_USING_GP2Y10 is not set
+# CONFIG_PKG_USING_SGP30 is not set
+# CONFIG_PKG_USING_HDC1000 is not set
+# CONFIG_PKG_USING_BMP180 is not set
+# CONFIG_PKG_USING_BMP280 is not set
+# CONFIG_PKG_USING_SHTC1 is not set
+# CONFIG_PKG_USING_BMI088 is not set
+# CONFIG_PKG_USING_HMC5883 is not set
+# CONFIG_PKG_USING_MAX6675 is not set
+# CONFIG_PKG_USING_TMP1075 is not set
+# CONFIG_PKG_USING_SR04 is not set
+# CONFIG_PKG_USING_CCS811 is not set
+# CONFIG_PKG_USING_PMSXX is not set
+# CONFIG_PKG_USING_RT3020 is not set
+# CONFIG_PKG_USING_MLX90632 is not set
+# CONFIG_PKG_USING_MLX90393 is not set
+# CONFIG_PKG_USING_MLX90392 is not set
+# CONFIG_PKG_USING_MLX90397 is not set
+# CONFIG_PKG_USING_MS5611 is not set
+# CONFIG_PKG_USING_MAX31865 is not set
+# CONFIG_PKG_USING_VL53L0X is not set
+# CONFIG_PKG_USING_INA260 is not set
+# CONFIG_PKG_USING_MAX30102 is not set
+# CONFIG_PKG_USING_INA226 is not set
+# CONFIG_PKG_USING_LIS2DH12 is not set
+# CONFIG_PKG_USING_HS300X is not set
+# CONFIG_PKG_USING_ZMOD4410 is not set
+# CONFIG_PKG_USING_ISL29035 is not set
+# CONFIG_PKG_USING_MMC3680KJ is not set
+# CONFIG_PKG_USING_QMP6989 is not set
+# CONFIG_PKG_USING_BALANCE is not set
 # CONFIG_PKG_USING_SHT2X is not set
 # CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AD7746 is not set
 # CONFIG_PKG_USING_ADT74XX is not set
+# CONFIG_PKG_USING_MAX17048 is not set
 # CONFIG_PKG_USING_AS7341 is not set
+# CONFIG_PKG_USING_CW2015 is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_STHS34PF80 is not set
+
+#
+# touch drivers
+#
+# CONFIG_PKG_USING_GT9147 is not set
+# CONFIG_PKG_USING_GT1151 is not set
+# CONFIG_PKG_USING_GT917S is not set
+# CONFIG_PKG_USING_GT911 is not set
+# CONFIG_PKG_USING_FT6206 is not set
+# CONFIG_PKG_USING_FT5426 is not set
+# CONFIG_PKG_USING_FT6236 is not set
+# CONFIG_PKG_USING_XPT2046_TOUCH is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ESP_IDF is not set
-# CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_BUTTON is not set
 # CONFIG_PKG_USING_PCF8574 is not set
 # CONFIG_PKG_USING_SX12XX is not set
@@ -541,12 +627,9 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_AGILE_LED is not set
 # CONFIG_PKG_USING_AT24CXX is not set
 # CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
-# CONFIG_PKG_USING_AD7746 is not set
 # CONFIG_PKG_USING_PCA9685 is not set
 # CONFIG_PKG_USING_I2C_TOOLS is not set
 # CONFIG_PKG_USING_NRF24L01 is not set
-# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
-# CONFIG_PKG_USING_MAX17048 is not set
 # CONFIG_PKG_USING_RPLIDAR is not set
 # CONFIG_PKG_USING_AS608 is not set
 # CONFIG_PKG_USING_RC522 is not set
@@ -561,7 +644,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_CAN_YMODEM is not set
 # CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
 # CONFIG_PKG_USING_QLED is not set
-# CONFIG_PKG_USING_PAJ7620 is not set
 # CONFIG_PKG_USING_AGILE_CONSOLE is not set
 # CONFIG_PKG_USING_LD3320 is not set
 # CONFIG_PKG_USING_WK2124 is not set
@@ -592,10 +674,11 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_BL_MCU_SDK is not set
 # CONFIG_PKG_USING_SOFT_SERIAL is not set
 # CONFIG_PKG_USING_MB85RS16 is not set
-# CONFIG_PKG_USING_CW2015 is not set
 # CONFIG_PKG_USING_RFM300 is not set
 # CONFIG_PKG_USING_IO_INPUT_FILTER is not set
 # CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
+# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
+# CONFIG_PKG_USING_FINGERPRINT is not set
 
 #
 # AI packages
@@ -610,6 +693,12 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_QUEST is not set
 # CONFIG_PKG_USING_NAXOS is not set
 
+#
+# Signal Processing and Control Algorithm Packages
+#
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
+# CONFIG_PKG_USING_UKAL is not set
+
 #
 # miscellaneous packages
 #
@@ -639,6 +728,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_TETRIS is not set
 # CONFIG_PKG_USING_DONUT is not set
 # CONFIG_PKG_USING_COWSAY is not set
+# CONFIG_PKG_USING_MORSE is not set
 # CONFIG_PKG_USING_LIBCSV is not set
 # CONFIG_PKG_USING_OPTPARSE is not set
 # CONFIG_PKG_USING_FASTLZ is not set
@@ -661,7 +751,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_VI is not set
 # CONFIG_PKG_USING_KI is not set
 # CONFIG_PKG_USING_ARMv7M_DWT is not set
-# CONFIG_PKG_USING_UKAL is not set
 # CONFIG_PKG_USING_CRCLIB is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_STATE_MACHINE is not set
@@ -672,70 +761,227 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_SLCAN2RTT is not set
 # CONFIG_PKG_USING_SOEM is not set
 # CONFIG_PKG_USING_QPARAM is not set
+# CONFIG_PKG_USING_CorevMCU_CLI is not set
 
 #
-# Privated Packages of RealThread
-#
-# CONFIG_PKG_USING_CODEC is not set
-# CONFIG_PKG_USING_PLAYER is not set
-# CONFIG_PKG_USING_MPLAYER is not set
-# CONFIG_PKG_USING_PERSIMMON_SRC is not set
-# CONFIG_PKG_USING_JS_PERSIMMON is not set
-# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
-
-#
-# Network Utilities
-#
-# CONFIG_PKG_USING_WICED is not set
-# CONFIG_PKG_USING_CLOUDSDK is not set
-# CONFIG_PKG_USING_POWER_MANAGER is not set
-# CONFIG_PKG_USING_RT_OTA is not set
-# CONFIG_PKG_USING_RTINSIGHT is not set
-# CONFIG_PKG_USING_SMARTCONFIG is not set
-# CONFIG_PKG_USING_RTX is not set
-# CONFIG_RT_USING_TESTCASE is not set
-# CONFIG_PKG_USING_NGHTTP2 is not set
-# CONFIG_PKG_USING_AVS is not set
-# CONFIG_PKG_USING_ALI_LINKKIT is not set
-# CONFIG_PKG_USING_STS is not set
-# CONFIG_PKG_USING_DLMS is not set
-# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
-# CONFIG_PKG_USING_ZBAR is not set
-# CONFIG_PKG_USING_MCF is not set
-# CONFIG_PKG_USING_URPC is not set
-# CONFIG_PKG_USING_DCM is not set
-# CONFIG_PKG_USING_EMQ is not set
-# CONFIG_PKG_USING_CFGM is not set
-# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
-# CONFIG_PKG_USING_SMODULE is not set
-# CONFIG_PKG_USING_SNFD is not set
-# CONFIG_PKG_USING_UDBD is not set
-# CONFIG_PKG_USING_BENCHMARK is not set
-# CONFIG_PKG_USING_UBJSON is not set
-# CONFIG_PKG_USING_DATATYPE is not set
-# CONFIG_PKG_USING_FASTFS is not set
-# CONFIG_PKG_USING_RIL is not set
-# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
-# CONFIG_PKG_USING_WATCH_APP_FWK is not set
-# CONFIG_PKG_USING_GUI_TEST is not set
-# CONFIG_PKG_USING_PMEM is not set
-# CONFIG_PKG_USING_LWRDP is not set
-# CONFIG_PKG_USING_MASAN is not set
-# CONFIG_PKG_USING_BSDIFF_LIB is not set
-# CONFIG_PKG_USING_PRC_DIFF is not set
-
-#
-# RT-Thread Smart
-#
-# CONFIG_PKG_USING_UKERNEL is not set
-# CONFIG_PKG_USING_TRACE_AGENT is not set
+# Arduino libraries
+#
+# CONFIG_PKG_USING_RTDUINO is not set
+
+#
+# Projects
+#
+# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
+# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
+# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
+
+#
+# Sensors
+#
+# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set
+# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
+# CONFIG_PKG_USING_ADAFRUIT_MSA301 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
+# CONFIG_PKG_USING_SEEED_ITG3200 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
+# CONFIG_PKG_USING_SEEED_MP503 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
+
+#
+# Display
+#
+# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
+# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set
+# CONFIG_PKG_USING_SEEED_TM1637 is not set
+
+#
+# Timing
+#
+# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
+
+#
+# Data Processing
+#
+# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
+# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
+
+#
+# Data Storage
+#
+
+#
+# Communication
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
+
+#
+# Device Control
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set
+
+#
+# Other
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set
+# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set
+
+#
+# Signal IO
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
+
+#
+# Uncategorized
+#
 CONFIG_SOC_FAMILY_APM32=y
 CONFIG_SOC_SERIES_APM32F4=y
 
 #
 # Hardware Drivers Config
 #
-CONFIG_SOC_APM32F407VG=y
+CONFIG_SOC_APM32F407IG=y
 
 #
 # On-chip Peripheral Drivers

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 4 - 0
project_0/.cproject


+ 2 - 2
project_0/.settings/projcfg.ini

@@ -1,5 +1,5 @@
 #RT-Thread Studio Project Configuration
-# Fri Sep 16 15:03:00 2022
+# Fri Mar 10 10:46:23 2023
 cfg_version=v3.0
 
 board_name=
@@ -17,4 +17,4 @@ project_type=rt-thread
 os_branch=master
 os_version=latest
 project_name=project_0
-output_project_path=C:\Users\apex\Documents\rt-thread1\bsp\apm32\apm32f407vg-minibroard\rtt_studio
+output_project_path=D:\study material\RT-Thread\2023011402\rt-thread\bsp\apm32\apm32f407vg-minibroard\project_0

+ 1 - 1
project_0/board/Kconfig

@@ -1,6 +1,6 @@
 menu "Hardware Drivers Config"
 
-config SOC_APM32F407VG
+config SOC_APM32F407IG
     bool
     select SOC_SERIES_APM32F4
     select RT_USING_COMPONENTS_INIT

+ 1 - 0
project_0/board/board.h

@@ -15,6 +15,7 @@
 #include <apm32f4xx.h>
 
 #include "apm32f4xx_gpio.h"
+#include "apm32f4xx_syscfg.h"
 #include "apm32f4xx_rcm.h"
 #include "apm32f4xx_misc.h"
 #include "apm32f4xx_rcm.h"

+ 4 - 3
project_0/board/linker_scripts/link.lds

@@ -1,5 +1,5 @@
 /*
- * linker script for APM32F10x with GNU ld
+ * linker script for APM32F40x with GNU ld
  */
 
 /* Program Entry, set to mark it as "used" and avoid gc */
@@ -77,11 +77,12 @@ SECTIONS
         _edata = . ;
     } >DATA
 
-    .stack : 
+    .stack :
     {
         . = . + _system_stack_size;
         . = ALIGN(4);
         _estack = .;
+        _end_stack = .;
     } >DATA
 
     __bss_start = .;
@@ -98,7 +99,7 @@ SECTIONS
         . = ALIGN(4);
         /* This is used by the startup in order to initialize the .bss secion */
         _ebss = . ;
-        
+
         *(.bss.init)
     } > DATA
     __bss_end = .;

+ 1424 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/inc/apm32f4xx_eth.h

@@ -0,0 +1,1424 @@
+/*!
+ * @file        apm32f4xx_eth.c
+ *
+ * @brief       This file provides all the ETH firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+/* Define to prevent recursive inclusion */
+#ifndef __APM32F4xx_ETH_H
+#define __APM32F4xx_ETH_H
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+/* Includes */
+#include "apm32f4xx.h"
+
+/** @addtogroup APM32F4xx_ETHDriver
+  @{
+*/
+
+/** @addtogroup ETH_Driver
+  @{
+*/
+
+/** @defgroup ETH_Enumerations
+  @{
+*/
+
+/**
+ * @brief    ETH AutoNegotiation
+ */
+typedef enum
+{
+    ETH_AUTONEGOTIATION_DISABLE,    /*!< Disable negotiation */
+    ETH_AUTONEGOTIATION_ENABLE      /*!< Enable negotiation */
+} ETH_AUTONEGOTIATION_T;
+
+/**
+ * @brief    ETH Watchdog
+ */
+typedef enum
+{
+    ETH_WATCHDOG_ENABLE,    /*!< Enable watch dog */
+    ETH_WATCHDOG_DISABLE    /*!< Disable watch dog */
+} ETH_WATCHDOG_T;
+
+/**
+ * @brief    ETH Jabber
+ */
+typedef enum
+{
+    ETH_JABBER_ENABLE,  /*!< Enable jabber */
+    ETH_JABBER_DISABLE  /*!< Disable jabber */
+} ETH_JABBER_T;
+
+/**
+ * @brief    ETH Inter Frame Gap
+ */
+typedef enum
+{
+    ETH_INTERFRAMEGAP_96BIT = 0x00, /*!< Inter-Frame gap = 96-bit */
+    ETH_INTERFRAMEGAP_88BIT = 0x01, /*!< Inter-Frame gap = 88-bit */
+    ETH_INTERFRAMEGAP_80BIT = 0x02, /*!< Inter-Frame gap = 80-bit */
+    ETH_INTERFRAMEGAP_72BIT = 0x03, /*!< Inter-Frame gap = 72-bit */
+    ETH_INTERFRAMEGAP_64BIT = 0x04, /*!< Inter-Frame gap = 64-bit */
+    ETH_INTERFRAMEGAP_56BIT = 0x05, /*!< Inter-Frame gap = 56-bit */
+    ETH_INTERFRAMEGAP_48BIT = 0x06, /*!< Inter-Frame gap = 48-bit */
+    ETH_INTERFRAMEGAP_40BIT = 0x07  /*!< Inter-Frame gap = 40-bit */
+} ETH_INTERFRAMEGAP_T;
+
+/**
+ * @brief    ETH Carrier Sense
+ */
+typedef enum
+{
+    ETH_CARRIERSENCE_ENABLE,    /*!< Disable carrier sense during transmission */
+    ETH_CARRIERSENCE_DISABLE    /*!< Ignore MII CRS signal */
+} ETH_CARRIERSENCE_T;
+
+/**
+ * @brief    ETH Speed
+ */
+typedef enum
+{
+    ETH_SPEED_10M,  /*!< 10M speed */
+    ETH_SPEED_100M  /*!< 100M speed */
+} ETH_SPEED_T;
+
+/**
+ * @brief    ETH Receive Own
+ */
+typedef enum
+{
+    ETH_RECEIVEOWN_ENABLE,  /*!< Enable receive own */
+    ETH_RECEIVEOWN_DISABLE  /*!< Disable receive own */
+} ETH_RECEIVEOWN_T;
+
+/**
+ * @brief    ETH Loop Back Mode
+ */
+typedef enum
+{
+    ETH_LOOPBACKMODE_DISABLE,   /*!< Disable loopback mode */
+    ETH_LOOPBACKMODE_ENABLE     /*!< Enable loopback mode */
+} ETH_LOOPBACKMODE_T;
+
+/**
+ * @brief    ETH Duplex Mode
+ */
+typedef enum
+{
+    ETH_MODE_HALFDUPLEX,    /*!< Half-Duplex */
+    ETH_MODE_FULLDUPLEX     /*!< Full-Duplex */
+} ETH_MODE_T;
+
+/**
+ * @brief    ETH Checksum Offload
+ */
+typedef enum
+{
+    ETH_CHECKSUMOFFLAOD_DISABLE,    /*!< Disable IPv4 checksum offload */
+    ETH_CHECKSUMOFFLAOD_ENABLE      /*!< Enable Ipv4 checksum offload */
+} ETH_CHECKSUMOFFLAOD_T;
+
+/**
+ * @brief    ETH Retry Transmission
+ */
+typedef enum
+{
+    ETH_RETRYTRANSMISSION_ENABLE,   /*!< Enable retry */
+    ETH_RETRYTRANSMISSION_DISABLE   /*!< Disable retry */
+} ETH_RETRYTRANSMISSION_T;
+
+/**
+ * @brief    ETH Automatic Pad CRC Strip
+ */
+typedef enum
+{
+    ETH_AUTOMATICPADCRCSTRIP_DISABLE,   /*!< Disable automatic pad or CRC stripping */
+    ETH_AUTOMATICPADCRCSTRIP_ENABLE     /*!< Enable automatic pad or CRC stripping */
+} ETH_AUTOMATICPADCRCSTRIP_T;
+
+/**
+ * @brief    ETH Back Off Limit
+ */
+typedef enum
+{
+    ETH_BACKOFFLIMIT_10,    /*!< Set back off limit to 10 */
+    ETH_BACKOFFLIMIT_8,     /*!< Set back off limit to 18 */
+    ETH_BACKOFFLIMIT_4,     /*!< Set back off limit to 4 */
+    ETH_BACKOFFLIMIT_1      /*!< Set back off limit to 1 */
+} ETH_BACKOFFLIMIT_T;
+
+/**
+ * @brief    ETH Deferral Check
+ */
+typedef enum
+{
+    ETH_DEFFERRALCHECK_DISABLE, /*!< Disable deferral check */
+    ETH_DEFFERRALCHECK_ENABLE   /*!< Enable deferral check */
+} ETH_DEFFERRALCHECK_T;
+
+/**
+ * @brief    ETH Receive All
+ */
+typedef enum
+{
+    ETH_RECEIVEAll_DISABLE, /*!< Disable receive all */
+    ETH_RECEIVEALL_ENABLE   /*!< Enable receive all */
+} ETH_RECEIVEAll_T;
+
+/**
+ * @brief    ETH Source Addr Filter
+ */
+typedef enum
+{
+    ETH_SOURCEADDRFILTER_DISABLE,                       /*!< Disable source address filter */
+    ETH_SOURCEADDRFILTER_NORMAL_ENABLE = BIT9,          /*!< Enable normal source address filter */
+    ETH_SOURCEADDRFILTER_INVERSE_ENABLE = BIT8 | BIT9,  /*!< Enable inverse source address filter */
+} ETH_SOURCEADDRFILTER_T;
+
+/**
+ * @brief    ETH Pass Control Frames
+ */
+typedef enum
+{
+    ETH_PASSCONTROLFRAMES_BLOCKALL = 1,             /*!< Even if all control frames except pause frames fail the
+                                                        address filter, MAC forwards them to the application */
+    ETH_PASSCONTROLFRAMES_FORWARDALL,               /*!< MAC forwards control frames to the application even if
+                                                        they do not pass the address filter */
+    ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER   /*!< MAC forwards control frames that pass through the address filter */
+} ETH_PASSCONTROLFRAMES_T;
+
+/**
+ * @brief    ETH Broadcast Frames Reception
+ */
+typedef enum
+{
+    ETH_BROADCASTFRAMESRECEPTION_ENABLE,    /*!< Enable broadcast frames */
+    ETH_BROADCASTFRAMESRECEPTION_DISABLE    /*!< Disable broadcast frames */
+} ETH_BROADCASTFRAMESRECEPTION_T;
+
+/**
+ * @brief    ETH Destination Addr Filter
+ */
+typedef enum
+{
+    ETH_DESTINATIONADDRFILTER_NORMAL,   /*!< Normal destination address filter */
+    ETH_DESTINATIONADDRFILTER_INVERSE   /*!< Inverse destination address filter */
+} ETH_DESTINATIONADDRFILTER_T;
+
+/**
+ * @brief    ETH Destination Addr Filter
+ */
+typedef enum
+{
+    ETH_PROMISCUOUS_MODE_DISABLE,   /*!< Disable promiscuous mode */
+    ETH_PROMISCUOUS_MODE_ENABLE     /*!< Enable promiscuous mode */
+} ETH_PROMISCUOUS_MODE_T;
+
+/**
+ * @brief    ETH Multicast Frames Filter
+ */
+typedef enum
+{
+    ETH_MULTICASTFRAMESFILTER_PERFECT,                      /*!< Multicast perfect filter */
+    ETH_MULTICASTFRAMESFILTER_NONE = BIT4,                  /*!< Multicast pass all multicast */
+    ETH_MULTICASTFRAMESFILTER_HASHTABLE = BIT2,             /*!< Multicast hash multicast */
+    ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE = BIT2|BIT10 /*!< Multicast perfect hash table */
+} ETH_MULTICASTFRAMESFILTER_T;
+
+/**
+ * @brief    ETH Unicast Frames Filter
+ */
+typedef enum
+{
+    ETH_UNICASTFRAMESFILTER_PERFECT,                        /*!< Unicast perfect filter */
+    ETH_UNICASTFRAMESFILTER_HASHTABLE = BIT1,               /*!< Unicast hash table */
+    ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE = BIT1|BIT10   /*!< Unicast perfect hash table */
+} ETH_UNICASTFRAMESFILTER_T;
+
+/**
+ * @brief    ETH Zero Quanta Pause
+ */
+typedef enum
+{
+    ETH_ZEROQUANTAPAUSE_ENABLE,     /*!< Enable zero-quanta pause */
+    ETH_ZEROQUANTAPAUSE_DISABLE     /*!< Disable zero-quanta pause */
+} ETH_ZEROQUANTAPAUSE_T;
+
+/**
+ * @brief    ETH Pause Low Threshold
+ */
+typedef enum
+{
+    ETH_PAUSELOWTHRESHOLD_MINUS4,   /*!< Minus 4 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS28,  /*!< Minus 28 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS144, /*!< Minus 144 slot-time */
+    ETH_PAUSELOWTHRESHOLD_MINUS256  /*!< Minus 256 slot-time */
+} ETH_PAUSELOWTHRESHOLD_T;
+
+/**
+ * @brief    ETH Unicast Pause Frame Detect
+ */
+typedef enum
+{
+    ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,    /*!< Disable unicast pause frame detect */
+    ETH_UNICASTPAUSEFRAMEDETECT_ENABLE      /*!< Enable unicast pause frame detect */
+} ETH_UNICASTPAUSEFRAMEDETECT_T;
+
+/**
+ * @brief    ETH Receive Flow Control
+ */
+typedef enum
+{
+    ETH_RECEIVEFLOWCONTROL_DISABLE, /*!< Disable receive flow control */
+    ETH_RECEIVEFLOWCONTROL_ENABLE   /*!< Enable receive flow control */
+} ETH_RECEIVEFLOWCONTROL_T;
+
+/**
+ * @brief    ETH Transmit Flow Control
+ */
+typedef enum
+{
+    ETH_TRANSMITFLOWCONTROL_DISABLE,    /*!< Disable transmit flow control */
+    ETH_TRANSMITFLOWCONTROL_ENABLE      /*!< Enable transmit flow control */
+} ETH_TRANSMITFLOWCONTROL_T;
+
+/**
+ * @brief    ETH VLAN Tag Comparison
+ */
+typedef enum
+{
+    ETH_VLANTAGCOMPARISON_16BIT,    /*!< 16-bit VLAN tag comparison */
+    ETH_VLANTAGCOMPARISON_12BIT     /*!< 12-bit VLAN tag comparison */
+} ETH_VLANTAGCOMPARISON_T;
+
+/**
+ * @brief    ETH MAC Flags
+ */
+typedef enum
+{
+    ETH_MAC_FLAG_TST  = 0x00000200, /*!< Time stamp trigger flag */
+    ETH_MAC_FLAG_MMCT = 0x00000040, /*!< MMC transmit flag */
+    ETH_MAC_FLAG_MMCR = 0x00000020, /*!< MMC receive flag */
+    ETH_MAC_FLAG_MMC  = 0x00000010, /*!< MMC flag */
+    ETH_MAC_FLAG_PMT  = 0x00000008  /*!< PMT flag */
+} ETH_MAC_FLAG_T;
+
+/**
+ * @brief    ETH MAC Interrupts
+ */
+typedef enum
+{
+    ETH_MAC_INT_TST  = 0x00000200,  /*!< Time stamp trigger interrupt */
+    ETH_MAC_INT_MMCT = 0x00000040,  /*!< MMC transmit interrupt */
+    ETH_MAC_INT_MMCR = 0x00000020,  /*!< MMC receive interrupt */
+    ETH_MAC_INT_MMC  = 0x00000010,  /*!< MMC interrupt */
+    ETH_MAC_INT_PMT  = 0x00000008   /*!< PMT interrupt */
+} ETH_MAC_INT_T;
+
+/**
+ * @brief    ETH MAC Interrupts
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESS0 = 0x00000000,  /*!< MAC Address0 */
+    ETH_MAC_ADDRESS1 = 0x00000008,  /*!< MAC Address1 */
+    ETH_MAC_ADDRESS2 = 0x00000010,  /*!< MAC Address2 */
+    ETH_MAC_ADDRESS3 = 0x00000018   /*!< MAC Address3 */
+} ETH_MAC_ADDRESS_T;
+
+/**
+ * @brief    ETH MAC addresses filter SA/DA
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESSFILTER_SA,           /*!< MAC Address is used to compare with the
+                                            SA fields of the received frame */
+    ETH_MAC_ADDRESSFILTER_DA = BIT30    /*!< MAC Address is used to compare with the
+                                            DA fields of the received frame */
+} ETH_MAC_ADDRESSFILTER_T;
+
+/**
+ * @brief    ETH MAC addresses filter Mask bytes
+ */
+typedef enum
+{
+    ETH_MAC_ADDRESSMASK_BYTE6 = 0x20000000,  /*!< Mask MAC Address high reg bits [15:8] */
+    ETH_MAC_ADDRESSMASK_BYTE5 = 0x10000000,  /*!< Mask MAC Address high reg bits [7:0] */
+    ETH_MAC_ADDRESSMASK_BYTE4 = 0x08000000,  /*!< Mask MAC Address low reg bits [31:24] */
+    ETH_MAC_ADDRESSMASK_BYTE3 = 0x04000000,  /*!< Mask MAC Address low reg bits [23:16] */
+    ETH_MAC_ADDRESSMASK_BYTE2 = 0x02000000,  /*!< Mask MAC Address low reg bits [15:8] */
+    ETH_MAC_ADDRESSMASK_BYTE1 = 0x01000000   /*!< Mask MAC Address low reg bits [70] */
+} ETH_MAC_ADDRESSMASK_T;
+
+/**
+ * @brief    DMA Tx descriptor flags
+ */
+typedef enum
+{
+    ETH_DMATXDESC_OWN      = (int)0x80000000,   /*!< Descriptor is owned by DMA engine */
+    ETH_DMATXDESC_INTC     = 0x40000000,        /*!< Interrupt on completion */
+    ETH_DMATXDESC_LS       = 0x20000000,        /*!< Last Segment */
+    ETH_DMATXDESC_FS       = 0x10000000,        /*!< First Segment */
+    ETH_DMATXDESC_DISC     = 0x08000000,        /*!< Disable CRC */
+    ETH_DMATXDESC_DISP     = 0x04000000,        /*!< Disable Pad */
+    ETH_DMATXDESC_TXTSEN   = 0x02000000,        /*!< Transmit Time Stamp Enable */
+    ETH_DMATXDESC_TXENDR   = 0x00200000,        /*!< Transmit End of Ring */
+    ETH_DMATXDESC_TXCH     = 0x00100000,        /*!< Second Address Chained */
+    ETH_DMATXDESC_TXTSS    = 0x00020000,        /*!< Tx Time Stamp Status */
+    ETH_DMATXDESC_IHERR    = 0x00010000,        /*!< IP Header Error */
+    ETH_DMATXDESC_ERRS     = 0x00008000,        /*!< Error summary */
+    ETH_DMATXDESC_JTO      = 0x00004000,        /*!< Jabber Timeout */
+    ETH_DMATXDESC_FF       = 0x00002000,        /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
+    ETH_DMATXDESC_IPERR    = 0x00001000,        /*!< Payload Checksum Error */
+    ETH_DMATXDESC_LSC      = 0x00000800,        /*!< Loss of Carrier: carrier lost during transmission */
+    ETH_DMATXDESC_NC       = 0x00000400,        /*!< No Carrier: no carrier signal from the transceiver */
+    ETH_DMATXDESC_LC       = 0x00000200,        /*!< Late Collision: transmission aborted due to collision */
+    ETH_DMATXDESC_EC       = 0x00000100,        /*!< Excessive Collision: transmission aborted after 16 collisions */
+    ETH_DMATXDESC_VLANF    = 0x00000080,        /*!< VLAN Frame */
+    ETH_DMATXDESC_CCNT     = 0x00000078,        /*!< Collision Count */
+    ETH_DMATXDESC_EDEF     = 0x00000004,        /*!< Excessive Deferral */
+    ETH_DMATXDESC_UFERR    = 0x00000002,        /*!< Underflow Error: late data arrival from the memory */
+    ETH_DMATXDESC_DEF      = 0x00000001         /*!< Deferred Bit */
+} ETH_DMATXDESC_FLAG_T;
+
+/**
+ * @brief    ETH DMA Tx descriptor segment
+ */
+typedef enum
+{
+    ETH_DMATXDESC_LASTSEGMENTS = BIT30, /*!< Actual Tx desc contain last segment */
+    ETH_DMATXDESC_FIRSTSEGMENT = BIT29  /*!< Actual Tx desc contain first segment */
+} ETH_DMATXDESC_SEGMENTS_T;
+
+/**
+ * @brief    ETH DMA Tx descriptor Checksum Insertion Control
+ */
+typedef enum
+{
+    ETH_DMATXDESC_CHECKSUMBYPASS,                       /*!< Checksum bypass */
+    ETH_DMATXDESC_CHECKSUMIPV4HEADER = BIT22,           /*!< IPv4 header checksum */
+    ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT = BIT23,    /*!< TCP/UDP/ICMP checksum. Pseudo header
+                                                            checksum is assumed to be present */
+    ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL = BIT22|BIT23  /*!< TCP/UDP/ICMP checksum fully in hardware
+                                                            including pseudo header */
+} ETH_DMATXDESC_CHECKSUMB_T;
+
+/**
+ * @brief    DMA Rx descriptor status
+ */
+typedef enum
+{
+    ETH_DMARXDESC_OWN      =  (int)0x80000000U, /*!< Descriptor is owned by DMA engine */
+    ETH_DMARXDESC_ADDRF    =  0x40000000,       /*!< DA Filter Fail for the rx frame */
+    ETH_DMARXDESC_ERRS     =  0x00008000,       /*!< Error summary */
+    ETH_DMARXDESC_DESERR   =  0x00004000,       /*!< Descriptor error: no more descriptors for receive frame */
+    ETH_DMARXDESC_SADDRF   =  0x00002000,       /*!< SA Filter Fail for the received frame */
+    ETH_DMARXDESC_LERR     =  0x00001000,       /*!< Frame size not matching with length field */
+    ETH_DMARXDESC_OFERR    =  0x00000800,       /*!< Overflow Error: Frame was damaged due to buffer overflow */
+    ETH_DMARXDESC_VLANF    =  0x00000400,       /*!< VLAN Tag: received frame is a VLAN frame */
+    ETH_DMARXDESC_FDES     =  0x00000200,       /*!< First descriptor of the frame */
+    ETH_DMARXDESC_LDES     =  0x00000100,       /*!< Last descriptor of the frame */
+    ETH_DMARXDESC_IPV4HCE  =  0x00000080,       /*!< IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error */
+    ETH_DMARXDESC_LC       =  0x00000040,       /*!< Late collision occurred during reception */
+    ETH_DMARXDESC_FT       =  0x00000020,       /*!< Frame type - Ethernet, otherwise 802.3 */
+    ETH_DMARXDESC_RXWDTTO  =  0x00000010,       /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
+    ETH_DMARXDESC_RERR     =  0x00000008,       /*!< Receive error: error reported by MII interface */
+    ETH_DMARXDESC_DERR     =  0x00000004,       /*!< Dribble bit error: frame contains non int multiple of 8 bits */
+    ETH_DMARXDESC_CERR     =  0x00000002,       /*!< CRC error */
+    ETH_DMARXDESC_MAMPCE   =  0x00000001        /*!< Rx MAC Address/Payload Checksum Error:
+                                                    Rx MAC address matched/ Rx Payload Checksum Error */
+} ETH_DMARXDESC_FLAG_T;
+
+/**
+ * @brief    DMA Rx descriptor extended flags
+ */
+typedef enum
+{
+    ETH_DMAPTPRXDESC_PTPV   =  0x00002000,  /*!< PTP version */
+    ETH_DMAPTPRXDESC_PTPFT  =  0x00001000,  /*!< PTP frame type */
+    ETH_DMAPTPRXDESC_PTPMT  =  0x00000F00,  /*!< PTP message type */
+    ETH_DMAPTPRXDESC_IPV6P  =  0x00000080,  /*!< IPv6 packet received */
+    ETH_DMAPTPRXDESC_IPV4P  =  0x00000040,  /*!< IPv4 packet received */
+    ETH_DMAPTPRXDESC_IPCBP  =  0x00000020,  /*!< IP checksum bypassed */
+    ETH_DMAPTPRXDESC_IPPERR =  0x00000010,  /*!< IP payload error */
+    ETH_DMAPTPRXDESC_IPHERR =  0x00000008,  /*!< IP header error */
+    ETH_DMAPTPRXDESC_IPPT   =  0x00000007   /*!< IP payload type */
+} ETH_DMAPTPRXDESC_FLAG_T;
+
+/**
+ * @brief    ETH DMA Rx descriptor buffers
+ */
+typedef enum
+{
+    ETH_DMARXDESC_BUFFER1,  /*!< DMA Rx Desc Buffer1 */
+    ETH_DMARXDESC_BUFFER2   /*!< DMA Rx Desc Buffer2 */
+} ETH_DMARXDESC_BUFFER_T;
+
+/**
+ * @brief    ETH Drop TCP IP Checksum Error Frame
+ */
+typedef enum
+{
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE,     /*!< Enable dropping of TCP/IP checksum error frame */
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE     /*!< Disable dropping of TCP/IP checksum error frame */
+} ETH_DROPTCPIPCHECKSUMERRORFRAME_T;
+
+/**
+ * @brief    ETH Receive Store Forward
+ */
+typedef enum
+{
+    ETH_RECEIVESTOREFORWARD_DISABLE,    /*!< Disable receive store and forward */
+    ETH_RECEIVESTOREFORWARD_ENABLE      /*!< Enable receive store and forward */
+} ETH_RECEIVESTOREFORWARD_T;
+
+/**
+ * @brief    ETH Flush Received Frame
+ */
+typedef enum
+{
+    ETH_FLUSHRECEIVEDFRAME_ENABLE,  /*!< Enable flushing of received frames */
+    ETH_FLUSHRECEIVEDFRAME_DISABLE  /*!< Disable flushing of received frames */
+} ETH_FLUSHRECEIVEDFRAME_T;
+
+/**
+ * @brief    ETH Transmit Store Forward
+ */
+typedef enum
+{
+    ETH_TRANSMITSTOREFORWARD_DISABLE,   /*!< Disable transmit store and forward */
+    ETH_TRANSMITSTOREFORWARD_ENABLE     /*!< Enable transmit store and forward */
+} ETH_TRANSMITSTOREFORWARD_T;
+
+/**
+ * @brief    ETH Transmit Threshold Control
+ */
+typedef enum
+{
+    ETH_TRANSMITTHRESHOLDCONTROL_64BYTES,   /*!< Select 64 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_128BYTES,  /*!< Select 128 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_192BYTES,  /*!< Select 192 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_256BYTES,  /*!< Select 256 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_40BYTES,   /*!< Select 40 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_32BYTES,   /*!< Select 32 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_24BYTES,   /*!< Select 24 bytes transmit threshild level */
+    ETH_TRANSMITTHRESHOLDCONTROL_16BYTES    /*!< Select 16 bytes transmit threshild level */
+} ETH_TRANSMITTHRESHOLDCONTROL_T;
+
+/**
+ * @brief    ETH Forward Error Frames
+ */
+typedef enum
+{
+    ETH_FORWARDERRORFRAMES_DISABLE, /*!< Disable forward error frames */
+    ETH_FORWARDERRORFRAMES_ENABLE   /*!< Enable forward error frames */
+} ETH_FORWARDERRORFRAMES_T;
+
+/**
+ * @brief    ETH Forward Undersized Good Frames
+ */
+typedef enum
+{
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE,    /*!< Disable forward undersized good frames */
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE      /*!< Enable forward undersized good frames */
+} ETH_FORWARDUNDERSIZEDGOODFRAMES_T;
+
+/**
+ * @brief    ETH Receive Threshold Control
+ */
+typedef enum
+{
+    ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES,   /*!< Select 64 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES,   /*!< Select 32 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES,   /*!< Select 96 bytes receive threshold level */
+    ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES   /*!< Select 128 bytes receive threshold level */
+} ETH_RECEIVEDTHRESHOLDCONTROL_T;
+
+/**
+ * @brief    ETH Second Frame Operate
+ */
+typedef enum
+{
+    ETH_SECONDFRAMEOPERARTE_DISABLE,    /*!< Disable second frame operate */
+    ETH_SECONDFRAMEOPERARTE_ENABLE      /*!< Enable second frame operate */
+} ETH_SECONDFRAMEOPERARTE_T;
+
+/**
+ * @brief    ETH Address Aligned Beats
+ */
+typedef enum
+{
+    ETH_ADDRESSALIGNEDBEATS_DISABLE,    /*!< Disable address aligned beats */
+    ETH_ADDRESSALIGNEDBEATS_ENABLE      /*!< Enable address aligned beats */
+} ETH_ADDRESSALIGNEDBEATS_T;
+
+/**
+ * @brief    ETH Fixed Burst
+ */
+typedef enum
+{
+    ETH_FIXEDBURST_DISABLE, /*!< Disable fixed burst */
+    ETH_FIXEDBURST_ENABLE   /*!< Enable fixed burst */
+} ETH_FIXEDBURST_T;
+
+/**
+ * @brief    ETH Rx DMA Burst Length
+ */
+typedef enum
+{
+    ETH_RXDMABURSTLENGTH_1BEAT        = BIT17,          /*!< Maxnum number of Rx DMA transaction = 1 beat */
+    ETH_RXDMABURSTLENGTH_2BEAT        = BIT18,          /*!< Maxnum number of Rx DMA transaction = 2 beat */
+    ETH_RXDMABURSTLENGTH_4BEAT        = BIT19,          /*!< Maxnum number of Rx DMA transaction = 4 beat */
+    ETH_RXDMABURSTLENGTH_8BEAT        = BIT20,          /*!< Maxnum number of Rx DMA transaction = 8 beat */
+    ETH_RXDMABURSTLENGTH_16BEAT       = BIT21,          /*!< Maxnum number of Rx DMA transaction = 16 beat */
+    ETH_RXDMABURSTLENGTH_32BEAT       = BIT22,          /*!< Maxnum number of Rx DMA transaction = 32 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_4BEAT  = BIT17|BIT24,    /*!< Maxnum number of Rx DMA transaction = 4 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_8BEAT  = BIT18|BIT24,    /*!< Maxnum number of Rx DMA transaction = 8 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_16BEAT = BIT19|BIT24,    /*!< Maxnum number of Rx DMA transaction = 16 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_32BEAT = BIT20|BIT24,    /*!< Maxnum number of Rx DMA transaction = 32 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_64BEAT = BIT21|BIT24,    /*!< Maxnum number of Rx DMA transaction = 64 beat */
+    ETH_RXDMABURSTLENGTH_4XPBL_128BEAT= BIT22|BIT24     /*!< Maxnum number of Rx DMA transaction = 128 beat */
+} ETH_RXDMABURSTLENGTH_T;
+
+/**
+ * @brief    ETH Tx DMA Burst Length
+ */
+typedef enum
+{
+    ETH_TXDMABURSTLENGTH_1BEAT        = BIT8,           /*!< Maxnum number of Tx DMA transaction = 1 beat */
+    ETH_TXDMABURSTLENGTH_2BEAT        = BIT9,           /*!< Maxnum number of Tx DMA transaction = 2 beat */
+    ETH_TXDMABURSTLENGTH_4BEAT        = BIT10,          /*!< Maxnum number of Tx DMA transaction = 4 beat */
+    ETH_TXDMABURSTLENGTH_8BEAT        = BIT11,          /*!< Maxnum number of Tx DMA transaction = 8 beat */
+    ETH_TXDMABURSTLENGTH_16BEAT       = BIT12,          /*!< Maxnum number of Tx DMA transaction = 16 beat */
+    ETH_TXDMABURSTLENGTH_32BEAT       = BIT13,          /*!< Maxnum number of Tx DMA transaction = 32 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_4BEAT  = BIT8|BIT24,     /*!< Maxnum number of Tx DMA transaction = 4 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_8BEAT  = BIT9|BIT24,     /*!< Maxnum number of Tx DMA transaction = 8 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_16BEAT = BIT10|BIT24,    /*!< Maxnum number of Tx DMA transaction = 16 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_32BEAT = BIT11|BIT24,    /*!< Maxnum number of Tx DMA transaction = 32 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_64BEAT = BIT12|BIT24,    /*!< Maxnum number of Tx DMA transaction = 64 beat */
+    ETH_TXDMABURSTLENGTH_4XPBL_128BEAT= BIT13|BIT24     /*!< Maxnum number of Tx DMA transaction = 128 beat */
+} ETH_TXDMABURSTLENGTH_T;
+
+/**
+ * @brief    ETH DMA Arbitration
+ */
+typedef enum
+{
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1,                 /*!< Priority ratio RX : TX = 1 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 = BIT14,         /*!< Priority ratio RX : TX = 2 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 = BIT15,         /*!< Priority ratio RX : TX = 3 : 1 */
+    ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 = BIT14|BIT15,   /*!< Priority ratio RX : TX = 4 : 1 */
+    ETH_DMAARBITRATION_RXPRIORTX = BIT1                     /*!< Rx priority ratio higher than Tx */
+} ETH_DMAARBITRATION_T;
+
+/**
+ * @brief    ETH DMA Flags
+ */
+typedef enum
+{
+    ETH_DMA_FLAG_TST               = 0x20000000,   /*!< Time-stamp trigger interrupt (on DMA) */
+    ETH_DMA_FLAG_PMT               = 0x10000000,   /*!< PMT interrupt (on DMA) */
+    ETH_DMA_FLAG_MMC               = 0x08000000,   /*!< MMC interrupt (on DMA) */
+    ETH_DMA_FLAG_DATATRANSFERERROR = 0x00800000,   /*!< Error bits 0-Rx DMA, 1-Tx DMA */
+    ETH_DMA_FLAG_READWRITEERROR    = 0x01000000,   /*!< Error bits 0-write transfer, 1-read transfer */
+    ETH_DMA_FLAG_ACCESSERROR       = 0x02000000,   /*!< Error bits 0-data buffer, 1-desc. access */
+    ETH_DMA_FLAG_NIS               = 0x00010000,   /*!< Normal interrupt summary flag */
+    ETH_DMA_FLAG_AIS               = 0x00008000,   /*!< Abnormal interrupt summary flag */
+    ETH_DMA_FLAG_ER                = 0x00004000,   /*!< Early receive flag */
+    ETH_DMA_FLAG_FBE               = 0x00002000,   /*!< Fatal bus error flag */
+    ETH_DMA_FLAG_ET                = 0x00000400,   /*!< Early transmit flag */
+    ETH_DMA_FLAG_RWT               = 0x00000200,   /*!< Receive watchdog timeout flag */
+    ETH_DMA_FLAG_RPS               = 0x00000100,   /*!< Receive process stopped flag */
+    ETH_DMA_FLAG_RBU               = 0x00000080,   /*!< Receive buffer unavailable flag */
+    ETH_DMA_FLAG_RX                = 0x00000040,   /*!< Receive flag */
+    ETH_DMA_FLAG_TU                = 0x00000020,   /*!< Underflow flag */
+    ETH_DMA_FLAG_RO                = 0x00000010,   /*!< Overflow flag */
+    ETH_DMA_FLAG_TJT               = 0x00000008,   /*!< Transmit jabber timeout flag */
+    ETH_DMA_FLAG_TBU               = 0x00000004,   /*!< Transmit buffer unavailable flag */
+    ETH_DMA_FLAG_TPS               = 0x00000002,   /*!< Transmit process stopped flag */
+    ETH_DMA_FLAG_TX                = 0x00000001    /*!< Transmit flag */
+} ETH_DMA_FLAG_T;
+
+/**
+ * @brief    ETH DMA Interrupts
+ */
+typedef enum
+{
+    ETH_DMA_INT_TST   =   0x20000000,   /*!< Time-stamp trigger interrupt (on DMA) */
+    ETH_DMA_INT_PMT   =   0x10000000,   /*!< PMT interrupt (on DMA) */
+    ETH_DMA_INT_MMC   =   0x08000000,   /*!< MMC interrupt (on DMA) */
+    ETH_DMA_INT_NIS   =   0x00010000,   /*!< Normal interrupt summary */
+    ETH_DMA_INT_AIS   =   0x00008000,   /*!< Abnormal interrupt summary */
+    ETH_DMA_INT_ER    =   0x00004000,   /*!< Early receive interrupt */
+    ETH_DMA_INT_FBE   =   0x00002000,   /*!< Fatal bus error interrupt */
+    ETH_DMA_INT_ET    =   0x00000400,   /*!< Early transmit interrupt */
+    ETH_DMA_INT_RWT   =   0x00000200,   /*!< Receive watchdog timeout interrupt */
+    ETH_DMA_INT_RPS   =   0x00000100,   /*!< Receive process stopped interrupt */
+    ETH_DMA_INT_RBU   =   0x00000080,   /*!< Receive buffer unavailable interrupt */
+    ETH_DMA_INT_RX    =   0x00000040,   /*!< Receive interrupt */
+    ETH_DMA_INT_TU    =   0x00000020,   /*!< Underflow interrupt */
+    ETH_DMA_INT_RO    =   0x00000010,   /*!< Overflow interrupt */
+    ETH_DMA_INT_TJT   =   0x00000008,   /*!< Transmit jabber timeout interrupt */
+    ETH_DMA_INT_TBU   =   0x00000004,   /*!< Transmit buffer unavailable interrupt */
+    ETH_DMA_INT_TPS   =   0x00000002,   /*!< Transmit process stopped interrupt */
+    ETH_DMA_INT_TX    =   0x00000001    /*!< Transmit interrupt */
+} ETH_DMA_INT_T;
+
+/**
+ * @brief    ETH DMA transmit process state
+ */
+typedef enum
+{
+    ETH_DMA_TRANSMITPROCESS_STOPPED,            /*!< Stopped - Reset or Stop Tx Command issued */
+    ETH_DMA_TRANSMITPROCESS_FETCHING,           /*!< Running - fetching the Tx descriptor */
+    ETH_DMA_TRANSMITPROCESS_WAITING,            /*!< Running - waiting for status */
+    ETH_DMA_TRANSMITPROCESS_READING,            /*!< Running - reading the data from host memory */
+    ETH_DMA_TRANSMITPROCESS_SUSPENDED = 0x06,   /*!< Suspended - Tx Descriptor unavailable */
+    ETH_DMA_TRANSMITPROCESS_CLOSING = 0x07,     /*!< Running - closing Rx descriptor */
+} ETH_DMA_TRANSMITPROCESS_T;
+
+/**
+ * @brief    ETH DMA receive process state
+ */
+typedef enum
+{
+    ETH_DMA_RECEIVEPROCESS_STOPPED,             /*!< Stopped - Reset or Stop Rx Command issued */
+    ETH_DMA_RECEIVEPROCESS_FETCHING  = 0x02,    /*!< Running - fetching the Rx descriptor */
+    ETH_DMA_RECEIVEPROCESS_WAITING   = 0x06,    /*!< Running - waiting for packet */
+    ETH_DMA_RECEIVEPROCESS_SUSPENDED = 0x08,    /*!< Suspended - Rx Descriptor unavailable */
+    ETH_DMA_RECEIVEPROCESS_CLOSING   = 0x0A,    /*!< Running - closing descriptor */
+    ETH_DMA_RECEIVEPROCESS_QUEUING   = 0x0E     /*!< Running - queuing the receive frame into host memory */
+} ETH_DMA_RECEIVEPROCESS_T;
+
+/**
+ * @brief    ETH DMA overflow
+ */
+typedef enum
+{
+    ETH_DMA_OVERFLOW_RXFIFOCOUNTER = BIT28,     /*!< Overflow for FIFO Overflows Counter */
+    ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER = BIT16 /*!< Overflow for Buffer Unavailable Missed Frame Counter */
+} ETH_DMA_OVERFLOW_T;
+
+/**
+ * @brief    ETH PMT Flags
+ */
+typedef enum
+{
+    ETH_PMT_FLAG_WUFFRPR = (int)BIT31,  /*!< Wake-Up Frame Filter Register Pointer Reset */
+    ETH_PMT_FLAG_WUFR = BIT6,           /*!< Wake-Up Frame Received */
+    ETH_PMT_FLAG_MPR = BIT5             /*!< Magic Packet Received */
+} ETH_PMT_FLAG_T;
+
+/**
+ * @brief    ETH MMC Tx/RX Interrupts
+ */
+typedef enum
+{
+    ETH_MMC_INT_TGF    = BIT21,         /*!< When Tx good frame counter reaches half the maximum value */
+    ETH_MMC_INT_TGFMSC = BIT15,         /*!< When Tx good multi col counter reaches half the maximum value */
+    ETH_MMC_INT_TGFSC  = BIT14,         /*!< When Tx good single col counter reaches half the maximum value */
+    ETH_MMC_INT_RGUF   = BIT21|BIT30,   /*!< When Rx good unicast frames counter reaches half the maximum value */
+    ETH_MMC_INT_RFAE   = BIT6|BIT30,    /*!< When Rx alignment error counter reaches half the maximum value */
+    ETH_MMC_INT_RFCE   = BIT5|BIT30     /*!< When Rx crc error counter reaches half the maximum value */
+} ETH_MMC_INT_T;
+
+/**
+ * @brief    ETH MMC Registers
+ */
+typedef enum
+{
+    ETH_MMC_CTRL       =  0x00000100,   /*!< MMC CTRL register */
+    ETH_MMC_RXINT      =  0x00000104,   /*!< MMC RXINT register */
+    ETH_MMC_TXINT      =  0x00000108,   /*!< MMC TXINT register */
+    ETH_MMC_RXINTMASK  =  0x0000010C,   /*!< MMC RXINTMASK register */
+    ETH_MMC_TXINTMASK  =  0x00000110,   /*!< MMC TXINTMASK register */
+    ETH_MMC_TXGFSCCNT  =  0x0000014C,   /*!< MMC TXGFSCCNT register */
+    ETH_MMC_TXGFMCCNT  =  0x00000150,   /*!< MMC TXGFMCCNT register */
+    ETH_MMC_TXGFCNT    =  0x00000168,   /*!< MMC TXGFCNT register */
+    ETH_MMC_RXFCECNT   =  0x00000194,   /*!< MMC RXFCECNT register */
+    ETH_MMC_RXFAECNT   =  0x00000198,   /*!< MMC RXFAECNT register */
+    ETH_MMC_RXGUNCNT   =  0x000001C4    /*!< MMC RXGUNCNT register */
+} ETH_MMC_REG_T;
+
+/**@} end of group ETH_Enumerations*/
+
+
+/** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor
+  @{
+  */
+
+/**
+*  DMA Tx Descriptor
+*  -----------------------------------------------------------------------------------------------
+*  TXDES0 | OWN(31) | CTRL[30:25] | Reserved(24) | CTRL[23:20] | Reserved[19:18] | Status[17:0]   |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES1 | Reserved[31:29] | Buffer2 Size[28:16] | Reserved[15:13] | Buffer1 Size[12:0]          |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES2 |                         Buffer1 Address [31:0]                                        |
+*  -----------------------------------------------------------------------------------------------
+*  TXDES3 |                   Buffer2 Address [31:0] / Next Descriptor Address [31:0]             |
+*  -----------------------------------------------------------------------------------------------
+*/
+
+/**
+  * @brief  Bit definition of TXDES0 register: DMA Tx descriptor status register
+  */
+#define ETH_DMATXDESC_OWN                     0x80000000U   /*!< OWN bit: descriptor is owned by DMA engine */
+#define ETH_DMATXDESC_INTC                    0x40000000U   /*!< Interrupt on Completion */
+#define ETH_DMATXDESC_LS                      0x20000000U   /*!< Last Segment */
+#define ETH_DMATXDESC_FS                      0x10000000U   /*!< First Segment */
+#define ETH_DMATXDESC_DISC                    0x08000000U   /*!< Disable CRC */
+#define ETH_DMATXDESC_DISP                    0x04000000U   /*!< Disable Padding */
+#define ETH_DMATXDESC_TXTSEN                  0x02000000U   /*!< Transmit Time Stamp Enable */
+#define ETH_DMATXDESC_CIC                     0x00C00000U   /*!< Checksum Insertion Control: 4 cases */
+#define ETH_DMATXDESC_CIC_BYPASS              0x00000000U   /*!< Do Nothing: Checksum Engine is bypassed */
+#define ETH_DMATXDESC_CIC_IPV4HEADER          0x00400000U   /*!< IPV4 header Checksum Insertion */
+#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT  0x00800000U   /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
+#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL     0x00C00000U   /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
+#define ETH_DMATXDESC_TXENDR                  0x00200000U   /*!< Transmit End of Ring */
+#define ETH_DMATXDESC_TXCH                    0x00100000U   /*!< Second Address Chained */
+#define ETH_DMATXDESC_TXTSS                   0x00020000U   /*!< Tx Time Stamp Status */
+#define ETH_DMATXDESC_IHERR                   0x00010000U   /*!< IP Header Error */
+#define ETH_DMATXDESC_ERRS                    0x00008000U   /*!< Error summary: OR of the following bits: UFERR || EDEF || EC || LC || NC || LSC || FF || JTO */
+#define ETH_DMATXDESC_JTO                     0x00004000U   /*!< Jabber Timeout */
+#define ETH_DMATXDESC_FF                      0x00002000U   /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
+#define ETH_DMATXDESC_IPERR                   0x00001000U   /*!< Payload Checksum Error */
+#define ETH_DMATXDESC_LSC                     0x00000800U   /*!< Loss of Carrier: carrier lost during transmission */
+#define ETH_DMATXDESC_NC                      0x00000400U   /*!< No Carrier: no carrier signal from the transceiver */
+#define ETH_DMATXDESC_LC                      0x00000200U   /*!< Late Collision: transmission aborted due to collision */
+#define ETH_DMATXDESC_EC                      0x00000100U   /*!< Excessive Collision: transmission aborted after 16 collisions */
+#define ETH_DMATXDESC_VLANF                   0x00000080U   /*!< VLAN Frame */
+#define ETH_DMATXDESC_CCNT                    0x00000078U   /*!< Collision Count */
+#define ETH_DMATXDESC_EDEF                    0x00000004U   /*!< Excessive Deferral */
+#define ETH_DMATXDESC_UFERR                   0x00000002U   /*!< Underflow Error: late data arrival from the memory */
+#define ETH_DMATXDESC_DEF                     0x00000001U   /*!< Deferred Bit */
+
+/**
+  * @brief  Bit definition of TXDES1 register
+  */
+#define ETH_DMATXDESC_TXBS2  0x1FFF0000U /*!< Transmit Buffer2 Size */
+#define ETH_DMATXDESC_TXBS1  0x00001FFFU /*!< Transmit Buffer1 Size */
+
+/**
+  * @brief  Bit definition of TXDES2 register
+  */
+#define ETH_DMATXDESC_B1AP  0xFFFFFFFFU /*!< Buffer1 Address Pointer */
+
+/**
+  * @brief  Bit definition of TXDES3 register
+  */
+#define ETH_DMATXDESC_B2AP  0xFFFFFFFFU /*!< Buffer2 Address Pointer */
+
+/**
+*  ---------------------------------------------------------------------------------------------
+*  TXDES6 |                         Transmit Time Stamp Low [31:0]                               |
+*  ---------------------------------------------------------------------------------------------
+*  TXDES7 |                         Transmit Time Stamp High [31:0]                              |
+*  ----------------------------------------------------------------------------------------------
+*/
+
+/** Bit definition of TXDES6 register */
+#define ETH_DMAPTPTXDESC_TXTSL  0xFFFFFFFFU  /*!< Transmit Time Stamp Low */
+
+/** Bit definition of TXDES7 register */
+#define ETH_DMAPTPTXDESC_TXTSH  0xFFFFFFFFU  /*!< Transmit Time Stamp High */
+
+/**
+  * @}
+  */
+/** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor
+  @{
+  */
+
+/**
+  *DMA Rx Descriptor
+  *--------------------------------------------------------------------------------------------------------------------
+  *RXDES0 | OWN(31) |                                             Status [30:0]                                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES1 | CTRL(31) | Reserved[30:29] | Buffer2 Size[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 Size[12:0]          |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES2 |                                       Buffer1 Address [31:0]                                                |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES3 |                          Buffer2 Address [31:0] / Next Descriptor Address [31:0]                            |
+  *---------------------------------------------------------------------------------------------------------------------
+*/
+
+/**
+  * @brief  Bit definition of RXDES0 register: DMA Rx descriptor status register
+  */
+#define ETH_DMARXDESC_OWN         0x80000000U   /*!< OWN bit: descriptor is owned by DMA engine */
+#define ETH_DMARXDESC_ADDRF       0x40000000U   /*!< DA Filter Fail for the rx frame */
+#define ETH_DMARXDESC_FL          0x3FFF0000U   /*!< Receive descriptor frame length */
+#define ETH_DMARXDESC_ERRS        0x00008000U   /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
+#define ETH_DMARXDESC_DESERR      0x00004000U   /*!< Descriptor error: no more descriptors for receive frame */
+#define ETH_DMARXDESC_SADDRF      0x00002000U   /*!< SA Filter Fail for the received frame */
+#define ETH_DMARXDESC_LERR        0x00001000U   /*!< Frame size not matching with length field */
+#define ETH_DMARXDESC_OFERR       0x00000800U   /*!< Overflow Error: Frame was damaged due to buffer overflow */
+#define ETH_DMARXDESC_VLANF       0x00000400U   /*!< VLAN Tag: received frame is a VLAN frame */
+#define ETH_DMARXDESC_FDES        0x00000200U   /*!< First descriptor of the frame */
+#define ETH_DMARXDESC_LDES        0x00000100U   /*!< Last descriptor of the frame */
+#define ETH_DMARXDESC_IPV4HCE     0x00000080U   /*!< IPC Checksum Error: Rx Ipv4 header checksum error */
+#define ETH_DMARXDESC_LC          0x00000040U   /*!< Late collision occurred during reception */
+#define ETH_DMARXDESC_FT          0x00000020U   /*!< Frame type - Ethernet, otherwise 802.3 */
+#define ETH_DMARXDESC_RXWWTTO     0x00000010U   /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
+#define ETH_DMARXDESC_RERR        0x00000008U   /*!< Receive error: error reported by MII interface */
+#define ETH_DMARXDESC_DERR        0x00000004U   /*!< Dribble bit error: frame contains non int multiple of 8 bits */
+#define ETH_DMARXDESC_CERR        0x00000002U   /*!< CRC error */
+#define ETH_DMARXDESC_MAMPCE      0x00000001U   /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
+
+/**
+  * @brief  Bit definition of RXDES1 register
+  */
+#define ETH_DMARXDESC_DINTC  0x80000000U /*!< Disable Interrupt on Completion */
+#define ETH_DMARXDESC_RXBS2  0x1FFF0000U /*!< Receive Buffer2 Size */
+#define ETH_DMARXDESC_RXER   0x00008000U /*!< Receive End of Ring */
+#define ETH_DMARXDESC_RXCH   0x00004000U /*!< Second Address Chained */
+#define ETH_DMARXDESC_RXBS1  0x00001FFFU /*!< Receive Buffer1 Size */
+
+/**
+  * @brief  Bit definition of RXDES2 register
+  */
+#define ETH_DMARXDESC_B1AP  0xFFFFFFFFU /*!< Buffer1 Address Pointer */
+
+/**
+  * @brief  Bit definition of RXDES3 register
+  */
+#define ETH_DMARXDESC_B2AP  0xFFFFFFFFU /*!< Buffer2 Address Pointer */
+
+/**
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES4 |                   Reserved[31:14]              |             Extended Status [13:0]                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES5 |                                            Reserved[31:0]                                                   |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES6 |                                       Receive Time Stamp Low [31:0]                                         |
+  *---------------------------------------------------------------------------------------------------------------------
+  *RXDES7 |                                       Receive Time Stamp High [31:0]                                        |
+  *---------------------------------------------------------------------------------------------------------------------
+*/
+
+/** Bit definition of RXDES4 register */
+#define ETH_DMAPTPRXDESC_PTPV     0x00002000U                           /*!< PTP Version */
+#define ETH_DMAPTPRXDESC_PTPFT    0x00001000U                           /*!< PTP Frame Type */
+#define ETH_DMAPTPRXDESC_PTPMT    0x00000F00U                           /*!< PTP Message Type */
+#define ETH_DMAPTPRXDESC_PTPMT_SYNC                      0x00000100U    /*!< SYNC message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_FOLLOWUP                  0x00000200U    /*!< FollowUp message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_DELAYREQ                  0x00000300U    /*!< DelayReq message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_DELAYRESP                 0x00000400U    /*!< DelayResp message (all clock types) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYREQ_ANNOUNCE        0x00000500U    /*!< PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESP_MANAG          0x00000600U    /*!< PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESPFOLLOWUP_SIGNAL 0x00000700U    /*!< PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */
+#define ETH_DMAPTPRXDESC_IPV6P    0x00000080U                           /*!< IPv6 Packet Received */
+#define ETH_DMAPTPRXDESC_IPV4P    0x00000040U                           /*!< IPv4 Packet Received */
+#define ETH_DMAPTPRXDESC_IPCBP    0x00000020U                           /*!< IP Checksum Bypassed */
+#define ETH_DMAPTPRXDESC_IPPERR   0x00000010U                           /*!< IP Payload Error */
+#define ETH_DMAPTPRXDESC_IPHERR   0x00000008U                           /*!< IP Header Error */
+#define ETH_DMAPTPRXDESC_IPPT     0x00000007U                           /*!< IP Payload Type */
+#define ETH_DMAPTPRXDESC_IPPT_UDP                 0x00000001U           /*!< UDP payload encapsulated in the IP datagram */
+#define ETH_DMAPTPRXDESC_IPPT_TCP                 0x00000002U           /*!< TCP payload encapsulated in the IP datagram */
+#define ETH_DMAPTPRXDESC_IPPT_ICMP                0x00000003U           /*!< ICMP payload encapsulated in the IP datagram */
+
+/** Bit definition of RXDES6 register */
+#define ETH_DMAPTPRXDESC_RXTSL  0xFFFFFFFFU  /*!< Receive Time Stamp Low */
+
+/** Bit definition of RXDES7 register */
+#define ETH_DMAPTPRXDESC_RXTSH  0xFFFFFFFFU  /*!< Receive Time Stamp High */
+/**
+  * @}
+  */
+
+
+/** @addtogroup ETH_Macros Macros
+  *@{
+  */
+
+/** ETH Frames defines */
+
+/** Definition of the Ethernet driver buffers size and count */
+#define ETH_RX_BUF_SIZE                ETH_MAX_PACKET_SIZE  /*!< buffer size for receive */
+#define ETH_TX_BUF_SIZE                ETH_MAX_PACKET_SIZE  /*!< buffer size for transmit */
+#define ETH_RXBUFNB                    (10U)                /*!< 10 Rx buffers of size ETH_RX_BUF_SIZE */
+#define ETH_TXBUFNB                    (10U)                /*!< 10 Tx buffers of size ETH_TX_BUF_SIZE */
+
+/** ETH_Buffers_setting ETH Buffers setting */
+#define ETH_MAX_PACKET_SIZE       1524U /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */
+#define ETH_HEADER                14U   /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
+#define ETH_CRC                   4U    /*!< Ethernet CRC */
+#define ETH_EXTRA                 2U    /*!< Extra bytes in some cases */
+#define ETH_VLAN_TAG              4U    /*!< optional 802.1q VLAN Tag */
+#define ETH_MIN_ETH_PAYLOAD       46U   /*!< Minimum Ethernet payload size */
+#define ETH_MAX_ETH_PAYLOAD       1500U /*!< Maximum Ethernet payload size */
+#define ETH_JUMBO_FRAME_PAYLOAD   9000U /*!< Jumbo frame payload size */
+
+/**
+*  Ethernet driver receive buffers are organized in a chained linked-list, when
+*  an ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO
+*  to the driver receive buffers memory.
+*
+*  Depending on the size of the received ethernet packet and the size of
+*  each ethernet driver receive buffer, the received packet can take one or more
+*  ethernet driver receive buffer.
+*
+*  In below are defined the size of one ethernet driver receive buffer ETH_RX_BUF_SIZE
+*  and the total count of the driver receive buffers ETH_RXBUFNB.
+*
+*  The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as
+*  example, they can be reconfigured in the application layer to fit the application
+*  needs
+*/
+
+/** Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet
+*   packet
+*/
+#ifndef ETH_RX_BUF_SIZE
+#define ETH_RX_BUF_SIZE         ETH_MAX_PACKET_SIZE
+#endif
+
+/** 5 Ethernet driver receive buffers are used (in a chained linked list)*/
+#ifndef ETH_RXBUFNB
+#define ETH_RXBUFNB             5U  /*!< 5 Rx buffers of size ETH_RX_BUF_SIZE */
+#endif
+
+/**
+*  Ethernet driver transmit buffers are organized in a chained linked-list, when
+*  an ethernet packet is transmitted, Tx-DMA will transfer the packet from the
+*  driver transmit buffers memory to the TxFIFO.
+*
+*  Depending on the size of the Ethernet packet to be transmitted and the size of
+*  each ethernet driver transmit buffer, the packet to be transmitted can take
+*  one or more ethernet driver transmit buffer.
+*
+*  In below are defined the size of one ethernet driver transmit buffer ETH_TX_BUF_SIZE
+*  and the total count of the driver transmit buffers ETH_TXBUFNB.
+*
+*  The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as
+*  example, they can be reconfigured in the application layer to fit the application
+*  needs
+*/
+
+/** Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet
+*   packet
+*/
+#ifndef ETH_TX_BUF_SIZE
+#define ETH_TX_BUF_SIZE         ETH_MAX_PACKET_SIZE
+#endif
+
+/** 5 ethernet driver transmit buffers are used (in a chained linked list)*/
+#ifndef ETH_TXBUFNB
+#define ETH_TXBUFNB             5U  /*!< 5  Tx buffers of size ETH_TX_BUF_SIZE */
+#endif
+
+/** ETHERNET MAC address offsets */
+#define ETH_MAC_ADDR_HBASE   (ETH_MAC_BASE + 0x40)      /*!< ETHERNET MAC address high offset */
+#define ETH_MAC_ADDR_LBASE    (ETH_MAC_BASE + 0x44)     /*!< ETHERNET MAC address low offset */
+
+/** ETHERNET Errors */
+#define  ETH_SUCCESS            1U
+#define  ETH_ERROR              0U
+
+/** ETHERNET DMA Tx descriptors Collision Count Shift */
+#define  ETH_DMATXDESC_COLLISION_COUNTSHIFT        3U
+
+/** ETHERNET DMA Tx descriptors Buffer2 Size Shift */
+#define  ETH_DMATXDESC_BUFFER2_SIZESHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Frame Length Shift */
+#define  ETH_DMARXDESC_FRAME_LENGTHSHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Buffer2 Size Shift */
+#define  ETH_DMARXDESC_BUFFER2_SIZESHIFT           16U
+
+/** ETHERNET DMA Rx descriptors Frame length Shift */
+#define  ETH_DMARXDESC_FRAMELENGTHSHIFT            16U
+
+/** ETHERNET MACMIIAR register Mask */
+#define ETH_MACMIIAR_CR_MASK    0xFFFFFFE3U
+
+/** ETHERNET MACCR register Mask */
+#define ETH_MACCR_CLEAR_MASK    0xFF20010FU
+
+/** ETHERNET MACFCR register Mask */
+#define ETH_MACFCR_CLEAR_MASK   0x0000FF41U
+
+/** ETHERNET DMAOMR register Mask */
+#define ETH_DMAOMR_CLEAR_MASK   0xF8DE3F23U
+
+/** ETHERNET Remote Wake-up frame register length */
+#define ETH_WAKEUP_REGISTER_LENGTH      8U
+
+/** ETHERNET Missed frames counter Shift */
+#define  ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT     17U
+
+/** PHY registers defines */
+
+/** PHY Read write Timeouts */
+#define PHY_READ_TIMEOUT                ((uint32_t)0x0004FFFF)
+#define PHY_WRITE_TIMEOUT               ((uint32_t)0x0004FFFF)
+
+/** PHY Register address */
+#define PHY_BCR                                      0         /*!< Transceiver Basic Control Register */
+#define PHY_BSR                                      1         /*!< Transceiver Basic Status Register */
+#define PHY_SR                                       16        /*!< Transceiver Status Register for dp83848 */
+
+/** PHY Status Register (PHYSTS), address 0x10 */
+#define PHY_DUPLEX_STATUS               ((uint16_t)0x0004)     /*!< for dp83848 ((uint16_t)0x0010) */
+#define PHY_SPEED_STATUS                ((uint16_t)0x0002)     /*!< for dp83848 ((uint16_t)0x0004) */
+
+/** PHY basic status register */
+#define PHY_AUTONEGO_COMPLETE           ((uint16_t)0x0020)     /*!< Auto-Negotiation process completed */
+#define PHY_LINKED_STATUS               ((uint16_t)0x0004)     /*!< Valid link established */
+#define PHY_JABBER_DETECTION            ((uint16_t)0x0002)     /*!< Jabber condition detected */
+
+/** PHY basic Control register */
+#define PHY_RESET                       ((uint16_t)0x8000)     /*!< PHY Reset */
+#define PHY_LOOPBACK                    ((uint16_t)0x4000)     /*!< Select loop-back mode */
+#define PHY_FULLDUPLEX_100M             ((uint16_t)0x2100)     /*!< Set the full-duplex mode at 100 Mb/s */
+#define PHY_HALFDUPLEX_100M             ((uint16_t)0x2000)     /*!< Set the half-duplex mode at 100 Mb/s */
+#define PHY_FULLDUPLEX_10M              ((uint16_t)0x0100)     /*!< Set the full-duplex mode at 10 Mb/s */
+#define PHY_HALFDUPLEX_10M              ((uint16_t)0x0000)     /*!< Set the half-duplex mode at 10 Mb/s */
+#define PHY_AUTONEGOTIATION             ((uint16_t)0x1000)     /*!< Enable auto-negotiation function */
+#define PHY_RESTAET_AUTONEGOTIATION     ((uint16_t)0x0200)     /*!< Restart auto-negotiation function */
+#define PHY_POWERDOWN                   ((uint16_t)0x0800)     /*!< Select the power down mode */
+#define PHY_ISOLATE                     ((uint16_t)0x0400)     /*!< Isolate PHY from MII */
+
+/** PHY Delay */
+#define PHY_RESET_DELAY                 ((uint32_t)0x000FFFFF) /*!< PHY reset delay */
+#define PHY_CONFIG_DELAY                ((uint32_t)0x00FFFFFF) /*!< PHY configuration delay */
+/** Delay to wait when writing to some Ethernet registers */
+#define ETH_REG_WRITE_DELAY             ((uint32_t)0x0000FFFF)
+
+/** Ethernet MAC MII Address Clock Range*/
+#define ETH_MACMIIAR_CR_DIV42   ((uint8_t)0x00)                 /*!< HCLK:60-100 MHz; MDC clock = HCLK/42 */
+#define ETH_MACMIIAR_CR_DIV62   ((uint8_t)0x01)                 /*!< HCLK:100-150 MHz; MDC clock = HCLK/62 */
+#define ETH_MACMIIAR_CR_DIV16   ((uint8_t)0x02)                 /*!< HCLK:20-35 MHz; MDC clock = HCLK/16 */
+#define ETH_MACMIIAR_CR_DIV26   ((uint8_t)0x03)                 /*!< HCLK:35-60 MHz; MDC clock = HCLK/26 */
+#define ETH_MACMIIAR_CR_DIV102  ((uint8_t)0x04)                 /*!< HCLK:150-168 MHz; MDC clock = HCLK/102 */
+
+/** Control the Enhanced DMA descriptors */
+#define USE_ENHANCED_DMA_DESCRIPTORS     1
+
+/**@} end of group ETH_Macros */
+
+
+/** @addtogroup ETH_Structure Data Structure
+  @{
+*/
+
+/**
+ * @brief    ETH MAC Config structure types
+ */
+typedef struct
+{
+    /** MAC Configuration */
+    ETH_AUTONEGOTIATION_T           autoNegotiation;            /*!< Selects or not the AutoNegotiation mode for the external PHY
+                                                                    The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps)
+                                                                    and the mode (half/full-duplex) */
+
+    ETH_WATCHDOG_T                  watchDog;                   /*!< Selects or not the Watchdog timer
+                                                                    When enabled, the MAC allows no more then 2048 bytes to be received.
+                                                                    When disabled, the MAC can receive up to 16384 bytes. */
+
+    ETH_JABBER_T                    jabber;                     /*!< Selects or not Jabber timer
+                                                                    When enabled, the MAC allows no more then 2048 bytes to be sent.
+                                                                    When disabled, the MAC can send up to 16384 bytes. */
+    ETH_INTERFRAMEGAP_T             interFrameGap;              /*!< Selects the minimum IFG between frames during transmission */
+
+    ETH_CARRIERSENCE_T              carrierSense;               /*!< Selects or not the Carrier Sense */
+
+    ETH_SPEED_T                     speed;                      /*!< Sets the Ethernet speed: 10/100 Mbps */
+
+    ETH_RECEIVEOWN_T                receiveOwn;                 /*!< Selects or not the ReceiveOwn
+                                                                    ReceiveOwn allows the reception of frames when the TX_EN signal is asserted
+                                                                    in Half-Duplex mode */
+
+    ETH_LOOPBACKMODE_T              loopbackMode;               /*!< Selects or not the internal MAC MII Loopback mode */
+
+    ETH_MODE_T                      mode;                       /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode */
+
+    ETH_CHECKSUMOFFLAOD_T           checksumOffload;            /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers. */
+
+    ETH_RETRYTRANSMISSION_T         retryTransmission;          /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL,
+                                                                    when a collision occurs (Half-Duplex mode) */
+
+    ETH_AUTOMATICPADCRCSTRIP_T      automaticPadCRCStrip;       /*!< Selects or not the Automatic MAC Pad/CRC Stripping */
+
+    ETH_BACKOFFLIMIT_T              backOffLimit;               /*!< Selects the BackOff limit value */
+
+    ETH_DEFFERRALCHECK_T            deferralCheck;              /*!< Selects or not the deferral check function (Half-Duplex mode) */
+
+    ETH_RECEIVEAll_T                receiveAll;                 /*!< Selects or not all frames reception by the MAC (No filtering) */
+
+    ETH_SOURCEADDRFILTER_T          sourceAddrFilter;           /*!< Selects the Source Address Filter mode */
+
+    ETH_PASSCONTROLFRAMES_T         passControlFrames;          /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames) */
+
+    ETH_BROADCASTFRAMESRECEPTION_T  broadcastFramesReception;   /*!< Selects or not the reception of Broadcast Frames */
+
+    ETH_DESTINATIONADDRFILTER_T     destinationAddrFilter;      /*!< Sets the destination filter mode for both unicast and multicast frames */
+
+    ETH_PROMISCUOUS_MODE_T          promiscuousMode;            /*!< Selects or not the Promiscuous Mode */
+
+    ETH_MULTICASTFRAMESFILTER_T     multicastFramesFilter;      /*!< Selects the Multicast Frames filter mode */
+
+    ETH_UNICASTFRAMESFILTER_T       unicastFramesFilter;        /*!< Selects the Unicast Frames filter mode */
+
+
+    uint32_t                        hashTableHigh;              /*!< This field holds the higher 32 bits of Hash table. */
+
+    uint32_t                        hashTableLow;               /*!< This field holds the lower 32 bits of Hash table. */
+
+    uint32_t                        pauseTime;                  /*!< This field holds the (value<=0xFFFF) to be used in the Pause Time */
+
+    ETH_ZEROQUANTAPAUSE_T           zeroQuantaPause;            /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames */
+
+    ETH_PAUSELOWTHRESHOLD_T         pauseLowThreshold;          /*!< This field configures the threshold of the PAUSE to be checked for
+                                                                    automatic retransmission of PAUSE Frame */
+
+    ETH_UNICASTPAUSEFRAMEDETECT_T   unicastPauseFrameDetect;    /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0
+                                                                    unicast address and unique multicast address) */
+
+    ETH_RECEIVEFLOWCONTROL_T        receiveFlowControl;         /*!< Enables or disables the MAC to decode the received Pause frame and
+                                                                    disable its transmitter for a specified time (Pause Time) */
+
+    ETH_TRANSMITFLOWCONTROL_T       transmitFlowControl;        /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode)
+                                                                    or the MAC back-pressure operation (Half-Duplex mode) */
+
+    ETH_VLANTAGCOMPARISON_T         VLANTagComparison;          /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for
+                                                                    comparison and filtering */
+
+    uint32_t                        VLANTagIdentifier;          /*!< Holds the (value <=0xFFFF) VLAN tag identifier for receive frames */
+
+    /** DMA Configuration */
+    ETH_DROPTCPIPCHECKSUMERRORFRAME_T   dropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames */
+
+    ETH_RECEIVESTOREFORWARD_T           receiveStoreForward;         /*!< Enables or disables the Receive store and forward mode */
+
+    ETH_FLUSHRECEIVEDFRAME_T            flushReceivedFrame;          /*!< Enables or disables the flushing of received frames */
+
+    ETH_TRANSMITSTOREFORWARD_T          transmitStoreForward;        /*!< Enables or disables Transmit store and forward mode */
+
+    ETH_TRANSMITTHRESHOLDCONTROL_T      transmitThresholdControl;    /*!< Selects or not the Transmit Threshold Control */
+
+    ETH_FORWARDERRORFRAMES_T            forwardErrorFrames;          /*!< Selects or not the forward to the DMA of erroneous frames */
+
+    ETH_FORWARDUNDERSIZEDGOODFRAMES_T   forwardUndersizedGoodFrames; /*!< Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error
+                                                                        and length less than 64 bytes) including pad-bytes and CRC) */
+
+    ETH_RECEIVEDTHRESHOLDCONTROL_T      receiveThresholdControl;     /*!< Selects the threshold level of the Receive FIFO */
+
+    ETH_SECONDFRAMEOPERARTE_T           secondFrameOperate;          /*!< Selects or not the Operate on second frame mode, which allows the DMA to process a second
+                                                                        frame of Transmit data even before obtaining the status for the first frame. */
+
+    ETH_ADDRESSALIGNEDBEATS_T           addressAlignedBeats;         /*!< Enables or disables the Address Aligned Beats */
+
+    ETH_FIXEDBURST_T                    fixedBurst;                  /*!< Enables or disables the AHB Master interface fixed burst transfers */
+
+    ETH_RXDMABURSTLENGTH_T              rxDMABurstLength;            /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction */
+
+    ETH_TXDMABURSTLENGTH_T              txDMABurstLength;            /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction */
+
+    uint32_t                            descriptorSkipLength;        /*!< Specifies the number of word to skip between two unchained descriptors (Ring mode) (value <= 0x1F) */
+
+    ETH_DMAARBITRATION_T                DMAArbitration;              /*!< Selects the DMA Tx/Rx arbitration */
+} ETH_Config_T;
+
+/**
+  * @brief  ETH DMA Descriptors data structure types
+  */
+typedef struct
+{
+    __IO uint32_t   Status;                            /*!< Status */
+    uint32_t        ControlBufferSize;                 /*!< Control and Buffer1, Buffer2 lengths */
+    uint32_t        Buffer1Addr;                       /*!< Buffer1 address pointer */
+    uint32_t        Buffer2NextDescAddr;               /*!< Buffer2 or next descriptor address pointer */
+    /* Enhanced ETHERNET DMA PTP Descriptors */
+    #if USE_ENHANCED_DMA_DESCRIPTORS
+    uint32_t        ExtendedStatus;                    /*!< Extended status for PTP receive descriptor */
+    uint32_t        Reserved1;                         /*!< Reserved */
+    uint32_t        TimeStampLow;                      /*!< Time Stamp Low value for transmit and receive */
+    uint32_t        TimeStampHigh;                     /*!< Time Stamp High value for transmit and receive */
+    #endif /* USE_ENHANCED_DMA_DESCRIPTORS */
+} ETH_DMADescConfig_T;
+
+/**
+  * @brief  ETH DMA Descriptors data structure types
+  */
+typedef struct
+{
+    uint32_t        length;                 /*!< Data length */
+    uint32_t        buffer;                 /*!< Data buffer */
+    __IO ETH_DMADescConfig_T *descriptor;   /*!< DMA descriptor */
+} ETH_Frame_T;
+
+/**
+  * @brief  ETH DMA Descriptors Received Frame Informations structure types
+  */
+typedef struct  {
+  __IO ETH_DMADescConfig_T   *FS_RxDesc;              /*!< First Segment Rx Desc */
+  __IO ETH_DMADescConfig_T   *LS_RxDesc;              /*!< Last Segment Rx Desc */
+  __IO uint32_t               segCount;               /*!< Segment count */
+} ETH_DMARxFrameInformations;
+
+/**@} end of group ETH_Structure*/
+
+/** @defgroup ETH_Functions
+  @{
+*/
+
+/* ETH Configuration */
+void ETH_Reset(void);
+void ETH_ConfigStructInit(ETH_Config_T* ethConfig);
+uint32_t ETH_Config(ETH_Config_T* ethConfig, uint16_t addr);
+void ETH_SoftwareReset(void);
+uint8_t ETH_ReadSoftwareReset(void);
+void ETH_Start(void);
+void ETH_Stop(void);
+uint32_t ETH_ReadRxPacketSize(ETH_DMADescConfig_T *DMARxDesc);
+#if USE_ENHANCED_DMA_DESCRIPTORS
+void ETH_EnableEnhancedDescriptor(void);
+void ETH_DisableEnhancedDescriptor(void);
+#endif /*!< USE_ENHANCED_DMA_DESCRIPTORS */
+
+/* PHY */
+uint16_t ETH_ReadPHYRegister(uint16_t addr, uint16_t reg);
+uint32_t ETH_WritePHYRegister(uint16_t addr, uint16_t reg, uint16_t data);
+uint32_t ETH_EnablePHYLoopBack(uint16_t addr);
+uint32_t ETH_DisablePHYLoopBack(uint16_t addr);
+
+/* MAC */
+void ETH_EnableMACTransmission(void);
+void ETH_DisableMACTransmission(void);
+void ETH_EnableMACReceiver(void);
+void ETH_DisableMACReceiver(void);
+uint8_t ETH_ReadFlowControlBusyStatus(void);
+void ETH_SetPauseControlFrame(void);
+void ETH_EnableBackPressureActivation(void);
+void ETH_DisableBackPressureActivation(void);
+uint8_t ETH_ReadMACFlagStatus(ETH_MAC_FLAG_T flag);
+void ETH_EnableMACInterrupt(uint32_t interrupt);
+void ETH_DisableMACInterrupt(uint32_t interrupt);
+void ETH_ConfigMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr);
+void ETH_ReadMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr);
+void ETH_EnableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr);
+void ETH_DisableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr);
+void ETH_ConfigMACAddressFilter(ETH_MAC_ADDRESS_T macAddr, ETH_MAC_ADDRESSFILTER_T filter);
+void ETH_ConfigMACAddressMaskBytesFilter(ETH_MAC_ADDRESS_T macAddr, uint32_t maskByte);
+
+/* DMA descriptors */
+void ETH_ConfigDMARxDescChain(ETH_DMADescConfig_T *DMARxDescTab, uint8_t *rxBuff, uint32_t rxBuffcount);
+void ETH_ConfigDMATxDescChain(ETH_DMADescConfig_T *DMATxDescTab, uint8_t* txBuff, uint32_t txBuffcount);
+uint32_t ETH_CheckReceivedFrame(void);
+uint32_t ETH_Transmit_Descriptors(u16 frameLength);
+ETH_Frame_T ETH_ReadReceivedFrame(void);
+uint8_t ETH_ReadDMATxDescFlagStatus(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_FLAG_T flag);
+uint32_t ETH_ReadDMATxDescCollisionCount(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescOwnBit(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescFrameSegment(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_SEGMENTS_T frameSegment);
+void ETH_ConfigDMATxDescChecksumInsertion(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_CHECKSUMB_T checksum);
+void ETH_EnableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_EnableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_DisableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc);
+void ETH_ConfigDMATxDescBufferSize(ETH_DMADescConfig_T *DMATxDesc, uint32_t bufferSize1, uint32_t bufferSize2);
+uint8_t ETH_ReadDMARxDescFlagStatus(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_FLAG_T flag);
+#if USE_ENHANCED_DMA_DESCRIPTORS
+uint8_t ETH_ReadDMAPTPRxDescExtendedFlagStatus(ETH_DMADescConfig_T *DMAPTPRxDesc, ETH_DMAPTPRXDESC_FLAG_T flag);
+#endif
+void ETH_ConfigDMARxDescOwnBit(ETH_DMADescConfig_T *DMARxDesc);
+uint32_t ETH_ReadDMARxDescFrameLength(ETH_DMADescConfig_T *DMARxDesc);
+void ETH_EnableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc);
+void ETH_DisableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMATxDesc);
+uint32_t ETH_ReadDMARxDescBufferSize(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_BUFFER_T buffer);
+ETH_Frame_T ETH_ReadReceivedFrameInterrupt(void);
+
+/* DMA */
+uint8_t ETH_ReadDMAFlagStatus(ETH_DMA_FLAG_T flag);
+void ETH_ClearDMAFlag(uint32_t flag);
+uint8_t ETH_ReadDMAIntFlag(ETH_DMA_INT_T flag);
+void ETH_ClearDMAIntFlag(uint32_t flag);
+uint32_t ETH_ReadTransmitProcessState(void);
+uint32_t ETH_ReadReceiveProcessState(void);
+void ETH_FlushTransmitFIFO(void);
+uint8_t ETH_ReadFlushTransmitFIFOStatus(void);
+void ETH_EnableDMATransmission(void);
+void ETH_DisableDMATransmission(void);
+void ETH_EnableDMAReceiver(void);
+void ETH_DisableDMAReceiver(void);
+void ETH_EnableDMAInterrupt(uint32_t interrupt);
+void ETH_DisableDMAInterrupt(uint32_t interrupt);
+uint8_t ETH_ReadDMAOverflowStatus(ETH_DMA_OVERFLOW_T overflow);
+uint32_t ETH_ReadRxOverflowMissedFrameCounter(void);
+uint32_t ETH_ReadBufferUnavailableMissedFrameCounter(void);
+uint32_t ETH_ReadCurrentTxDescStartAddress(void);
+uint32_t ETH_ReadCurrentRxDescStartAddress(void);
+uint32_t ETH_ReadCurrentTxBufferAddress(void);
+uint32_t ETH_ReadCurrentRxBufferAddress(void);
+void ETH_ResetDMATransmission(void);
+void ETH_ResetDMAReception(void);
+void ETH_ConfigReceiveWatchdogTimer(uint8_t value);
+
+/* PMT */
+void ETH_ResetWakeUpFrameFilterRegisterPointer(void);
+void ETH_ConfigWakeUpFrameFilterRegister(uint32_t *buffer);
+void ETH_EnableGlobalUnicastWakeUp(void);
+void ETH_DisableGlobalUnicastWakeUp(void);
+uint8_t ETH_ReadPMTFlagStatus(ETH_PMT_FLAG_T flag);
+void ETH_EnableWakeUpFrameDetection(void);
+void ETH_DisableWakeUpFrameDetection(void);
+void ETH_EnableMagicPacketDetection(void);
+void ETH_DisableMagicPacketDetection(void);
+void ETH_EnablePowerDown(void);
+void ETH_DisablePowerDown(void);
+
+/* MMC */
+void ETH_PresetMMCCounterFull(void);
+void ETH_PresetMMCCounterHalf(void);
+void ETH_EnableMMCCounterFreeze(void);
+void ETH_DisableMMCCounterFreeze(void);
+void ETH_EnableMMCResetOnRead(void);
+void ETH_DisableMMCResetOnRead(void);
+void ETH_EnableMMCCounterRollover(void);
+void ETH_DisableMMCCounterRollover(void);
+void ETH_ResetMMCCounters(void);
+void ETH_EnableMMCInterrupt(uint32_t interrupt);
+void ETH_DisableMMCInterrupt(uint32_t interrupt);
+uint8_t ETH_ReadMMCIntFlag(uint32_t flag);
+uint32_t ETH_ReadMMCRegister(ETH_MMC_REG_T MMCReg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /** __APM32F4xx_ETH_H */
+
+/**@} end of group ETH_Functions */
+/**@} end of group ETH_Driver */
+/**@} end of group APM32F4xx_ETHDriver */

+ 2308 - 0
project_0/libraries/APM32F4xx_Library/APM32F4xx_ETH_Driver/src/apm32f4xx_eth.c

@@ -0,0 +1,2308 @@
+/*!
+ * @file        apm32f4xx_eth.c
+ *
+ * @brief       This file provides all the ETH firmware functions
+ *
+ * @version     V1.0.2
+ *
+ * @date        2022-06-23
+ *
+ * @attention
+ *
+ *  Copyright (C) 2021-2022 Geehy Semiconductor
+ *
+ *  You may not use this file except in compliance with the
+ *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
+ *
+ *  The program is only for reference, which is distributed in the hope
+ *  that it will be usefull and instructional for customers to develop
+ *  their software. Unless required by applicable law or agreed to in
+ *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
+ *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
+ *  and limitations under the License.
+ */
+
+#include "apm32f4xx_eth.h"
+#include "apm32f4xx_rcm.h"
+
+/** @addtogroup APM32F4xx_ETHDriver
+  @{
+*/
+
+/** @defgroup ETH_Driver
+  * @brief ETH driver modules
+  @{
+*/
+
+#if defined   (__CC_ARM) /*!< ARM Compiler */
+__align(4)
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB]; /*!< Ethernet Rx MA Descriptor */
+__align(4)
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB]; /*!< Ethernet Tx DMA Descriptor */
+__align(4)
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];  /*!< Ethernet Receive Buffer */
+__align(4)
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];  /*!< Ethernet Transmit Buffer */
+
+#elif defined ( __ICCARM__ )
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB]; /*!< Ethernet Rx MA Descriptor */
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB]; /*!< Ethernet Tx DMA Descriptor */
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];  /*!< Ethernet Receive Buffer */
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];  /*!< Ethernet Transmit Buffer */
+
+#elif defined (__GNUC__) /*!< GNU Compiler */
+ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB] __attribute__ ((aligned (4))); /*!< Ethernet Rx MA Descriptor */
+ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB] __attribute__ ((aligned (4))); /*!< Ethernet Tx DMA Descriptor */
+uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __attribute__ ((aligned (4)));  /*!< Ethernet Receive Buffer */
+uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __attribute__ ((aligned (4)));  /*!< Ethernet Transmit Buffer */
+
+#endif
+
+/** @defgroup Global_Definition
+  @{
+*/
+
+/* Global pointers on Tx and Rx descriptor used to transmit and receive descriptors */
+__IO ETH_DMADescConfig_T  *DMATxDescToSet;
+__IO ETH_DMADescConfig_T  *DMARxDescToGet;
+
+/* Structure used to hold the last received packet descriptors info */
+ETH_DMARxFrameInformations      RxFrameDescriptor;
+__IO ETH_DMARxFrameInformations *DMARxFraminfos;
+__IO uint32_t FrameRxindex;
+
+/**
+  * @}
+  */
+
+/** @defgroup ETH_Functions
+  @{
+*/
+
+/*!
+ * @brief  Inserts a delay time.
+ *
+ * @param  count: specifies the delay time length.
+ *
+ * @retval None
+ */
+static void ETH_Delay(__IO uint32_t count)
+{
+    __IO uint32_t i = 0;
+    for(i = count; i!= 0; i--)
+    {
+    }
+}
+
+/** ETH Configuration */
+
+/*!
+ * @brief  Reset ETH peripheral registers to their default reset values.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_Reset(void)
+{
+    RCM_EnableAHB1PeriphReset(RCM_AHB1_PERIPH_ETH_MAC);
+    RCM_DisableAHB1PeriphReset(RCM_AHB1_PERIPH_ETH_MAC);
+}
+
+/*!
+ * @brief  Config ETH_Config_T member with its default value.
+ *
+ * @param  ethConfig: pointer to a ETH_Config_T structure which will be initialized.
+ *
+ * @retval None
+ */
+void ETH_ConfigStructInit(ETH_Config_T* ethConfig)
+{
+    /* MAC Configuration */
+    ethConfig->autoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+    ethConfig->watchDog = ETH_WATCHDOG_ENABLE;
+    ethConfig->jabber = ETH_JABBER_ENABLE;
+    ethConfig->interFrameGap = ETH_INTERFRAMEGAP_96BIT;
+    ethConfig->carrierSense = ETH_CARRIERSENCE_ENABLE;
+    ethConfig->speed = ETH_SPEED_100M;
+    ethConfig->receiveOwn = ETH_RECEIVEOWN_ENABLE;
+    ethConfig->loopbackMode = ETH_LOOPBACKMODE_DISABLE;
+    ethConfig->mode = ETH_MODE_FULLDUPLEX;
+    ethConfig->checksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
+    ethConfig->retryTransmission = ETH_RETRYTRANSMISSION_ENABLE;
+    ethConfig->automaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
+    ethConfig->backOffLimit = ETH_BACKOFFLIMIT_10;
+    ethConfig->deferralCheck = ETH_DEFFERRALCHECK_DISABLE;
+    ethConfig->receiveAll = ETH_RECEIVEAll_DISABLE;
+    ethConfig->sourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
+    ethConfig->passControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
+    ethConfig->broadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_DISABLE;
+    ethConfig->destinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
+    ethConfig->promiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
+    ethConfig->multicastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
+    ethConfig->unicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
+    ethConfig->hashTableHigh = 0x0000;
+    ethConfig->hashTableLow = 0x0000;
+    ethConfig->pauseTime = 0x0000;
+    ethConfig->zeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
+    ethConfig->pauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
+    ethConfig->unicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
+    ethConfig->receiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
+    ethConfig->transmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
+    ethConfig->VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
+    ethConfig->VLANTagIdentifier = 0x0000;
+    /* DMA Configuration */
+    ethConfig->dropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE;
+    ethConfig->receiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
+    ethConfig->flushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
+    ethConfig->transmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
+    ethConfig->transmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
+    ethConfig->forwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
+    ethConfig->forwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
+    ethConfig->receiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
+    ethConfig->secondFrameOperate = ETH_SECONDFRAMEOPERARTE_DISABLE;
+    ethConfig->addressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
+    ethConfig->fixedBurst = ETH_FIXEDBURST_ENABLE;
+    ethConfig->rxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
+    ethConfig->txDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
+    ethConfig->descriptorSkipLength = 0x00;
+    ethConfig->DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
+}
+
+/*!
+ * @brief  Config the ETH peripheral parameters in the ethConfig.
+ *
+ * @param  ethConfig: pointer to a ETH_Config_T structure.
+ *
+ * @param  addr: external PHY address
+ *
+ * @retval ETH_ERROR: Ethernet initialization error
+ *         ETH_SUCCESS: Ethernet initialization success
+ */
+uint32_t ETH_Config(ETH_Config_T* ethConfig, uint16_t addr)
+{
+    uint32_t regValue = 0;
+    uint32_t hclk = 60000000;
+    __IO uint32_t timeout = 0, err = ETH_SUCCESS;
+
+    hclk = RCM_ReadHCLKFreq();
+
+    if((hclk >= 20000000) && (hclk <= 35000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV16;
+    }
+    else if((hclk >= 35000000)&&(hclk < 60000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV26;
+    }
+    else if((hclk >= 60000000)&&(hclk < 100000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV42;
+    }
+    else if((hclk >= 100000000)&&(hclk < 150000000))
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV62;
+    }
+    else
+    {
+        ETH->ADDR_B.CR = ETH_MACMIIAR_CR_DIV102;
+    }
+
+    /* PHY initialization and configuration */
+    if(!(ETH_WritePHYRegister(addr, PHY_BCR, PHY_RESET)))
+    {
+    /* Return ERROR in case of write timeout */
+    err = ETH_ERROR;
+    goto error;
+    }
+
+    ETH_Delay(PHY_RESET_DELAY);
+
+    if(ethConfig->autoNegotiation == ETH_AUTONEGOTIATION_ENABLE)
+    {
+        /* Wait for linked status */
+        do
+        {
+            timeout++ ;
+        } while(!(ETH_ReadPHYRegister(addr,PHY_BSR) & PHY_LINKED_STATUS) && (timeout < PHY_READ_TIMEOUT));
+
+        /* Return ERROR in case of timeout */
+        if(timeout == PHY_READ_TIMEOUT)
+        {
+            err = ETH_ERROR;
+            goto error;
+        }
+
+        timeout = 0;
+        /* Enable Auto-Negotiation */
+        if(!(ETH_WritePHYRegister(addr, PHY_BCR, PHY_AUTONEGOTIATION)))
+        {
+            /* Return ERROR in case of write timeout */
+            err = ETH_ERROR;
+        }
+
+        /* Wait until the auto-negotiation will be completed */
+        do
+        {
+        timeout++;
+        } while (!(ETH_ReadPHYRegister(addr, PHY_BSR) & PHY_AUTONEGO_COMPLETE) && (timeout < (uint32_t)PHY_READ_TIMEOUT));
+
+        /* Return ERROR in case of timeout */
+        if(timeout == PHY_READ_TIMEOUT)
+        {
+            err = ETH_ERROR;
+            goto error;
+        }
+
+        timeout = 0;
+        /* Read the result of the auto-negotiation */
+        regValue = ETH_ReadPHYRegister(addr, PHY_SR);
+
+        if((regValue & PHY_DUPLEX_STATUS) != (uint32_t)RESET)
+        {
+            ethConfig->mode = ETH_MODE_FULLDUPLEX;
+        }
+        else
+        {
+            ethConfig->mode = ETH_MODE_HALFDUPLEX;
+        }
+        if(regValue & PHY_SPEED_STATUS)
+        {
+            ethConfig->speed = ETH_SPEED_10M;
+        }
+        else
+        {
+            ethConfig->speed = ETH_SPEED_100M;
+        }
+    }
+    else
+    {
+        if(!ETH_WritePHYRegister(addr, PHY_BCR,((uint16_t)(ethConfig->speed << 8) |
+                                                (uint16_t)(ethConfig->mode  << 13))))
+        {
+            err = ETH_ERROR;
+        }
+
+        ETH_Delay(PHY_CONFIG_DELAY);
+    }
+error:
+    if(err == ETH_ERROR)
+    {
+        ethConfig->speed = ETH_SPEED_100M;
+        ethConfig->mode = ETH_MODE_FULLDUPLEX;
+    }
+
+    /* ETHERNET MAC_CFG Configuration */
+    ETH->CFG_B.WDTDIS = ethConfig->watchDog;
+    ETH->CFG_B.JDIS   = ethConfig->jabber;
+    ETH->CFG_B.IFG    = ethConfig->interFrameGap;
+    ETH->CFG_B.DISCRS = ethConfig->carrierSense;
+    ETH->CFG_B.SSEL   = ethConfig->speed;
+    ETH->CFG_B.DISRXO = ethConfig->receiveOwn;
+    ETH->CFG_B.LBM    = ethConfig->loopbackMode;
+    ETH->CFG_B.DM     = ethConfig->mode;
+    ETH->CFG_B.IPC    = ethConfig->checksumOffload;
+    ETH->CFG_B.DISR   = ethConfig->retryTransmission;
+    ETH->CFG_B.ACS    = ethConfig->automaticPadCRCStrip;
+    ETH->CFG_B.BL     = ethConfig->backOffLimit;
+    ETH->CFG_B.DC     = ethConfig->deferralCheck;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_FRAF Configuration */
+    ETH->FRAF_B.RXA    = ethConfig->receiveAll;
+    ETH->FRAF         |= ethConfig->sourceAddrFilter;
+    ETH->FRAF_B.PCTRLF = ethConfig->passControlFrames;
+    ETH->FRAF_B.DISBF  = ethConfig->broadcastFramesReception;
+    ETH->FRAF_B.DAIF   = ethConfig->destinationAddrFilter;
+    ETH->FRAF_B.PR     = ethConfig->promiscuousMode;
+    ETH->FRAF         |= ethConfig->multicastFramesFilter;
+    ETH->FRAF         |= ethConfig->unicastFramesFilter;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_HTH/HTL Configuration */
+    ETH->HTH = ethConfig->hashTableHigh;
+    ETH->HTL = ethConfig->hashTableLow;
+
+    /* ETHERNET MAC_FCTRL Configuration */
+    ETH->FCTRL_B.PT        = ethConfig->pauseTime;
+    ETH->FCTRL_B.ZQPDIS    = ethConfig->zeroQuantaPause;
+    ETH->FCTRL_B.PTSEL     = ethConfig->pauseLowThreshold;
+    ETH->FCTRL_B.UNPFDETE  = ethConfig->unicastPauseFrameDetect;
+    ETH->FCTRL_B.RXFCTRLEN = ethConfig->receiveFlowControl;
+    ETH->FCTRL_B.TXFCTRLEN = ethConfig->transmitFlowControl;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET MAC_VLANT Configuration */
+    ETH->VLANT_B.VLANTCOMP = ethConfig->VLANTagComparison;
+    ETH->VLANT_B.VLANTID   = ethConfig->VLANTagIdentifier;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET DMA_OPMOD Configuration */
+    ETH->DMAOPMOD_B.DISDT    = ethConfig->dropTCPIPChecksumErrorFrame;
+    ETH->DMAOPMOD_B.RXSF     = ethConfig->receiveStoreForward;
+    ETH->DMAOPMOD_B.DISFRXF  = ethConfig->flushReceivedFrame;
+    ETH->DMAOPMOD_B.TXSF     = ethConfig->transmitStoreForward;
+    ETH->DMAOPMOD_B.TXTHCTRL = ethConfig->transmitThresholdControl;
+    ETH->DMAOPMOD_B.FERRF    = ethConfig->forwardErrorFrames;
+    ETH->DMAOPMOD_B.FUF      = ethConfig->forwardUndersizedGoodFrames;
+    ETH->DMAOPMOD_B.RXTHCTRL = ethConfig->receiveThresholdControl;
+    ETH->DMAOPMOD_B.OSECF    = ethConfig->secondFrameOperate;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+    /* ETHERNET DMA_BMOD Configuration */
+    ETH->DMABMOD = RESET;
+    ETH->DMABMOD_B.AAL = ethConfig->addressAlignedBeats;
+    ETH->DMABMOD_B.FB = ethConfig->fixedBurst;
+    ETH->DMABMOD |= ethConfig->rxDMABurstLength;
+    ETH->DMABMOD |= ethConfig->txDMABurstLength;
+    ETH->DMABMOD_B.DSL = ethConfig->descriptorSkipLength;
+    ETH->DMABMOD |= ethConfig->DMAArbitration;
+    ETH->DMABMOD_B.USP = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+    ETH->DMABMOD_B.EDFEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+#endif
+
+    if(err == ETH_SUCCESS)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/*!
+ * @brief  Resets all MAC subsystem internal registers and logic.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_SoftwareReset(void)
+{
+    ETH->DMABMOD_B.SWR = SET;
+}
+
+/*!
+ * @brief  Read the ETH software reset bit.
+ *
+ * @param  None
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadSoftwareReset(void)
+{
+    return ETH->DMABMOD_B.SWR;
+}
+
+/*!
+ * @brief     Enables ETH MAC and DMA reception/transmission
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ETH_Start(void)
+{
+    ETH_EnableMACTransmission();
+    ETH_EnableMACReceiver();
+    ETH_FlushTransmitFIFO();
+    ETH_EnableDMATransmission();
+    ETH_EnableDMAReceiver();
+}
+
+/*!
+ * @brief     Disables ETH MAC and DMA reception/transmission
+ *
+ * @param     None
+ *
+ * @retval    None
+ */
+void ETH_Stop(void)
+{
+    ETH_DisableDMATransmission();
+    ETH_DisableDMAReceiver();
+    ETH_DisableMACReceiver();
+    ETH_FlushTransmitFIFO();
+    ETH_DisableMACTransmission();
+}
+
+/*!
+ * @brief  Read the size of the received packet.
+ *
+ * @param  None
+ *
+ * @retval frameLength: received packet size
+ */
+uint32_t ETH_ReadRxPacketSize(ETH_DMADescConfig_T *DMARxDesc)
+{
+    uint32_t frameLength = 0;
+    if(((DMARxDesc->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+       ((DMARxDesc->Status & ETH_DMARXDESC_ERRS)  == (uint32_t)RESET) &&
+       ((DMARxDesc->Status & ETH_DMARXDESC_LDES)  != (uint32_t)RESET))
+    {
+        frameLength =  ETH_ReadDMARxDescFrameLength(DMARxDesc);
+    }
+    return frameLength;
+}
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+/*!
+ * @brief  Enable the Enhanced descriptor structure.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableEnhancedDescriptor(void)
+{
+     ETH->DMABMOD_B.EDFEN = SET;
+}
+
+/*!
+ * @brief  Disable the Enhanced descriptor structure.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableEnhancedDescriptor(void)
+{
+     ETH->DMABMOD_B.EDFEN = RESET;
+}
+#endif /** USE_ENHANCED_DMA_DESCRIPTORS */
+
+/** PHY functions */
+
+/*!
+ * @brief  Read a PHY register
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @param  reg:  PHY register
+ *               This parameter can be one of the following values:
+ *               @arg PHY_BCR : Transceiver Basic Control Register
+ *               @arg PHY_BSR : Transceiver Basic Status Register
+ *               @arg PHY_SR  :  Transceiver Status Register
+ *
+ * @retval ETH_ERROR: in case of timeout
+ *         MAC DATA register value: Data read from the selected PHY register
+ */
+uint16_t ETH_ReadPHYRegister(uint16_t addr, uint16_t reg)
+{
+    __IO uint32_t timeout = 0;
+
+    ETH->ADDR_B.PA = addr;
+    ETH->ADDR_B.MR = reg;
+    ETH->ADDR_B.MW = RESET;
+    ETH->ADDR_B.MB = SET;
+    /* Check for the Busy flag */
+    do
+    {
+        timeout++ ;
+    } while ((ETH->ADDR_B.MB == SET) && (timeout < PHY_READ_TIMEOUT));
+    /* Return ERROR in case of timeout */
+    if(timeout == PHY_READ_TIMEOUT)
+    {
+        return ETH_ERROR;
+    }
+    /* Return data register value */
+    return (uint16_t)(ETH->DATA);
+}
+
+/*!
+ * @brief  Write to a PHY register
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+
+ * @param  reg:  PHY register
+ *               This parameter can be one of the following values:
+ *               @arg PHY_BCR : Transceiver Basic Control Register
+
+ * @param  data: the data to write
+ *
+ * @retval ETH_ERROR: write timeout
+ *         ETH_SUCCESS: write success
+ */
+uint32_t ETH_WritePHYRegister(uint16_t addr, uint16_t reg, uint16_t data)
+{
+    __IO uint32_t timeout = 0;
+
+    ETH->DATA = data;
+    ETH->ADDR_B.PA = addr;
+    ETH->ADDR_B.MR = reg;
+    ETH->ADDR_B.MW = SET;
+    ETH->ADDR_B.MB = SET;
+
+    /* Check for the Busy flag */
+    do
+    {
+        timeout++ ;
+    } while ((ETH->ADDR_B.MB == SET) && (timeout < PHY_WRITE_TIMEOUT));
+    /* Return ERROR in case of timeout */
+    if(timeout == PHY_WRITE_TIMEOUT)
+    {
+        return ETH_ERROR;
+    }
+    /* Return data register value */
+    return ETH_SUCCESS;
+}
+
+/*!
+ * @brief  Enable the PHY loopBack mode.
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_EnablePHYLoopBack(uint16_t addr)
+{
+    uint16_t temp = 0;
+
+    temp = ETH_ReadPHYRegister(addr,PHY_BCR);
+    temp |= PHY_LOOPBACK;
+
+    if(ETH_WritePHYRegister(addr,PHY_BCR,temp) == SET)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/*!
+ * @brief  Disable the PHY loopBack mode.
+ *
+ * @param  addr: PHY device address
+ *               This parameter can be one of the following values: 0,..,31
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_DisablePHYLoopBack(uint16_t addr)
+{
+    uint16_t temp = 0;
+
+    temp = ETH_ReadPHYRegister(addr,PHY_BCR);
+    temp &= ((uint16_t)~PHY_LOOPBACK);
+
+    if(ETH_WritePHYRegister(addr,PHY_BCR,temp) == SET)
+    {
+        return ETH_SUCCESS;
+    }
+    else
+    {
+        return ETH_ERROR;
+    }
+}
+
+/* MAC functions */
+
+/*!
+ * @brief  Enable the MAC transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMACTransmission(void)
+{
+    ETH->CFG_B.TXEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMACTransmission(void)
+{
+    ETH->CFG_B.TXEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMACReceiver(void)
+{
+    ETH->CFG_B.RXEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMACReceiver(void)
+{
+    ETH->CFG_B.RXEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH flow control busy status
+ *
+ * @param  None
+ *
+ * @retval SET or RESET
+ */
+uint8_t ETH_ReadFlowControlBusyStatus(void)
+{
+    return ETH->FCTRL_B.FCTRLB;
+}
+
+/*!
+ * @brief  Set a Pause Control Frame (Full-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_SetPauseControlFrame(void)
+{
+    ETH->FCTRL_B.FCTRLB = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Back Pressure operation activation (Half-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableBackPressureActivation(void)
+{
+    ETH->FCTRL_B.FCTRLB = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Back Pressure operation activation (Half-duplex only).
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableBackPressureActivation(void)
+{
+    ETH->FCTRL_B.FCTRLB = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the specified ETH MAC flag
+ *
+ * @param  flag: Ethernet MAC flag:
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_FLAG_TST  : Time stamp trigger flag
+ *           @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
+ *           @arg ETH_MAC_FLAG_MMCR : MMC receive flag
+ *           @arg ETH_MAC_FLAG_MMC  : MMC flag
+ *           @arg ETH_MAC_FLAG_PMT  : PMT flag
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadMACFlagStatus(ETH_MAC_FLAG_T flag)
+{
+    return (ETH->ISTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Enable the specified ETH MAC interrupts.
+ *
+ * @param  interrupt: Ethernet MAC interrupt flag:
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
+ *           @arg ETH_MAC_INT_PMT : PMT interrupt
+ *
+ * @retval None
+ */
+void ETH_EnableMACInterrupt(uint32_t interrupt)
+{
+    ETH->IMASK |= interrupt;
+}
+
+/*!
+ * @brief  Disable the specified ETH MAC interrupts.
+ *
+ * @param  interrupt: Ethernet MAC interrupt flag:
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_INT_TST : Time stamp trigger interrupt
+ *           @arg ETH_MAC_INT_PMT : PMT interrupt
+ *
+ * @retval None
+ */
+void ETH_DisableMACInterrupt(uint32_t interrupt)
+{
+    ETH->IMASK &= (~(uint32_t)interrupt);
+}
+
+/*!
+ * @brief  Config the MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS0 : MAC Address0
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  addr: Pointer on MAC address buffer data (6 bytes).
+ *
+ * @retval None
+ */
+void ETH_ConfigMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr)
+{
+    uint32_t temp;
+
+    temp = ((uint32_t)addr[5] << 8) | (uint32_t)addr[4];
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+
+    temp = ((uint32_t)addr[3] << 24) | ((uint32_t)addr[2] << 16) | ((uint32_t)addr[1] << 8) | addr[0];
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Read the MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS0 : MAC Address0
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  addr: Pointer on MAC address buffer data (6 bytes).
+ *
+ * @retval None
+ */
+void ETH_ReadMACAddress(ETH_MAC_ADDRESS_T macAddr, uint8_t *addr)
+{
+    uint32_t temp;
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+
+    addr[5] = ((temp >> 8) & 0xFF);
+    addr[4] = (temp & 0xFF);
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_LBASE + macAddr));
+    addr[3] = ((temp >> 24) & 0xFF);
+    addr[2] = ((temp >> 16) & 0xFF);
+    addr[1] = ((temp >> 8)  & 0xFF);
+    addr[0] = (temp & 0xFF);
+}
+
+/*!
+ * @brief  Enable address filters module uses the MAC address for perfect filtering.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @retval None
+ */
+void ETH_EnableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr)
+{
+    __IO uint32_t temp = 0;
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= BIT31;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Disable address filters module uses the MAC address for perfect filtering.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @retval None
+ */
+void ETH_DisableMACAddressPerfectFilter(ETH_MAC_ADDRESS_T macAddr)
+{
+    __IO uint32_t temp = 0;
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) &= (~BIT31);
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/*!
+ * @brief  Config the filter type for the MAC address
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  filter: Comparison with the SA/DA fields of the received frame.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESSFILTER_SA : MAC Address is used to compare with the
+ *                                           SA fields of the received frame.
+ *           @arg ETH_MAC_ADDRESSFILTER_DA : MAC Address is used to compare with the
+ *                                           DA fields of the received frame.
+ * @retval None
+ */
+void ETH_ConfigMACAddressFilter(ETH_MAC_ADDRESS_T macAddr, ETH_MAC_ADDRESSFILTER_T filter)
+{
+    if(filter == ETH_MAC_ADDRESSFILTER_SA)
+    {
+        (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= ETH_MAC_ADDRESSFILTER_SA;
+    }
+    else
+    {
+        (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= ETH_MAC_ADDRESSFILTER_DA;
+    }
+
+}
+
+/*!
+ * @brief  Config the filter type for the ETH MAC address.
+ *
+ * @param  macAddr: The MAC address.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MAC_ADDRESS1 : MAC Address1
+ *           @arg ETH_MAC_ADDRESS2 : MAC Address2
+ *           @arg ETH_MAC_ADDRESS3 : MAC Address3
+ *
+ * @param  MaskByte: specifies the used address bytes for comparison
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE6 : Mask MAC Address high reg bits [15:8].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE5 : Mask MAC Address high reg bits [7:0].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE4 : Mask MAC Address low reg bits [31:24].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE3 : Mask MAC Address low reg bits [23:16].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE2 : Mask MAC Address low reg bits [15:8].
+ *           @arg ETH_MAC_ADDRESSMASK_BYTE1 : Mask MAC Address low reg bits [7:0].
+ *
+ * @retval None
+ */
+void ETH_ConfigMACAddressMaskBytesFilter(ETH_MAC_ADDRESS_T macAddr, uint32_t maskByte)
+{
+    __IO uint32_t temp = 0;
+
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) &=(~(uint32_t)0x3F000000);
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+
+    /* Set the selected Filter mask bytes */
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) |= maskByte;
+
+    temp = (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr));
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+    (*(__IO uint32_t *) (ETH_MAC_ADDR_HBASE + macAddr)) = temp;
+}
+
+/** DMA Descriptors functions */
+
+/*!
+ * @brief  Config the DMA Rx descriptors in chain mode.
+ *
+ * @param  DMARxDescTab: Pointer on the first Rx desc list
+ *
+ * @param  rxBuff: Pointer on the first RxBuffer list
+ *
+ * @param  rxBuffcount: Number of the used Rx desc in the list
+ *
+ * @retval None
+ */
+void ETH_ConfigDMARxDescChain(ETH_DMADescConfig_T *DMARxDescTab, uint8_t *rxBuff, uint32_t rxBuffcount)
+{
+    uint32_t i = 0;
+    ETH_DMADescConfig_T *DMARxDesc;
+    DMARxDescToGet = DMARxDescTab;
+
+    for(i=0; i< rxBuffcount; i++)
+    {
+        DMARxDesc = DMARxDescTab+i;
+        DMARxDesc->Status = ETH_DMARXDESC_OWN;
+        DMARxDesc->ControlBufferSize = ETH_DMARXDESC_RXCH | ETH_RX_BUF_SIZE;
+        DMARxDesc->Buffer1Addr = (uint32_t)(&rxBuff[i*ETH_RX_BUF_SIZE]);
+        if(i < (rxBuffcount-1))
+        {
+            DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1);
+        }
+        else
+        {
+            DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab);
+        }
+    }
+
+
+    ETH->DMARXDLADDR = (uint32_t) DMARxDescTab;
+    DMARxFraminfos =&RxFrameDescriptor;
+}
+
+/*!
+ * @brief  Initializes the DMA Tx descriptors in chain mode.
+ *
+ * @param  DMATxDescTab: Pointer on the first Tx desc list
+ *
+ * @param  txBuff: Pointer on the first TxBuffer list
+ *
+ * @param  txBuffcount: Number of the used Tx desc in the list
+ *
+ * @retval None
+  */
+void ETH_ConfigDMATxDescChain(ETH_DMADescConfig_T *DMATxDescTab, uint8_t* txBuff, uint32_t txBuffcount)
+{
+    uint32_t i = 0;
+    ETH_DMADescConfig_T *DMATxDesc;
+    DMATxDescToSet = DMATxDescTab;
+
+    for(i=0; i< txBuffcount; i++)
+    {
+        DMATxDesc = DMATxDescTab+i;
+        DMATxDesc->Status = ETH_DMATXDESC_TXCH;
+        DMATxDesc->Buffer1Addr = (uint32_t)(&txBuff[i*ETH_TX_BUF_SIZE]);
+        if(i < (txBuffcount-1))
+        {
+            DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1);
+        }
+        else
+        {
+            DMATxDesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab);
+        }
+    }
+
+    ETH->DMATXDLADDR = (uint32_t) DMATxDescTab;
+}
+
+/*!
+ * @brief  This function polls for a frame receiver
+ *
+ * @param  None
+ *
+ * @retval Returns 1 when a frame is received, 0 if none.
+ */
+uint32_t ETH_CheckReceivedFrame(void)
+{
+    if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+        ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET))
+    {
+        DMARxFraminfos->segCount++;
+        if(DMARxFraminfos->segCount == 1)
+        {
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+        }
+        DMARxFraminfos->LS_RxDesc = DMARxDescToGet;
+        return 1;
+    }
+    else if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+    {
+        DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+        DMARxFraminfos->LS_RxDesc = NULL;
+        DMARxFraminfos->segCount  = 1;
+        DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+    }
+    else if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) == (uint32_t)RESET) &&
+             ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+    {
+        (DMARxFraminfos->segCount) ++;
+        DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+    }
+    return 0;
+}
+
+/*!
+ * @brief  Prepares DMA Tx descriptors to transmit an ethernet frame
+ *
+ * @param  FrameLength : length of the frame to send
+ *
+ * @retval ETH_ERROR or ETH_SUCCESS
+ */
+uint32_t ETH_Transmit_Descriptors(u16 frameLength)
+{
+    uint32_t count=0, size=0, i=0;
+    __IO ETH_DMADescConfig_T  *DMATxDesc;
+
+    if((DMATxDescToSet->Status & ETH_DMATXDESC_OWN) == SET)
+    {
+        return ETH_ERROR;
+    }
+
+    DMATxDesc = DMATxDescToSet;
+
+    if(frameLength > ETH_TX_BUF_SIZE)
+    {
+        count = frameLength/ETH_TX_BUF_SIZE;
+        if(frameLength%ETH_TX_BUF_SIZE) count++;
+    }
+    else count =1;
+
+    if(count == 1)
+    {
+        DMATxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
+        DMATxDesc->ControlBufferSize = (frameLength & ETH_DMATXDESC_TXBS1);
+        DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+        DMATxDesc = (ETH_DMADescConfig_T*) (DMATxDesc->Buffer2NextDescAddr);
+    }
+    else
+    {
+        for(i=0; i<count; i++)
+        {
+            DMATxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS);
+
+            if(i==0)
+            {
+                DMATxDesc->Status |= ETH_DMATXDESC_FS;
+            }
+            DMATxDesc->ControlBufferSize =(ETH_TX_BUF_SIZE & ETH_DMATXDESC_TXBS1);
+
+            if(i== (count-1))
+            {
+                DMATxDesc->Status |= ETH_DMATXDESC_LS;
+                size = frameLength - (count-1)*ETH_TX_BUF_SIZE;
+                DMATxDesc->ControlBufferSize =(size & ETH_DMATXDESC_TXBS1);
+            }
+
+            DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+            DMATxDesc = (ETH_DMADescConfig_T*) (DMATxDesc->Buffer2NextDescAddr);
+        }
+    }
+    DMATxDescToSet = DMATxDesc;
+
+    if(ETH->DMASTS_B.TXBU == SET)
+    {
+        ETH->DMASTS = BIT2;
+        ETH->DMATXPD = 0;
+    }
+
+    return ETH_SUCCESS;
+}
+
+/*!
+ * @brief  Read the received frame.
+ *
+ * @param  none
+ *
+ * @retval Structure of type ETH_Frame_T
+ */
+ETH_Frame_T ETH_ReadReceivedFrame(void)
+{
+    uint32_t frameLength = 0;
+    ETH_Frame_T frame = {0,0,0};
+
+    frameLength = ((DMARxDescToGet->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4;
+    frame.length = frameLength;
+
+    frame.descriptor = DMARxFraminfos->FS_RxDesc;
+    frame.buffer = (DMARxFraminfos->FS_RxDesc)->Buffer1Addr;
+    DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+
+    return(frame);
+}
+
+/*!
+ * @brief  Read ETH DMA Tx Descriptor flag.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  flag: Specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_OWN   : Descriptor is owned by DMA engine
+ *           @arg ETH_DMATXDESC_INTC  : Interrupt on completion
+ *           @arg ETH_DMATXDESC_LS    : Last Segment
+ *           @arg ETH_DMATXDESC_FS    : First Segment
+ *           @arg ETH_DMATXDESC_DISC  : Disable CRC
+ *           @arg ETH_DMATXDESC_DISP  : Disable Pad
+ *           @arg ETH_DMATXDESC_TXTSEN: Transmit Time Stamp Enable
+ *           @arg ETH_DMATXDESC_TXENDR: Transmit End of Ring
+ *           @arg ETH_DMATXDESC_TXCH  : Second Address Chained
+ *           @arg ETH_DMATXDESC_TXTSS : Tx Time Stamp Status
+ *           @arg ETH_DMATXDESC_IHERR : IP Header Error
+ *           @arg ETH_DMATXDESC_ERRS  : Error summary
+ *           @arg ETH_DMATXDESC_JTO   : Jabber Timeout
+ *           @arg ETH_DMATXDESC_FF    : Frame Flushed: DMA/MTL flushed the frame due to SW flush
+ *           @arg ETH_DMATXDESC_IPERR : Payload Checksum Error
+ *           @arg ETH_DMATXDESC_LSC   : Loss of Carrier: carrier lost during transmission
+ *           @arg ETH_DMATXDESC_NC    : No Carrier: no carrier signal from the transceiver
+ *           @arg ETH_DMATXDESC_LC    : Late Collision: transmission aborted due to collision
+ *           @arg ETH_DMATXDESC_EC    : Excessive Collision: transmission aborted after 16 collisions
+ *           @arg ETH_DMATXDESC_VLANF : VLAN Frame
+ *           @arg ETH_DMATXDESC_CCNT  : Collision Count
+ *           @arg ETH_DMATXDESC_EDEF  : Excessive Deferral
+ *           @arg ETH_DMATXDESC_UFERR : Underflow Error: late data arrival from the memory
+ *           @arg ETH_DMATXDESC_DEF   : Deferred Bit
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMATxDescFlagStatus(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_FLAG_T flag)
+{
+    return (DMATxDesc->Status & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Returns ETH DMA Tx Descriptor collision count.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval The Transmit descriptor collision counter value.
+ */
+uint32_t ETH_ReadDMATxDescCollisionCount(ETH_DMADescConfig_T *DMATxDesc)
+{
+    return ((DMATxDesc->Status & ETH_DMATXDESC_CCNT) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT);
+}
+
+/*!
+ * @brief  Config the ETH DMA Tx Descriptor Own bit.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescOwnBit(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_OWN;
+}
+
+/*!
+ * @brief  Enable the ETH DMA Tx Descriptor Transmit interrupt.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_INTC;
+}
+
+/*!
+ * @brief  Disable the ETH DMA Tx Descriptor Transmit interrupt.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescTransmitInterrupt(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_INTC);
+}
+
+/*!
+ * @brief  Config Tx descriptor as last or first segment
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  frameSegment: Tx desc contain last or first segment.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_LASTSEGMENTS : Actual Tx desc contain last segment
+ *           @arg ETH_DMATXDESC_FIRSTSEGMENT : Actual Tx desc contain first segment
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescFrameSegment(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_SEGMENTS_T frameSegment)
+{
+    DMATxDesc->Status |= frameSegment;
+}
+/*!
+ * @brief  Config ETH DMA Tx Desc Checksum Insertion.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  checksum: specifies is the DMA Tx desc checksum insertion.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMATXDESC_CHECKSUMBYPASS              : Checksum bypass
+ *           @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER          : IPv4 header checksum
+ *           @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT   : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
+ *           @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL      : TCP/UDP/ICMP checksum fully in hardware including pseudo header
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescChecksumInsertion(ETH_DMADescConfig_T *DMATxDesc, ETH_DMATXDESC_CHECKSUMB_T checksum)
+{
+    DMATxDesc->Status |= checksum;
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc CRC.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DISC);
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc CRC.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescCRC(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_DISC;
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc second address chained.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_TXCH;
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc second address chained.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescSecondAddressChained(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &=(~(uint32_t)ETH_DMATXDESC_TXCH);
+}
+
+/*!
+ * @brief  Enable the DMA Tx Desc padding for frame shorter than 64 bytes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status &= (~(uint32_t)ETH_DMATXDESC_DISP);
+}
+
+/*!
+ * @brief  Disable the DMA Tx Desc padding for frame shorter than 64 bytes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMATxDescShortFramePadding(ETH_DMADescConfig_T *DMATxDesc)
+{
+    DMATxDesc->Status |= ETH_DMATXDESC_DISP;
+}
+
+/*!
+ * @brief  Config the ETH DMA Tx Desc buffer1 and buffer2 sizes.
+ *
+ * @param  DMATxDesc: pointer on a DMA Tx descriptor
+ *
+ * @param  bufferSize1: specifies the Tx desc buffer1 size.
+ *
+ * @param  bufferSize2: specifies the Tx desc buffer2 size.
+ *
+ * @retval None
+ */
+void ETH_ConfigDMATxDescBufferSize(ETH_DMADescConfig_T *DMATxDesc, uint32_t bufferSize1, uint32_t bufferSize2)
+{
+    DMATxDesc->ControlBufferSize |= (bufferSize1 | (bufferSize2 << ETH_DMATXDESC_BUFFER2_SIZESHIFT));
+}
+
+/*!
+ * @brief  Checks whether the specified ETHERNET Rx Desc flag is set or not.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMARXDESC_OWN    :    Descriptor is owned by DMA engine
+ *           @arg ETH_DMARXDESC_ADDRF  :    DA Filter Fail for the rx frame
+ *           @arg ETH_DMARXDESC_ERRS   :    Error summary
+ *           @arg ETH_DMARXDESC_DESERR :    Descriptor error: no more descriptors for receive frame
+ *           @arg ETH_DMARXDESC_SADDRF :    SA Filter Fail for the received frame
+ *           @arg ETH_DMARXDESC_LERR   :    Frame size not matching with length field
+ *           @arg ETH_DMARXDESC_OFERR  :    Overflow Error: Frame was damaged due to buffer overflow
+ *           @arg ETH_DMARXDESC_VLANF  :    VLAN Tag: received frame is a VLAN frame
+ *           @arg ETH_DMARXDESC_FDES   :    First descriptor of the frame
+ *           @arg ETH_DMARXDESC_LDES   :    Last descriptor of the frame
+ *           @arg ETH_DMARXDESC_IPV4HCE:    IPC Checksum Error/Giant Frame: Rx Ipv4 header checksum error
+ *           @arg ETH_DMARXDESC_LC     :    Late collision occurred during reception
+ *           @arg ETH_DMARXDESC_FT     :    Frame type - Ethernet, otherwise 802.3
+ *           @arg ETH_DMARXDESC_RXWDTTO:    Receive Watchdog Timeout: watchdog timer expired during reception
+ *           @arg ETH_DMARXDESC_RERR   :    Receive error: error reported by MII interface
+ *           @arg ETH_DMARXDESC_DERR   :    Dribble bit error: frame contains non int multiple of 8 bits
+ *           @arg ETH_DMARXDESC_CERR   :    CRC error
+ *           @arg ETH_DMARXDESC_MAMPCE :    Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMARxDescFlagStatus(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_FLAG_T flag)
+{
+    return (DMARxDesc->Status & flag) ? SET : RESET;
+}
+
+#if USE_ENHANCED_DMA_DESCRIPTORS
+/*!
+ * @brief  Checks whether the specified ETHERNET PTP Rx Desc extended flag is set or not.
+ *
+ * @param  DMAPTPRxDesc: pointer on a DMA PTP Rx descriptor
+ *
+ * @param  flag: specifies the extended flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMAPTPRXDESC_PTPV  :  PTP version
+ *           @arg ETH_DMAPTPRXDESC_PTPFT :  PTP frame type
+ *           @arg ETH_DMAPTPRXDESC_PTPMT :  PTP message type
+ *           @arg ETH_DMAPTPRXDESC_IPV6P :  IPv6 packet received
+ *           @arg ETH_DMAPTPRXDESC_IPV4P :  IPv4 packet received
+ *           @arg ETH_DMAPTPRXDESC_IPCBP :  IP checksum bypassed
+ *           @arg ETH_DMAPTPRXDESC_IPPERR:  IP payload error
+ *           @arg ETH_DMAPTPRXDESC_IPHERR:  IP header error
+ *           @arg ETH_DMAPTPRXDESC_IPPT  :  IP payload type
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAPTPRxDescExtendedFlagStatus(ETH_DMADescConfig_T *DMAPTPRxDesc, ETH_DMAPTPRXDESC_FLAG_T flag)
+{
+    return (DMAPTPRxDesc->Status & flag) ? SET : RESET;
+}
+#endif
+
+/*!
+ * @brief  Config the ETH DMA Rx Desc Own bit.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_ConfigDMARxDescOwnBit(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->Status |= ETH_DMARXDESC_OWN;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Rx descriptor frame length.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval The Rx descriptor received frame length.
+ */
+uint32_t ETH_ReadDMARxDescFrameLength(ETH_DMADescConfig_T *DMARxDesc)
+{
+    return ((DMARxDesc->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT);
+}
+
+/*!
+ * @brief  Enable the ETH DMA Rx Desc receive interrupt.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_EnableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARXDESC_DINTC);
+}
+
+/*!
+ * @brief  Disable the ETH DMA Rx Desc receive interrupt.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @retval None
+ */
+void ETH_DisableDMARxDescReceiveInterrupt(ETH_DMADescConfig_T *DMARxDesc)
+{
+    DMARxDesc->ControlBufferSize |= ETH_DMARXDESC_DINTC;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Rx Desc buffer size.
+ *
+ * @param  DMARxDesc: pointer on a DMA Rx descriptor
+ *
+ * @param  buffer: specifies the DMA Rx Desc buffer.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMARxDesc_Buffer1 : DMA Rx Desc Buffer1
+ *           @arg ETH_DMARxDesc_Buffer2 : DMA Rx Desc Buffer2
+ *
+ * @retval The Receive descriptor frame length.
+ */
+uint32_t ETH_ReadDMARxDescBufferSize(ETH_DMADescConfig_T *DMARxDesc, ETH_DMARXDESC_BUFFER_T buffer)
+{
+    if(buffer == ETH_DMARXDESC_BUFFER1)
+    {
+        return (DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RXBS1);
+    }
+    else
+    {
+        return ((DMARxDesc->ControlBufferSize & ETH_DMARXDESC_RXBS2) >> ETH_DMARXDESC_BUFFER2_SIZESHIFT);
+    }
+}
+
+/*!
+ * @brief  Read frame using DMA Receive interrupt.
+ *         it allows scanning of Rx descriptors to get the the receive frame
+ *
+ * @param  None
+ *
+ * @retval Structure of type ETH_Frame_T
+ */
+ETH_Frame_T ETH_ReadReceivedFrameInterrupt(void)
+{
+    __IO uint32_t count = 0;
+    ETH_Frame_T frame = {0,0,0};
+
+    while (((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) == (uint32_t)RESET)&& (count < ETH_RXBUFNB))
+    {
+        count ++;
+
+        if(((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET)&&
+        ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+        {
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+            DMARxFraminfos->segCount = 1;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+        }
+        else if (((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) == (uint32_t)RESET)&&
+                ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) == (uint32_t)RESET))
+        {
+            (DMARxFraminfos->segCount) ++;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+        }
+        else
+        {
+            DMARxFraminfos->LS_RxDesc = DMARxDescToGet;
+            (DMARxFraminfos->segCount)++;
+
+            if ((DMARxFraminfos->segCount)==1)
+            DMARxFraminfos->FS_RxDesc = DMARxDescToGet;
+
+            frame.length = ((DMARxDescToGet->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAMELENGTHSHIFT) - 4;
+
+            if(DMARxFraminfos->segCount >1)
+            {
+                frame.buffer = (DMARxFraminfos->FS_RxDesc)->Buffer1Addr;
+            }
+            else
+            {
+                frame.buffer = DMARxDescToGet->Buffer1Addr;
+            }
+
+            frame.descriptor = DMARxFraminfos->FS_RxDesc;
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+
+            return (frame);
+        }
+    }
+    return (frame);
+}
+
+/** DMA functions */
+
+/*!
+ * @brief  Read the ETH DMA flag.
+ *
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_FLAG_TST                  : Time-stamp trigger flag
+ *           @arg ETH_DMA_FLAG_PMT                  : PMT flag
+ *           @arg ETH_DMA_FLAG_MMC                  : MMC flag
+ *           @arg ETH_DMA_FLAG_DATATRANSFERERROR    : Error bits 0-data buffer, 1-desc. access
+ *           @arg ETH_DMA_FLAG_READWRITEERROR       : Error bits 0-write trnsf, 1-read transfr
+ *           @arg ETH_DMA_FLAG_ACCESSERROR          : Error bits 0-Rx DMA, 1-Tx DMA
+ *           @arg ETH_DMA_FLAG_NIS                  : Normal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_AIS                  : Abnormal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_ER                   : Early receive flag
+ *           @arg ETH_DMA_FLAG_FBE                  : Fatal bus error flag
+ *           @arg ETH_DMA_FLAG_ET                   : Early transmit flag
+ *           @arg ETH_DMA_FLAG_RWT                  : Receive watchdog timeout flag
+ *           @arg ETH_DMA_FLAG_RPS                  : Receive process stopped flag
+ *           @arg ETH_DMA_FLAG_RBU                  : Receive buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_RX                   : Receive flag
+ *           @arg ETH_DMA_FLAG_TU                   : Underflow flag
+ *           @arg ETH_DMA_FLAG_RO                   : Overflow flag
+ *           @arg ETH_DMA_FLAG_TJT                  : Transmit jabber timeout flag
+ *           @arg ETH_DMA_FLAG_TBU                  : Transmit buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_TPS                  : Transmit process stopped flag
+ *           @arg ETH_DMA_FLAG_TX                   : Transmit flag
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAFlagStatus(ETH_DMA_FLAG_T flag)
+{
+    return (ETH->DMASTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Clears the ETH DMA flag.
+ *
+ * @param  flag: specifies the flag to clear.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_FLAG_NIS : Normal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_AIS : Abnormal interrupt summary flag
+ *           @arg ETH_DMA_FLAG_ER  : Early receive flag
+ *           @arg ETH_DMA_FLAG_FBE : Fatal bus error flag
+ *           @arg ETH_DMA_FLAG_ET  : Early transmit flag
+ *           @arg ETH_DMA_FLAG_RWT : Receive watchdog timeout flag
+ *           @arg ETH_DMA_FLAG_RPS : Receive process stopped flag
+ *           @arg ETH_DMA_FLAG_RBU : Receive buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_RX  : Receive flag
+ *           @arg ETH_DMA_FLAG_TU  : Transmit Underflow flag
+ *           @arg ETH_DMA_FLAG_RO  : Receive Overflow flag
+ *           @arg ETH_DMA_FLAG_TJT : Transmit jabber timeout flag
+ *           @arg ETH_DMA_FLAG_TBU : Transmit buffer unavailable flag
+ *           @arg ETH_DMA_FLAG_TPS : Transmit process stopped flag
+ *           @arg ETH_DMA_FLAG_TX  : Transmit flag
+ *
+ * @retval None
+ */
+void ETH_ClearDMAFlag(uint32_t flag)
+{
+    ETH->DMASTS = flag;
+}
+
+/*!
+ * @brief  Read the ETH DMA interrupt flag.
+ *
+ * @param  flag: specifies the interrupt source to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_INT_TST : Time-stamp trigger interrupt
+ *           @arg ETH_DMA_INT_PMT : PMT interrupt
+ *           @arg ETH_DMA_INT_MMC : MMC interrupt
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAIntFlag(ETH_DMA_INT_T flag)
+{
+    return (ETH->DMASTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Clears the ETH DMA interrupt flag.
+ *
+ * @param  flag: specifies the interrupt flag to clear.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Transmit Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Receive Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_ClearDMAIntFlag(uint32_t flag)
+{
+    ETH->DMASTS = flag;
+}
+
+/*!
+ * @brief  Returns the ETH DMA Transmit Process State.
+ *
+ * @param  None
+
+ * @retval The new ETH DMA Transmit Process State:
+ *         This can be one of the following values:
+ *           - ETH_DMA_TRANSMITPROCESS_STOPPED   : Stopped - Reset or Stop Tx Command issued
+ *           - ETH_DMA_TRANSMITPROCESS_FETCHING  : Running - fetching the Tx descriptor
+ *           - ETH_DMA_TRANSMITPROCESS_WAITING   : Running - waiting for status
+ *           - ETH_DMA_TRANSMITPROCESS_READING   : Running - reading the data from host memory
+ *           - ETH_DMA_TRANSMITPROCESS_SUSPENDED : Suspended - Tx Descriptor unavailable
+ *           - ETH_DMA_TRANSMITPROCESS_CLOSING   : Running - closing Rx descriptor
+ */
+uint32_t ETH_ReadTransmitProcessState(void)
+{
+    return ((uint32_t)(ETH->DMASTS & BIT0) ? SET : RESET);
+}
+
+/*!
+ * @brief  Returns the ETH DMA Receive Process State.
+ *
+ * @param  None
+ *
+ * @retval The new ETH DMA Receive Process State:
+ *         This can be one of the following values:
+ *           - ETH_DMA_RECEIVEPROCESS_STOPPED   : Stopped - Reset or Stop Rx Command issued
+ *           - ETH_DMA_RECEIVEPROCESS_FETCHING  : Running - fetching the Rx descriptor
+ *           - ETH_DMA_RECEIVEPROCESS_WAITING   : Running - waiting for packet
+ *           - ETH_DMA_RECEIVEPROCESS_SUSPENDED : Suspended - Rx Descriptor unavailable
+ *           - ETH_DMA_RECEIVEPROCESS_CLOSING   : Running - closing descriptor
+ *           - ETH_DMA_RECEIVEPROCESS_QUEUING   : Running - queuing the receive frame into host memory
+ */
+uint32_t ETH_ReadReceiveProcessState(void)
+{
+    return ((uint32_t)(ETH->DMASTS & BIT6) ? SET : RESET);
+}
+
+/*!
+ * @brief  Flush the ETH transmit FIFO.
+ *
+ * @param  None
+ *
+ * @retval None
+  */
+void ETH_FlushTransmitFIFO(void)
+{
+    ETH->DMAOPMOD_B.FTXF = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH flush transmit FIFO status.
+ *
+ * @param  None
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadFlushTransmitFIFOStatus(void)
+{
+    return ETH->DMAOPMOD_B.FTXF;
+}
+
+/*!
+ * @brief  Enable the DMA transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableDMATransmission(void)
+{
+    ETH->DMAOPMOD_B.STTX = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the DMA transmission.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableDMATransmission(void)
+{
+    ETH->DMAOPMOD_B.STTX = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the DMA receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableDMAReceiver(void)
+{
+    ETH->DMAOPMOD_B.STRX = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the DMA receiver.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableDMAReceiver(void)
+{
+    ETH->DMAOPMOD_B.STRX = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the ETH DMA interrupts.
+ *
+ * @param  interrupt: specifies the ETH DMA interrupt sources.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_EnableDMAInterrupt(uint32_t interrupt)
+{
+    ETH->DMAINTEN |= interrupt;
+}
+
+/*!
+ * @brief  Disable the ETH DMA interrupts.
+ *
+ * @param  interrupt: specifies the ETH DMA interrupt sources.
+ *         This parameter can be any combination of the following values:
+ *           @arg ETH_DMA_INT_NIS : Normal interrupt summary
+ *           @arg ETH_DMA_INT_AIS : Abnormal interrupt summary
+ *           @arg ETH_DMA_INT_ER  : Early receive interrupt
+ *           @arg ETH_DMA_INT_FBE : Fatal bus error interrupt
+ *           @arg ETH_DMA_INT_ET  : Early transmit interrupt
+ *           @arg ETH_DMA_INT_RWT : Receive watchdog timeout interrupt
+ *           @arg ETH_DMA_INT_RPS : Receive process stopped interrupt
+ *           @arg ETH_DMA_INT_RBU : Receive buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_RX  : Receive interrupt
+ *           @arg ETH_DMA_INT_TU  : Underflow interrupt
+ *           @arg ETH_DMA_INT_RO  : Overflow interrupt
+ *           @arg ETH_DMA_INT_TJT : Transmit jabber timeout interrupt
+ *           @arg ETH_DMA_INT_TBU : Transmit buffer unavailable interrupt
+ *           @arg ETH_DMA_INT_TPS : Transmit process stopped interrupt
+ *           @arg ETH_DMA_INT_TX  : Transmit interrupt
+ *
+ * @retval None
+ */
+void ETH_DisableDMAInterrupt(uint32_t interrupt)
+{
+    ETH->DMAINTEN &= ((uint32_t)~interrupt);
+}
+
+/*!
+ * @brief  Read the ETH DMA overflow flag.
+ *
+ * @param  overflow: specifies the DMA overflow flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER        : Overflow for FIFO Overflows Counter
+ *           @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER   : Overflow for Buffer Unavailable Missed Frame Counter
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadDMAOverflowStatus(ETH_DMA_OVERFLOW_T overflow)
+{
+    return (ETH->DMAMFABOCNT & overflow) ? SET : RESET;
+}
+
+/*!
+ * @brief  Read the ETH DMA Rx Overflow Missed Frame Counter value.
+ *
+ * @param  None
+ *
+ * @retval The value of Rx overflow Missed Frame Counter.
+ */
+uint32_t ETH_ReadRxOverflowMissedFrameCounter(void)
+{
+    return (uint32_t)(ETH->DMAMFABOCNT_B.AMISFCNT);
+}
+
+/*!
+ * @brief  Read the ETH DMA Buffer Unavailable Missed Frame Counter value.
+ *
+ * @param  None
+ *
+ * @retval The value of Buffer unavailable Missed Frame Counter.
+ */
+uint32_t ETH_ReadBufferUnavailableMissedFrameCounter(void)
+{
+    return (uint32_t)(ETH->DMAMFABOCNT_B.MISFCNT);
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHTXD register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current Tx desc start address.
+ */
+uint32_t ETH_ReadCurrentTxDescStartAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHTXD));
+}
+
+/*!
+ * @brief  Read the ETHERNET DMA DMAHRXD register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current Rx desc start address.
+ */
+uint32_t ETH_ReadCurrentRxDescStartAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHRXD));
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHTXBADDR register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current transmit descriptor data buffer address.
+ */
+uint32_t ETH_ReadCurrentTxBufferAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHTXBADDR));
+}
+
+/*!
+ * @brief  Read the ETH DMA DMAHRXBADDR register value.
+ *
+ * @param  None
+ *
+ * @retval The value of the current receive descriptor data buffer address.
+ */
+uint32_t ETH_ReadCurrentRxBufferAddress(void)
+{
+    return ((uint32_t)(ETH->DMAHRXBADDR));
+}
+
+/*!
+ * @brief  Reset the DMA Transmission by writing to the DmaTxPollDemand register
+ *
+ * @param  None
+
+ * @retval None.
+ */
+void ETH_ResetDMATransmission(void)
+{
+    ETH->DMATXPD = 0;
+}
+
+/*!
+ * @brief  Reset the DMA Transmission by writing to the DmaRxPollDemand register
+ *
+ * @param  None
+ *
+ * @retval None.
+ */
+void ETH_ResetDMAReception(void)
+{
+    ETH->DMARXPD = 0;
+}
+
+/*!
+ * @brief  Config the DMA Receive status watchdog timer register value
+ *
+ * @param  value: watchdog timer register value
+ *
+ * @retval None
+ */
+void ETH_ConfigReceiveWatchdogTimer(uint8_t value)
+{
+    ETH->DMARXFLGWDT_B.RXWDTCNT = value;
+}
+
+/** Power Management(PMT) functions */
+
+/*!
+ * @brief  Reset Wakeup frame filter register pointer.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_ResetWakeUpFrameFilterRegisterPointer(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFRST = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Populates the remote wakeup frame registers.
+ *
+ * @param  buffer: WakeUp Frame Filter Register buffer data (8 words).
+ *
+ * @retval None
+ */
+void ETH_ConfigWakeUpFrameFilterRegister(uint32_t *buffer)
+{
+    uint32_t i = 0;
+    __IO uint32_t temp = 0;
+
+    for(i = 0; i < ETH_WAKEUP_REGISTER_LENGTH; i++)
+    {
+        ETH->WKUPFFL = buffer[i];
+
+        temp = ETH->WKUPFFL;
+        ETH_Delay(ETH_REG_WRITE_DELAY);
+        ETH->WKUPFFL = temp;
+    }
+}
+
+/*!
+ * @brief  Enable any unicast packet filtered by the MAC address
+ *         recognition to be a wake-up frame.
+ *
+ * @retval None
+ */
+void ETH_EnableGlobalUnicastWakeUp(void)
+{
+    ETH->PMTCTRLSTS_B.GUN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable any unicast packet filtered by the MAC address
+ *         recognition to be a wake-up frame.
+ *
+ * @retval None
+ */
+void ETH_DisableGlobalUnicastWakeUp(void)
+{
+    ETH->PMTCTRLSTS_B.GUN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Read the ETH PMT flag.
+ *
+ * @param  flag: specifies the flag to check.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
+ *           @arg ETH_PMT_FLAG_WUFR    : Wake-Up Frame Received
+ *           @arg ETH_PMT_FLAG_MPR     : Magic Packet Received
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadPMTFlagStatus(ETH_PMT_FLAG_T flag)
+{
+    return (ETH->PMTCTRLSTS & flag) ? SET : RESET;
+}
+
+/*!
+ * @brief  Enable the MAC Wake-Up Frame Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableWakeUpFrameDetection(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Wake-Up Frame Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableWakeUpFrameDetection(void)
+{
+    ETH->PMTCTRLSTS_B.WKUPFEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Magic Packet Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMagicPacketDetection(void)
+{
+    ETH->PMTCTRLSTS_B.MPEN = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Magic Packet Detection.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMagicPacketDetection(void)
+{
+    ETH->PMTCTRLSTS_B.MPEN = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Enable the MAC Power Down.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnablePowerDown(void)
+{
+    ETH->PMTCTRLSTS_B.PD = SET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/*!
+ * @brief  Disable the MAC Power Down.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisablePowerDown(void)
+{
+    ETH->PMTCTRLSTS_B.PD = RESET;
+    ETH_Delay(ETH_REG_WRITE_DELAY);
+}
+
+/** MMC functions */
+
+/**
+  * @brief  Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
+  * @param  None
+  * @retval None
+  */
+void ETH_PresetMMCCounterFull(void)
+{
+    ETH->CTRL_B.MCNTP = SET;
+    ETH->CTRL_B.MCNTVALP = SET;
+}
+
+/**
+  * @brief  Preset and Initialize the MMC counters to almost-hal value: 0x7FFF_FFF0 (half - 16)
+  * @param  None
+  * @retval None
+  */
+void ETH_PresetMMCCounterHalf(void)
+{
+    ETH->CTRL_B.MCNTP = SET;
+    ETH->CTRL_B.MCNTVALP = RESET;
+}
+
+/*!
+ * @brief  Enable the MMC Counter Freeze.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCCounterFreeze(void)
+{
+    ETH->CTRL_B.MCNTF = SET;
+}
+
+/*!
+ * @brief  Disable the MMC Counter Freeze.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCCounterFreeze(void)
+{
+    ETH->CTRL_B.MCNTF = RESET;
+}
+
+/*!
+ * @brief  Enable the MMC Reset On Read.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCResetOnRead(void)
+{
+    ETH->CTRL_B.RSTOR = SET;
+}
+
+/*!
+ * @brief  Disable the MMC Reset On Read.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCResetOnRead(void)
+{
+    ETH->CTRL_B.RSTOR = RESET;
+}
+
+/*!
+ * @brief  Enble the MMC Counter Stop Rollover.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_EnableMMCCounterRollover(void)
+{
+    ETH->CTRL_B.CNTSTOPRO = RESET;
+}
+
+/*!
+ * @brief  Disable the MMC Counter Stop Rollover.
+ *
+ * @param  None
+ *
+ * @retval None
+ */
+void ETH_DisableMMCCounterRollover(void)
+{
+    ETH->CTRL_B.CNTSTOPRO = SET;
+}
+
+/**
+  * @brief  Resets the MMC Counters.
+  * @param  None
+  * @retval None
+  */
+void ETH_ResetMMCCounters(void)
+{
+    ETH->CTRL_B.CNTRST = SET;
+}
+
+/*!
+ * @brief  Enable the ETH MMC interrupts.
+ *
+ * @param  interrupt: specifies the ETH MMC interrupt sources.
+ *         This parameter can be any combination of Tx interrupt or
+ *         any combination of Rx interrupt (but not both)of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval None
+ */
+void ETH_EnableMMCInterrupt(uint32_t interrupt)
+{
+   if((interrupt & 0x10000000) == SET)
+   {
+        ETH->RXINTMASK &= (~(uint32_t)interrupt);
+   }
+   else
+   {
+        ETH->TXINTMASK &= (~(uint32_t)interrupt);
+   }
+}
+
+/*!
+ * @brief  Disable the ETH MMC interrupts.
+ *
+ * @param  interrupt: specifies the ETH MMC interrupt sources.
+ *         This parameter can be any combination of Tx interrupt or
+ *         any combination of Rx interrupt (but not both)of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval None
+ */
+void ETH_DisableMMCInterrupt(uint32_t interrupt)
+{
+   if((interrupt & 0x10000000) == SET)
+   {
+        ETH->RXINTMASK |= interrupt;
+   }
+   else
+   {
+        ETH->TXINTMASK |= interrupt;
+   }
+}
+
+/*!
+ * @brief  Read the ETH MMC interrupt flag.
+ *
+ * @param  flag: specifies the ETH MMC interrupt.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MMC_INT_TGF   : When Tx good frame counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFMSC: When Tx good multi col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_TGFSC : When Tx good single col counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RGUF  : When Rx good unicast frames counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFAE  : When Rx alignment error counter reaches half the maximum value
+ *           @arg ETH_MMC_INT_RFCE  : When Rx crc error counter reaches half the maximum value
+ *
+ * @retval SET or RESET.
+ */
+uint8_t ETH_ReadMMCIntFlag(uint32_t flag)
+{
+    if((flag & 0x10000000) == SET)
+    {
+        return ((((ETH->RXINT & flag) != RESET)) && ((ETH->RXINTMASK & flag) == RESET));
+    }
+    else
+    {
+        return ((((ETH->TXINT & flag) != RESET)) && ((ETH->TXINTMASK & flag) == RESET));
+    }
+}
+
+/*!
+ * @brief  Read the ETH MMC register value.
+ *
+ * @param  MMCReg: specifies the ETH MMC register.
+ *         This parameter can be one of the following values:
+ *           @arg ETH_MMC_CTRL      : MMC CTRL register
+ *           @arg ETH_MMC_RXINT     : MMC RXINT register
+ *           @arg ETH_MMC_TXINT     : MMC TXINT register
+ *           @arg ETH_MMC_RXINTMASK : MMC RXINTMASK register
+ *           @arg ETH_MMC_TXINTMASK : MMC TXINTMASK register
+ *           @arg ETH_MMC_TXGFSCCNT : MMC TXGFSCCNT register
+ *           @arg ETH_MMC_TXGFMCCNT : MMC TXGFMCCNT register
+ *           @arg ETH_MMC_TXGFCNT   : MMC TXGFCNT register
+ *           @arg ETH_MMC_RXFCECNT  : MMC RXFCECNT register
+ *           @arg ETH_MMC_RXFAECNT  : MMC RXFAECNT register
+ *           @arg ETH_MMC_RXGUNCNT  : MMC RXGUNCNT register
+ *
+ * @retval Return ETH MMC Register value.
+ */
+uint32_t ETH_ReadMMCRegister(ETH_MMC_REG_T MMCReg)
+{
+    return (*(__IO uint32_t *)(ETH_MAC_BASE + MMCReg));
+}
+
+/**@} end of group ETH_Functions */
+/**@} end of group ETH_Driver */
+/**@} end of group APM32F4xx_ETHDriver */

+ 9 - 4
project_0/libraries/APM32F4xx_Library/SConscript

@@ -9,6 +9,7 @@ cwd = GetCurrentDir()
 src = Split("""
 Device/Geehy/APM32F4xx/Source/system_apm32f4xx.c
 APM32F4xx_StdPeriphDriver/src/apm32f4xx_gpio.c
+APM32F4xx_StdPeriphDriver/src/apm32f4xx_syscfg.c
 APM32F4xx_StdPeriphDriver/src/apm32f4xx_misc.c
 APM32F4xx_StdPeriphDriver/src/apm32f4xx_rcm.c
 APM32F4xx_StdPeriphDriver/src/apm32f4xx_usart.c
@@ -30,14 +31,18 @@ if GetDepend(['RT_USING_SPI']):
 
 if GetDepend(['RT_USING_HWTIMER']) or GetDepend(['RT_USING_PWM']):
     src += ['APM32F4xx_StdPeriphDriver/src/apm32f4xx_tmr.c']
-    
+
 if GetDepend(['RT_USING_WDT']):
     src += ['APM32F4xx_StdPeriphDriver/src/apm32f4xx_wwdt.c']
     src += ['APM32F4xx_StdPeriphDriver/src/apm32f4xx_iwdt.c']
-    
-path = [cwd + '/Device/Geehy/APM32F4xx/Include', 
+
+if GetDepend(['BSP_USING_ETH']):
+    src += ['APM32F4xx_ETH_Driver/src/apm32f4xx_eth.c']
+
+path = [cwd + '/Device/Geehy/APM32F4xx/Include',
     cwd + '/APM32F4xx_StdPeriphDriver/inc',
-    cwd + '/CMSIS/Include']
+    cwd + '/CMSIS/Include',
+    cwd + '/APM32F4xx_ETH_Driver/inc']
 
 CPPDEFINES = ['USE_STDPERIPH_DRIVER']
 group = DefineGroup('Libraries', src, depend = [''], CPPPATH = path, CPPDEFINES = CPPDEFINES)

+ 7 - 3
project_0/libraries/Drivers/SConscript

@@ -25,9 +25,10 @@ if GetDepend(['RT_USING_DAC']):
 
 if GetDepend('BSP_USING_ONCHIP_RTC'):
     src += ['drv_rtc.c']
-    
+
 if GetDepend(['RT_USING_I2C']):
-    src += ['drv_soft_i2c.c']
+    if GetDepend('BSP_USING_I2C1') or GetDepend('BSP_USING_I2C2') or GetDepend('BSP_USING_I2C3') or GetDepend('BSP_USING_I2C4'):
+        src += ['drv_soft_i2c.c']
 
 if GetDepend(['RT_USING_SPI']):
     src += ['drv_spi.c']
@@ -38,9 +39,12 @@ if GetDepend(['RT_USING_HWTIMER']):
 if GetDepend(['RT_USING_PWM']):
     src += ['drv_pwm.c']
 
-if GetDepend(['RT_USING_WDT']):
+if GetDepend(['BSP_USING_WDT']):
     src += ['drv_wdt.c']
 
+if GetDepend(['BSP_USING_ETH', 'RT_USING_LWIP']):
+    src += ['drv_eth.c']
+
 src += ['drv_common.c']
 
 path =  [cwd]

+ 105 - 36
project_0/libraries/Drivers/drv_adc.c

@@ -7,22 +7,22 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
 
 #if defined(BSP_USING_ADC1) || defined(BSP_USING_ADC2) || defined(BSP_USING_ADC3)
 
-//#define DRV_DEBUG
-#define LOG_TAG               "drv.adc"
+#define DBG_TAG               "drv.adc"
 #define DBG_LVL               DBG_INFO
 #include <rtdbg.h>
 
-#define DRV_ADC_CHANNEL_MAX_NUM  14
+#define DRV_ADC_CHANNEL_MAX_NUM  16
 #define DRV_ADC_TIME_OUT         0xFFF
 
-#define _ADC_GET_PORT(pin_num) ((GPIO_T *)(GPIOA_BASE + (0x400u * (((pin_num) >> 4) & 0xFu))))
-#define _ADC_GET_PIN(pin_num)  ((uint16_t)(1u << ((pin_num) & 0xFu)))
+#define APM32_ADC_GET_PORT(pin_num) ((GPIO_T *)(GPIOA_BASE + (0x400u * (((pin_num) >> 4) & 0xFu))))
+#define APM32_ADC_GET_PIN(pin_num)  ((uint16_t)(1u << ((pin_num) & 0xFu)))
 
 struct apm32_adc
 {
@@ -32,7 +32,8 @@ struct apm32_adc
     rt_base_t channel_pin[DRV_ADC_CHANNEL_MAX_NUM];
     struct rt_adc_device adc_dev;
 };
-#ifdef APM32F10X_HD
+
+#if defined(SOC_SERIES_APM32F1)
 static struct apm32_adc adc_config[] =
 {
 #ifdef BSP_USING_ADC1
@@ -52,7 +53,6 @@ static struct apm32_adc adc_config[] =
             GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7), GET_PIN(B, 0), GET_PIN(B, 1),
             GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3)
         },
-        RT_NULL
     },
 #endif
 #ifdef BSP_USING_ADC2
@@ -72,7 +72,6 @@ static struct apm32_adc adc_config[] =
             GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7), GET_PIN(B, 0), GET_PIN(B, 1),
             GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3)
         },
-        RT_NULL
     },
 #endif
 #ifdef BSP_USING_ADC3
@@ -91,11 +90,10 @@ static struct apm32_adc adc_config[] =
             GET_PIN(A, 0), GET_PIN(A, 1), GET_PIN(A, 2), GET_PIN(A, 3), GET_PIN(F, 6),
             GET_PIN(F, 7), GET_PIN(F, 8), GET_PIN(F, 9), GET_PIN(F, 10)
         },
-        RT_NULL
     },
 #endif
 };
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
 static struct apm32_adc adc_config[] =
 {
 #ifdef BSP_USING_ADC1
@@ -116,7 +114,6 @@ static struct apm32_adc adc_config[] =
             GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7), GET_PIN(B, 0), GET_PIN(B, 1),
             GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3)
         },
-        RT_NULL
     },
 #endif
 #ifdef BSP_USING_ADC2
@@ -137,7 +134,6 @@ static struct apm32_adc adc_config[] =
             GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7), GET_PIN(B, 0), GET_PIN(B, 1),
             GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3)
         },
-        RT_NULL
     },
 #endif
 #ifdef BSP_USING_ADC3
@@ -158,15 +154,39 @@ static struct apm32_adc adc_config[] =
             GET_PIN(F, 7), GET_PIN(F, 8), GET_PIN(F, 9), GET_PIN(F, 10), GET_PIN(F, 3),
             GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3)
         },
-        RT_NULL
+    },
+#endif
+};
+#elif defined(SOC_SERIES_APM32F0)
+static struct apm32_adc adc_config[] =
+{
+#ifdef BSP_USING_ADC1
+    {
+        "adc1",
+        ADC,
+        {
+            ADC_RESOLUTION_12B,
+            ADC_DATA_ALIGN_RIGHT,
+            ADC_SCAN_DIR_UPWARD,
+            ADC_CONVERSION_SINGLE,
+            ADC_EXT_TRIG_CONV_TRG0,
+            ADC_EXT_TRIG_EDGE_NONE
+        },
+        {
+            GET_PIN(A, 0), GET_PIN(A, 1), GET_PIN(A, 2), GET_PIN(A, 3), GET_PIN(A, 4),
+            GET_PIN(A, 5), GET_PIN(A, 6), GET_PIN(A, 7), GET_PIN(B, 0), GET_PIN(B, 1),
+            GET_PIN(C, 0), GET_PIN(C, 1), GET_PIN(C, 2), GET_PIN(C, 3), GET_PIN(C, 4),
+            GET_PIN(C, 5)
+        },
     },
 #endif
 };
 #endif
-static rt_err_t _adc_channel_check(struct rt_adc_device *device, rt_uint32_t channel)
+
+static rt_err_t apm32_adc_channel_check(struct rt_adc_device *device, rt_uint32_t channel)
 {
     struct apm32_adc *adc_cfg = ((struct apm32_adc *)device->parent.user_data);
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
     if (adc_cfg->adc == ADC3)
     {
         if (channel <= 8)
@@ -181,34 +201,42 @@ static rt_err_t _adc_channel_check(struct rt_adc_device *device, rt_uint32_t cha
             return RT_EOK;
         }
     }
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
     if (channel <= 13)
     {
         return RT_EOK;
     }
+#elif defined(SOC_SERIES_APM32F0)
+    if (channel <= 16)
+    {
+        return RT_EOK;
+    }
 #endif
     LOG_E("channel %d of %s is not supported.", channel, adc_cfg->name);
     return -RT_ERROR;
 }
 
-static rt_err_t _adc_gpio_init(struct rt_adc_device *device, rt_uint32_t channel)
+static rt_err_t apm32_adc_gpio_init(struct rt_adc_device *device, rt_uint32_t channel)
 {
     struct apm32_adc *adc_cfg = ((struct apm32_adc *)device->parent.user_data);
     GPIO_Config_T hw_gpio_config;
 
-    if (_adc_channel_check(device, channel) != RT_EOK)
+    if (apm32_adc_channel_check(device, channel) != RT_EOK)
     {
         return -RT_ERROR;
     }
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA << ((adc_cfg->channel_pin[channel] >> 4) & 0xFu));
     hw_gpio_config.mode = GPIO_MODE_ANALOG;
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA << ((adc_cfg->channel_pin[channel] >> 4) & 0xFu));
     hw_gpio_config.mode = GPIO_MODE_AN;
+#elif defined(SOC_SERIES_APM32F0)
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA << ((adc_cfg->channel_pin[channel] >> 4) & 0xFu));
+    hw_gpio_config.mode = GPIO_MODE_AN;
 #endif
-    hw_gpio_config.pin = _ADC_GET_PIN(adc_cfg->channel_pin[channel]);
-    GPIO_Config(_ADC_GET_PORT(adc_cfg->channel_pin[channel]), &hw_gpio_config);
+    hw_gpio_config.pin = APM32_ADC_GET_PIN(adc_cfg->channel_pin[channel]);
+    GPIO_Config(APM32_ADC_GET_PORT(adc_cfg->channel_pin[channel]), &hw_gpio_config);
 
     return RT_EOK;
 }
@@ -224,12 +252,28 @@ static rt_err_t _adc_gpio_init(struct rt_adc_device *device, rt_uint32_t channel
  *
  * @return   RT_EOK indicates successful enable or disable adc, other value indicates failed.
  */
-static rt_err_t _adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
+static rt_err_t apm32_adc_enabled(struct rt_adc_device *device, rt_uint32_t channel, rt_bool_t enabled)
 {
     struct apm32_adc *adc_cfg = ((struct apm32_adc *)device->parent.user_data);
 
     RT_ASSERT(device != RT_NULL);
 
+#if defined(SOC_SERIES_APM32F0)
+    if (enabled)
+    {
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
+        if (apm32_adc_gpio_init(device, channel) != RT_EOK)
+        {
+            return -RT_ERROR;
+        }
+        ADC_Config(&adc_cfg->adc_config);
+        ADC_Enable();
+    }
+    else
+    {
+        ADC_Disable();
+    }
+#else
     if (enabled)
     {
         if (adc_cfg->adc == ADC1)
@@ -244,7 +288,7 @@ static rt_err_t _adc_enabled(struct rt_adc_device *device, rt_uint32_t channel,
         {
             RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC3);
         }
-        if (_adc_gpio_init(device, channel) != RT_EOK)
+        if (apm32_adc_gpio_init(device, channel) != RT_EOK)
         {
             return -RT_ERROR;
         }
@@ -257,6 +301,7 @@ static rt_err_t _adc_enabled(struct rt_adc_device *device, rt_uint32_t channel,
     {
         ADC_Disable(adc_cfg->adc);
     }
+#endif
 
     return RT_EOK;
 }
@@ -272,19 +317,22 @@ static rt_err_t _adc_enabled(struct rt_adc_device *device, rt_uint32_t channel,
  *
  * @return   RT_EOK indicates successful get adc value, other value indicates failed.
  */
-static rt_err_t _adc_get_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
+static rt_err_t apm32_adc_get_value(struct rt_adc_device *device, rt_uint32_t channel, rt_uint32_t *value)
 {
+#if !defined(SOC_SERIES_APM32F0)
     struct apm32_adc *adc_cfg = ((struct apm32_adc *)device->parent.user_data);
+#endif
     volatile rt_uint32_t counter = 0;
 
     RT_ASSERT(device != RT_NULL);
     RT_ASSERT(value != RT_NULL);
 
-    if (_adc_channel_check(device, channel) != RT_EOK)
+    if (apm32_adc_channel_check(device, channel) != RT_EOK)
     {
         return -RT_ERROR;
     }
-#ifdef APM32F10X_HD
+    
+#if defined(SOC_SERIES_APM32F1)
     ADC_ConfigRegularChannel(adc_cfg->adc, channel, 1, ADC_SAMPLETIME_13CYCLES5);
 
     ADC_StartCalibration(adc_cfg->adc);
@@ -298,11 +346,19 @@ static rt_err_t _adc_get_value(struct rt_adc_device *device, rt_uint32_t channel
     }
 
     ADC_EnableSoftwareStartConv(adc_cfg->adc);
-#elif APM32F40X
+    
+    while (!ADC_ReadStatusFlag(adc_cfg->adc, ADC_FLAG_EOC))
+    {
+        if (++counter > DRV_ADC_TIME_OUT)
+        {
+            return RT_ETIMEOUT;
+        }
+    }
+    *value = ADC_ReadConversionValue(adc_cfg->adc);
+#elif defined(SOC_SERIES_APM32F4)
     ADC_ConfigRegularChannel(adc_cfg->adc, channel, 1, ADC_SAMPLETIME_15CYCLES);
     ADC_SoftwareStartConv(adc_cfg->adc);
-#endif
-    counter = 0;
+    
     while (!ADC_ReadStatusFlag(adc_cfg->adc, ADC_FLAG_EOC))
     {
         if (++counter > DRV_ADC_TIME_OUT)
@@ -310,16 +366,29 @@ static rt_err_t _adc_get_value(struct rt_adc_device *device, rt_uint32_t channel
             return RT_ETIMEOUT;
         }
     }
-
     *value = ADC_ReadConversionValue(adc_cfg->adc);
-
+#elif defined(SOC_SERIES_APM32F0)
+    ADC_ConfigChannel((uint16_t)(1u << ((channel) & 0xFu)), ADC_SAMPLE_TIME_239_5);
+    
+    ADC_StartConversion();
+    
+    while (!ADC_ReadStatusFlag(ADC_FLAG_CC))
+    {
+        if (++counter > DRV_ADC_TIME_OUT)
+        {
+            return RT_ETIMEOUT;
+        }
+    }
+    *value = ADC_ReadConversionValue();
+#endif
+    
     return RT_EOK;
 }
 
-static const struct rt_adc_ops _adc_ops =
+static const struct rt_adc_ops apm32_adc_ops =
 {
-    .enabled = _adc_enabled,
-    .convert = _adc_get_value,
+    .enabled = apm32_adc_enabled,
+    .convert = apm32_adc_get_value,
 };
 
 /**
@@ -336,7 +405,7 @@ static int rt_hw_adc_init(void)
     for (i = 0; i < obj_num; i++)
     {
         /* register ADC device */
-        if (rt_hw_adc_register(&adc_config[i].adc_dev, adc_config[i].name, &_adc_ops, adc_config))
+        if (rt_hw_adc_register(&adc_config[i].adc_dev, adc_config[i].name, &apm32_adc_ops, &adc_config[i]) == RT_EOK)
         {
             LOG_D("%s init success", adc_config[i].name);
         }

+ 1 - 1
project_0/libraries/Drivers/drv_common.c

@@ -93,7 +93,7 @@ void rt_hw_us_delay(rt_uint32_t us)
 /**
  * This function will config the board for initialization.
  */
-RT_WEAK void rt_hw_board_init()
+RT_WEAK void rt_hw_board_init(void)
 {
     /* Systick initialization */
     rt_hw_systick_init();

+ 47 - 15
project_0/libraries/Drivers/drv_dac.c

@@ -7,14 +7,15 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
 
 #if defined(BSP_USING_DAC1)
 
-#define LOG_TAG               "drv.dac"
-#define DBG_LVL               DBG_INFO
+#define DBG_TAG               "drv.dac"
+#define DBG_LVL               DBG_LOG
 #include <rtdbg.h>
 
 struct apm32_dac
@@ -27,8 +28,19 @@ struct apm32_dac
 
 static struct apm32_dac dac_config[] =
 {
-#if defined(BSP_USING_DAC1)
+
+#if defined (BSP_USING_DAC1)
     {
+#if defined (SOC_SERIES_APM32F0)
+        "dac1",
+        DAC,
+        {
+            DAC_TRIGGER_SOFTWARE,
+            DAC_OUTPUTBUFF_DISABLE,
+            DAC_WAVE_GENERATION_NONE,
+            DAC_TRIANGLEAMPLITUDE_4095,
+        },
+#elif  defined (SOC_SERIES_APM32F1) || defined (SOC_SERIES_APM32F4)
         "dac1",
         DAC,
         {
@@ -37,7 +49,7 @@ static struct apm32_dac dac_config[] =
             DAC_WAVE_GENERATION_NONE,
             DAC_TRIANGLE_AMPLITUDE_4095,
         },
-        RT_NULL
+#endif
     }
 #endif
 };
@@ -51,16 +63,19 @@ static struct apm32_dac dac_config[] =
  *
  * @return   RT_EOK indicates successful enable dac, other value indicates failed.
  */
-static rt_err_t _dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
+static rt_err_t apm32_dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
 {
     GPIO_Config_T GPIO_ConfigStruct;
     struct apm32_dac *cfg = (struct apm32_dac *)device->parent.user_data;
-#ifdef APM32F10X_HD
+#if defined (SOC_SERIES_APM32F1)
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
     GPIO_ConfigStruct.mode = GPIO_MODE_ANALOG;
-#elif APM32F40X
+#elif defined (SOC_SERIES_APM32F4)
     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
     GPIO_ConfigStruct.mode = GPIO_MODE_AN;
+#elif defined (SOC_SERIES_APM32F0)
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
+    GPIO_ConfigStruct.mode = GPIO_MODE_AN;
 #endif
     if (channel == 1)
     {
@@ -96,7 +111,7 @@ static rt_err_t _dac_enabled(struct rt_dac_device *device, rt_uint32_t channel)
  *
  * @return   RT_EOK indicates successful disable dac, other value indicates failed.
  */
-static rt_err_t _dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
+static rt_err_t apm32_dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
 {
     if (channel == 1)
     {
@@ -126,8 +141,25 @@ static rt_err_t _dac_disabled(struct rt_dac_device *device, rt_uint32_t channel)
  *
  * @return   RT_EOK indicates successful set dac value, other value indicates failed.
  */
-static rt_err_t _dac_set_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
+static rt_err_t apm32_dac_set_value(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value)
 {
+#if defined (SOC_SERIES_APM32F0)
+    if (channel == 1)
+    {
+        DAC_ConfigChannel1Data(DAC_ALIGN_12B_R, *value);
+        DAC_EnableSoftwareTrigger(DAC_CHANNEL_1);
+    }
+    else if (channel == 2)
+    {
+        DAC_ConfigChannel2Data(DAC_ALIGN_12B_R, *value);
+        DAC_EnableSoftwareTrigger(DAC_CHANNEL_2);
+    }
+    else
+    {
+        LOG_E("dac channel must be 1 or 2.");
+        return -RT_ERROR;
+    }
+#elif defined (SOC_SERIES_APM32F1) || defined (SOC_SERIES_APM32F4)
     if (channel == 1)
     {
         DAC_ConfigChannel1Data(DAC_ALIGN_12BIT_R, *value);
@@ -143,15 +175,15 @@ static rt_err_t _dac_set_value(struct rt_dac_device *device, rt_uint32_t channel
         LOG_E("dac channel must be 1 or 2.");
         return -RT_ERROR;
     }
-
+#endif
     return RT_EOK;
 }
 
-static const struct rt_dac_ops _dac_ops =
+static const struct rt_dac_ops apm32_dac_ops =
 {
-    .disabled = _dac_disabled,
-    .enabled  = _dac_enabled,
-    .convert  = _dac_set_value,
+    .disabled = apm32_dac_disabled,
+    .enabled  = apm32_dac_enabled,
+    .convert  = apm32_dac_set_value,
 };
 
 /**
@@ -170,7 +202,7 @@ static int rt_hw_dac_init(void)
     for (i = 0; i < obj_num; i++)
     {
         /* register dac device */
-        if (rt_hw_dac_register(&dac_config[i].dac_dev, dac_config[i].name, &_dac_ops, dac_config) == RT_EOK)
+        if (rt_hw_dac_register(&dac_config[i].dac_dev, dac_config[i].name, &apm32_dac_ops, dac_config) == RT_EOK)
         {
             LOG_D("%s init success", dac_config[i].name);
         }

+ 780 - 0
project_0/libraries/Drivers/drv_eth.c

@@ -0,0 +1,780 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-10-20     luobeihai    first version
+ * 2023-01-10     luobeihai    fix Eanble HARDWARE_CHECKSUM bug
+ */
+
+#include <board.h>
+
+#ifdef BSP_USING_ETH
+
+#include <netif/ethernetif.h>
+#include <netif/etharp.h>
+#include <lwip/icmp.h>
+#include "lwipopts.h"
+#include "lwip/ip.h"
+#include "drv_eth.h"
+
+/* debug option */
+//#define DRV_DEBUG
+//#define ETH_RX_DUMP
+//#define ETH_TX_DUMP
+#define LOG_TAG             "drv.emac"
+#include <drv_log.h>
+
+/* Global pointers on Tx and Rx descriptor used to transmit and receive descriptors */
+extern ETH_DMADescConfig_T  *DMATxDescToSet, *DMARxDescToGet;
+
+/* Ethernet Rx & Tx DMA Descriptors */
+extern ETH_DMADescConfig_T  DMARxDscrTab[ETH_RXBUFNB];
+extern ETH_DMADescConfig_T  DMATxDscrTab[ETH_TXBUFNB];
+
+/* Ethernet Receive and Transmit buffers */
+extern uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE];
+extern uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE];
+
+/* phy address */
+static uint8_t phy_addr = 0xFF;
+
+#define MAX_ADDR_LEN 6
+struct rt_apm32_eth
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    rt_timer_t poll_link_timer;
+
+    /* interface address info. */
+    rt_uint8_t  dev_addr[MAX_ADDR_LEN];         /* hw address   */
+
+    uint32_t    ETH_Speed; /*!< @ref ETH_Speed */
+    uint32_t    ETH_Mode;  /*!< @ref ETH_Duplex_Mode */
+
+    uint32_t ETH_HashTableHigh;
+    uint32_t ETH_HashTableLow;
+};
+static struct rt_apm32_eth apm32_eth_device;
+static struct rt_semaphore tx_wait;
+static rt_bool_t tx_is_waiting = RT_FALSE;
+
+#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
+#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
+static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
+{
+    unsigned char *buf = (unsigned char *)ptr;
+    int i, j;
+
+    for (i = 0; i < buflen; i += 16)
+    {
+        rt_kprintf("%08X: ", i);
+
+        for (j = 0; j < 16; j++)
+            if (i + j < buflen)
+                rt_kprintf("%02X ", buf[i + j]);
+            else
+                rt_kprintf("   ");
+        rt_kprintf(" ");
+
+        for (j = 0; j < 16; j++)
+            if (i + j < buflen)
+                rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
+        rt_kprintf("\n");
+    }
+}
+#endif
+
+/* interrupt service routine */
+void ETH_IRQHandler(void)
+{
+    rt_uint32_t status, ier;
+
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    /* ETH DMA status registor */
+    status = ETH->DMASTS;
+    /* ETH DMA interrupt resgitor */
+    ier = ETH->DMAINTEN;
+
+    if(status & ETH_DMA_INT_MMC)
+    {
+        ETH_ClearDMAIntFlag(ETH_DMA_INT_MMC);
+    }
+
+    if(status & ETH_DMA_INT_NIS)
+    {
+        rt_uint32_t nis_clear = ETH_DMA_INT_NIS;
+
+        /* [0]:Transmit Interrupt. */
+        if((status & ier) & ETH_DMA_INT_TX) /* packet transmission */
+        {
+            if (tx_is_waiting == RT_TRUE)
+            {
+                tx_is_waiting = RT_FALSE;
+                rt_sem_release(&tx_wait);
+            }
+
+            nis_clear |= ETH_DMA_INT_TX;
+        }
+
+        /* [2]:Transmit Buffer Unavailable. */
+
+        /* [6]:Receive Interrupt. */
+        if((status & ier) & ETH_DMA_INT_RX) /* packet reception */
+        {
+            /* a frame has been received */
+            eth_device_ready(&(apm32_eth_device.parent));
+
+            nis_clear |= ETH_DMA_INT_RX;
+        }
+
+        /* [14]:Early Receive Interrupt. */
+
+        ETH_ClearDMAIntFlag(nis_clear);
+    }
+
+    if(status & ETH_DMA_INT_AIS)
+    {
+        rt_uint32_t ais_clear = ETH_DMA_INT_AIS;
+
+        /* [1]:Transmit Process Stopped. */
+        if(status & ETH_DMA_INT_TPS)
+        {
+            ais_clear |= ETH_DMA_INT_TPS;
+        }
+
+        /* [3]:Transmit Jabber Timeout. */
+        if(status & ETH_DMA_INT_TJT)
+        {
+            ais_clear |= ETH_DMA_INT_TJT;
+        }
+
+        /* [4]: Receive FIFO Overflow. */
+        if(status & ETH_DMA_INT_RO)
+        {
+            ais_clear |= ETH_DMA_INT_RO;
+        }
+
+        /* [5]: Transmit Underflow. */
+        if(status & ETH_DMA_INT_TU)
+        {
+            ais_clear |= ETH_DMA_INT_TU;
+        }
+
+        /* [7]: Receive Buffer Unavailable. */
+        if(status & ETH_DMA_INT_RBU)
+        {
+            ais_clear |= ETH_DMA_INT_RBU;
+        }
+
+        /* [8]: Receive Process Stopped. */
+        if(status & ETH_DMA_INT_RPS)
+        {
+            ais_clear |= ETH_DMA_INT_RPS;
+        }
+
+        /* [9]: Receive Watchdog Timeout. */
+        if(status & ETH_DMA_INT_RWT)
+        {
+            ais_clear |= ETH_DMA_INT_RWT;
+        }
+
+        /* [10]: Early Transmit Interrupt. */
+
+        /* [13]: Fatal Bus Error. */
+        if(status & ETH_DMA_INT_FBE)
+        {
+            ais_clear |= ETH_DMA_INT_FBE;
+        }
+
+        ETH_ClearDMAIntFlag(ais_clear);
+    }
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
+#if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD)
+/* polynomial: 0x04C11DB7 */
+static uint32_t ethcrc(const uint8_t *data, size_t length)
+{
+    uint32_t crc = 0xffffffff;
+    size_t i;
+    int j;
+
+    for (i = 0; i < length; i++)
+    {
+        for (j = 0; j < 8; j++)
+        {
+            if (((crc >> 31) ^ (data[i] >> j)) & 0x01)
+            {
+                /* x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */
+                crc = (crc << 1) ^ 0x04C11DB7;
+            }
+            else
+            {
+                crc = crc << 1;
+            }
+        }
+    }
+
+    return ~crc;
+}
+
+#define HASH_BITS   6       /* #bits in hash */
+static void register_multicast_address(struct rt_apm32_eth *apm32_eth, const uint8_t *mac)
+{
+    uint32_t crc;
+    uint8_t hash;
+
+    /* calculate crc32 value of mac address */
+    crc = ethcrc(mac, 6);
+
+    /* only upper 6 bits (HASH_BITS) are used
+    * which point to specific bit in he hash registers
+    */
+    hash = (crc >> 26) & 0x3F;
+    //rt_kprintf("register_multicast_address crc: %08X hash: %02X\n", crc, hash);
+
+    if (hash > 31)
+    {
+        apm32_eth->ETH_HashTableHigh |= 1 << (hash - 32);
+        ETH->HTH = apm32_eth->ETH_HashTableHigh;
+    }
+    else
+    {
+        apm32_eth->ETH_HashTableLow |= 1 << hash;
+        ETH->HTL = apm32_eth->ETH_HashTableLow;
+    }
+}
+#endif /* (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) */
+
+#if LWIP_IPV4 && LWIP_IGMP
+static err_t igmp_mac_filter( struct netif *netif, const ip4_addr_t *ip4_addr, enum netif_mac_filter_action action )
+{
+    uint8_t mac[6];
+    const uint8_t *p = (const uint8_t *)ip4_addr;
+    struct rt_apm32_eth *apm32_eth = (struct rt_apm32_eth *)netif->state;
+
+    mac[0] = 0x01;
+    mac[1] = 0x00;
+    mac[2] = 0x5E;
+    mac[3] = *(p+1) & 0x7F;
+    mac[4] = *(p+2);
+    mac[5] = *(p+3);
+
+    register_multicast_address(apm32_eth, mac);
+
+    if(1)
+    {
+        rt_kprintf("%s %s %s ", __FUNCTION__, (action==NETIF_ADD_MAC_FILTER)?"add":"del", ip4addr_ntoa(ip4_addr));
+        rt_kprintf("%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+    }
+
+    return 0;
+}
+#endif /* LWIP_IPV4 && LWIP_IGMP */
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+static err_t mld_mac_filter( struct netif *netif, const ip6_addr_t *ip6_addr, enum netif_mac_filter_action action )
+{
+    uint8_t mac[6];
+    const uint8_t *p = (const uint8_t *)&ip6_addr->addr[3];
+    struct rt_apm32_eth *apm32_eth = (struct rt_apm32_eth *)netif->state;
+
+    mac[0] = 0x33;
+    mac[1] = 0x33;
+    mac[2] = *(p+0);
+    mac[3] = *(p+1);
+    mac[4] = *(p+2);
+    mac[5] = *(p+3);
+
+    register_multicast_address(apm32_eth, mac);
+
+    if(1)
+    {
+        rt_kprintf("%s %s %s ", __FUNCTION__, (action==NETIF_ADD_MAC_FILTER)?"add":"del", ip6addr_ntoa(ip6_addr));
+        rt_kprintf("%02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+    }
+
+    return 0;
+}
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+/* initialize the interface */
+static rt_err_t rt_apm32_eth_init(rt_device_t dev)
+{
+    struct rt_apm32_eth * apm32_eth = (struct rt_apm32_eth *)dev;
+    ETH_Config_T ETH_InitStructure;
+
+    /* Enable ETHERNET clock  */
+#if defined(SOC_SERIES_APM32F1)
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_ETH_MAC | RCM_AHB_PERIPH_ETH_MAC_TX |
+                             RCM_AHB_PERIPH_ETH_MAC_RX);
+#elif defined(SOC_SERIES_APM32F4)
+    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_ETH_MAC | RCM_AHB1_PERIPH_ETH_MAC_Tx |
+                              RCM_AHB1_PERIPH_ETH_MAC_Rx);
+#endif
+    
+    /* Reset ETHERNET on AHB Bus */
+    ETH_Reset();
+
+    /* Software reset */
+    ETH_SoftwareReset();
+
+    /* Wait for software reset */
+    while(ETH_ReadSoftwareReset() == SET);
+
+    /* ETHERNET Configuration --------------------------------------------------*/
+    /* Call ETH_StructInit if you don't like to configure all ETH_InitStructure parameter */
+    ETH_ConfigStructInit(&ETH_InitStructure);
+
+    /* Fill ETH_InitStructure parametrs */
+    /*------------------------   MAC   -----------------------------------*/
+    ETH_InitStructure.autoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+    ETH_InitStructure.speed = (ETH_SPEED_T)apm32_eth->ETH_Speed;
+    ETH_InitStructure.mode  = (ETH_MODE_T)apm32_eth->ETH_Mode;
+
+    ETH_InitStructure.loopbackMode = ETH_LOOPBACKMODE_DISABLE;
+    ETH_InitStructure.retryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
+    ETH_InitStructure.automaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
+    ETH_InitStructure.receiveAll = ETH_RECEIVEAll_DISABLE;
+    ETH_InitStructure.broadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
+    ETH_InitStructure.promiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
+    ETH_InitStructure.multicastFramesFilter = ETH_MULTICASTFRAMESFILTER_HASHTABLE;
+    ETH_InitStructure.hashTableHigh = apm32_eth->ETH_HashTableHigh;
+    ETH_InitStructure.hashTableLow  = apm32_eth->ETH_HashTableLow;
+    ETH_InitStructure.unicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
+#ifdef RT_LWIP_USING_HW_CHECKSUM
+    ETH_InitStructure.checksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
+#endif
+
+    /*------------------------   DMA   -----------------------------------*/
+
+    /* When we use the Checksum offload feature, we need to enable the Store and Forward mode:
+    the store and forward guarantee that a whole frame is stored in the FIFO, so the MAC can insert/verify the checksum,
+    if the checksum is OK the DMA can handle the frame otherwise the frame is dropped */
+    ETH_InitStructure.dropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
+    ETH_InitStructure.receiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
+    ETH_InitStructure.flushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_DISABLE;
+    ETH_InitStructure.transmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
+
+    ETH_InitStructure.forwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
+    ETH_InitStructure.forwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
+    ETH_InitStructure.secondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
+    ETH_InitStructure.addressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
+    ETH_InitStructure.fixedBurst = ETH_FIXEDBURST_ENABLE;
+    ETH_InitStructure.rxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
+    ETH_InitStructure.txDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
+    ETH_InitStructure.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1;
+
+    /* configure Ethernet */
+    ETH_Config(&ETH_InitStructure, phy_addr);
+
+    /* Enable DMA Receive interrupt (need to enable in this case Normal interrupt) */
+    ETH_EnableDMAInterrupt(ETH_DMA_INT_NIS | ETH_DMA_INT_RX | ETH_DMA_INT_TX);
+    NVIC_EnableIRQ(ETH_IRQn);
+
+    /* Initialize Tx Descriptors list: Chain Mode */
+    ETH_ConfigDMATxDescChain(DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);
+    /* Initialize Rx Descriptors list: Chain Mode  */
+    ETH_ConfigDMARxDescChain(DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);
+
+    /* MAC address configuration */
+    ETH_ConfigMACAddress(ETH_MAC_ADDRESS0, (u8*)&apm32_eth_device.dev_addr[0]);
+
+    /* Enable MAC and DMA transmission and reception */
+    ETH_Start();
+
+#if LWIP_IPV4 && LWIP_IGMP
+    netif_set_igmp_mac_filter(apm32_eth->parent.netif, igmp_mac_filter);
+#endif /* LWIP_IPV4 && LWIP_IGMP */
+
+#if LWIP_IPV6 && LWIP_IPV6_MLD
+    netif_set_mld_mac_filter(apm32_eth->parent.netif, mld_mac_filter);
+#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_apm32_eth_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_apm32_eth_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t rt_apm32_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_size_t rt_apm32_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+    rt_set_errno(-RT_ENOSYS);
+    return 0;
+}
+
+static rt_err_t rt_apm32_eth_control(rt_device_t dev, int cmd, void *args)
+{
+    switch(cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if(args) rt_memcpy(args, apm32_eth_device.dev_addr, 6);
+        else return -RT_ERROR;
+        break;
+
+    default :
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+rt_err_t rt_apm32_eth_tx( rt_device_t dev, struct pbuf* p)
+{
+    struct pbuf* q;
+    rt_uint32_t offset;
+
+    /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
+    while ((DMATxDescToSet->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET)
+    {
+        rt_err_t result;
+        rt_uint32_t level;
+
+        level = rt_hw_interrupt_disable();
+        tx_is_waiting = RT_TRUE;
+        rt_hw_interrupt_enable(level);
+
+        /* it's own bit set, wait it */
+        result = rt_sem_take(&tx_wait, RT_WAITING_FOREVER);
+        if (result == RT_EOK) break;
+        if (result == -RT_ERROR) return -RT_ERROR;
+    }
+
+    offset = 0;
+    for (q = p; q != NULL; q = q->next)
+    {
+        uint8_t *to;
+
+        /* Copy the frame to be sent into memory pointed by the current ETHERNET DMA Tx descriptor */
+        to = (uint8_t*)((DMATxDescToSet->Buffer1Addr) + offset);
+        SMEMCPY(to, q->payload, q->len);
+        offset += q->len;
+    }
+#ifdef ETH_TX_DUMP
+    rt_kprintf("tx_dump, len:%d\r\n", p->tot_len);
+    dump_hex((rt_uint8_t*)(DMATxDescToSet->Buffer1Addr), p->tot_len);
+#endif
+
+    /* Setting the Frame Length: bits[12:0] */
+    DMATxDescToSet->ControlBufferSize = (p->tot_len & ETH_DMATXDESC_TXBS1);
+    /* Setting the last segment and first segment bits (in this case a frame is transmitted in one descriptor) */
+    DMATxDescToSet->Status |= ETH_DMATXDESC_LS | ETH_DMATXDESC_FS;
+    /* Enable TX Completion Interrupt */
+    DMATxDescToSet->Status |= ETH_DMATXDESC_INTC;
+#ifdef RT_LWIP_USING_HW_CHECKSUM
+    DMATxDescToSet->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
+    /* clean ICMP checksum APM32F need */
+    {
+        struct eth_hdr *ethhdr = (struct eth_hdr *)(DMATxDescToSet->Buffer1Addr);
+        /* is IP ? */
+        if( ethhdr->type == htons(ETHTYPE_IP) )
+        {
+            struct ip_hdr *iphdr = (struct ip_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR);
+            /* is ICMP ? */
+            if( IPH_PROTO(iphdr) == IP_PROTO_ICMP )
+            {
+                struct icmp_echo_hdr *iecho = (struct icmp_echo_hdr *)(DMATxDescToSet->Buffer1Addr + SIZEOF_ETH_HDR + sizeof(struct ip_hdr) );
+                iecho->chksum = 0;
+            }
+        }
+    }
+#endif
+    /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
+    DMATxDescToSet->Status |= ETH_DMATXDESC_OWN;
+    /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
+    if ((ETH->DMASTS & BIT2) != (u32)RESET)
+    {
+        /** Clear TBUS ETHERNET DMA flag */
+        ETH->DMASTS = BIT2;
+        /** Resume DMA transmission*/
+        ETH->DMATXPD = 0;
+    }
+
+    /* Update the ETHERNET DMA global Tx descriptor with next Tx decriptor */
+    /* Chained Mode */
+    /* Selects the next DMA Tx descriptor list for next buffer to send */
+    DMATxDescToSet = (ETH_DMADescConfig_T*) (DMATxDescToSet->Buffer2NextDescAddr);
+
+    /* Return SUCCESS */
+    return RT_EOK;
+}
+
+/* reception packet. */
+struct pbuf *rt_apm32_eth_rx(rt_device_t dev)
+{
+    struct pbuf* p;
+    rt_uint32_t offset = 0, framelength = 0;
+
+    /* init p pointer */
+    p = RT_NULL;
+
+    /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
+    if(((DMARxDescToGet->Status & ETH_DMARXDESC_OWN) != (uint32_t)RESET))
+        return p;
+
+    if (((DMARxDescToGet->Status & ETH_DMARXDESC_ERRS) == (uint32_t)RESET) &&
+            ((DMARxDescToGet->Status & ETH_DMARXDESC_LDES) != (uint32_t)RESET) &&
+            ((DMARxDescToGet->Status & ETH_DMARXDESC_FDES) != (uint32_t)RESET))
+    {
+        /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
+        framelength = ((DMARxDescToGet->Status & ETH_DMARXDESC_FL) >> ETH_DMARXDESC_FRAME_LENGTHSHIFT) - 4;
+
+        /* allocate buffer */
+        p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM);
+        if (p != RT_NULL)
+        {
+            struct pbuf* q;
+
+            for (q = p; q != RT_NULL; q= q->next)
+            {
+                /* Copy the received frame into buffer from memory pointed by the current ETHERNET DMA Rx descriptor */
+                SMEMCPY(q->payload, (uint8_t *)((DMARxDescToGet->Buffer1Addr) + offset), q->len);
+                offset += q->len;
+            }
+#ifdef ETH_RX_DUMP
+            rt_kprintf("rx_dump, len:%d\r\n", p->tot_len);
+            dump_hex((rt_uint8_t*)(DMARxDescToGet->Buffer1Addr), p->tot_len);
+#endif
+        }
+    }
+
+    /* Set Own bit of the Rx descriptor Status: gives the buffer back to ETHERNET DMA */
+    DMARxDescToGet->Status = ETH_DMARXDESC_OWN;
+
+    /* When Rx Buffer unavailable flag is set: clear it and resume reception */
+    if ((ETH->DMASTS & BIT7) != (u32)RESET)
+    {
+        /* Clear RBUS ETHERNET DMA flag */
+        ETH->DMASTS = BIT7;
+        /* Resume DMA reception */
+        ETH->DMARXPD = 0;
+    }
+
+    /* Update the ETHERNET DMA global Rx descriptor with next Rx decriptor */
+    /* Chained Mode */
+    if((DMARxDescToGet->ControlBufferSize & ETH_DMARXDESC_RXCH) != (uint32_t)RESET)
+    {
+        /* Selects the next DMA Rx descriptor list for next buffer to read */
+        DMARxDescToGet = (ETH_DMADescConfig_T*) (DMARxDescToGet->Buffer2NextDescAddr);
+    }
+    else /* Ring Mode */
+    {
+        if((DMARxDescToGet->ControlBufferSize & ETH_DMARXDESC_RXER) != (uint32_t)RESET)
+        {
+            /* Selects the first DMA Rx descriptor for next buffer to read: last Rx descriptor was used */
+            DMARxDescToGet = (ETH_DMADescConfig_T*) (ETH->DMARXDLADDR);
+        }
+        else
+        {
+            /* Selects the next DMA Rx descriptor list for next buffer to read */
+            DMARxDescToGet = (ETH_DMADescConfig_T*) ((uint32_t)DMARxDescToGet + 0x10 + ((ETH->DMABMOD & 0x0000007C) >> 2));
+        }
+    }
+
+    return p;
+}
+
+enum {
+    PHY_LINK        = (1 << 0),
+    PHY_100M        = (1 << 1),
+    PHY_FULL_DUPLEX = (1 << 2),
+};
+
+static void phy_linkchange(void)
+{
+    uint8_t phy_speed_new = 0;
+    static uint8_t phy_speed = 0;
+    uint16_t status  = ETH_ReadPHYRegister(phy_addr, PHY_BSR);
+
+    LOG_D("phy basic status reg is 0x%X", status);
+
+    if(status & (PHY_AUTONEGO_COMPLETE | PHY_LINKED_STATUS))
+    {
+        uint16_t SR;
+
+        phy_speed_new |= PHY_LINK;
+
+        SR = ETH_ReadPHYRegister(phy_addr, PHY_Status_REG);
+        LOG_D("phy control status reg is 0x%X", SR);
+
+        if (PHY_Status_SPEED_100M(SR))
+        {
+            phy_speed_new |= PHY_100M;
+        }
+
+        if (PHY_Status_FULL_DUPLEX(SR))
+        {
+            phy_speed_new |= PHY_FULL_DUPLEX;
+        }
+    }
+
+    /* linkchange */
+    if(phy_speed_new != phy_speed)
+    {
+        if(phy_speed_new & PHY_LINK)
+        {
+            LOG_D("link up ");
+
+            if(phy_speed_new & PHY_100M)
+            {
+                LOG_D("100Mbps");
+                apm32_eth_device.ETH_Speed = ETH_SPEED_100M;
+            }
+            else
+            {
+                apm32_eth_device.ETH_Speed = ETH_SPEED_10M;
+                LOG_D("10Mbps");
+            }
+
+            if(phy_speed_new & PHY_FULL_DUPLEX)
+            {
+                LOG_D("full-duplex\r\n");
+                apm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX;
+            }
+            else
+            {
+                LOG_D("half-duplex\r\n");
+                apm32_eth_device.ETH_Mode = ETH_MODE_HALFDUPLEX;
+            }
+            rt_apm32_eth_init((rt_device_t)&apm32_eth_device);
+
+            /* send link up. */
+            eth_device_linkchange(&apm32_eth_device.parent, RT_TRUE);
+        } /* link up. */
+        else
+        {
+            LOG_I("link down\r\n");
+            /* send link down. */
+            eth_device_linkchange(&apm32_eth_device.parent, RT_FALSE);
+        } /* link down. */
+
+        phy_speed = phy_speed_new;
+    } /* linkchange */
+}
+
+static void phy_monitor_thread_entry(void *parameter)
+{
+    uint8_t detected_count = 0;
+
+    while(phy_addr == 0xFF)
+    {
+        /* phy search */
+        rt_uint32_t i, temp;
+        for (i = 0; i <= 0x1F; i++)
+        {
+            temp = ETH_ReadPHYRegister(i, PHY_ID1_REG);
+
+            if (temp != 0xFFFF && temp != 0x00)
+            {
+                phy_addr = i;
+                break;
+            }
+        }
+
+        detected_count++;
+        rt_thread_mdelay(1000);
+
+        if (detected_count > 10)
+        {
+            LOG_E("No PHY device was detected, please check hardware!");
+        }
+    }
+
+    LOG_D("Found a phy, address:0x%02X", phy_addr);
+
+    /* RESET PHY */
+    LOG_D("RESET PHY!\r\n");
+    ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_RESET);
+    rt_thread_delay(RT_TICK_PER_SECOND * 2);
+    ETH_WritePHYRegister(phy_addr, PHY_BCR, PHY_AUTONEGOTIATION);
+
+    phy_linkchange();
+
+    apm32_eth_device.poll_link_timer = rt_timer_create("phylnk", (void (*)(void*))phy_linkchange,
+                                        NULL, RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
+    if (!apm32_eth_device.poll_link_timer || rt_timer_start(apm32_eth_device.poll_link_timer) != RT_EOK)
+    {
+        LOG_E("Start link change detection timer failed");
+    }
+}
+
+static int rt_hw_apm32_eth_init(void)
+{
+    /* reset phy */
+    extern void phy_reset(void);
+    phy_reset();
+
+    /* apm32 eth gpio init */
+    extern void apm32_msp_eth_init(void *instance);
+    apm32_msp_eth_init(RT_NULL);
+
+    apm32_eth_device.ETH_Speed = ETH_SPEED_100M;
+    apm32_eth_device.ETH_Mode  = ETH_MODE_FULLDUPLEX;
+
+    /* set mac address. */
+    apm32_eth_device.dev_addr[0] = 0x00;
+    apm32_eth_device.dev_addr[1] = 0x00;
+    apm32_eth_device.dev_addr[2] = 0x00;
+    apm32_eth_device.dev_addr[3] = 0x00;
+    apm32_eth_device.dev_addr[4] = 0x00;
+    apm32_eth_device.dev_addr[5] = 0x08;
+
+    apm32_eth_device.parent.parent.init       = rt_apm32_eth_init;
+    apm32_eth_device.parent.parent.open       = rt_apm32_eth_open;
+    apm32_eth_device.parent.parent.close      = rt_apm32_eth_close;
+    apm32_eth_device.parent.parent.read       = rt_apm32_eth_read;
+    apm32_eth_device.parent.parent.write      = rt_apm32_eth_write;
+    apm32_eth_device.parent.parent.control    = rt_apm32_eth_control;
+    apm32_eth_device.parent.parent.user_data  = RT_NULL;
+
+    apm32_eth_device.parent.eth_rx     = rt_apm32_eth_rx;
+    apm32_eth_device.parent.eth_tx     = rt_apm32_eth_tx;
+
+    /* init tx semaphore */
+    rt_sem_init(&tx_wait, "tx_wait", 0, RT_IPC_FLAG_FIFO);
+
+    /* register eth device */
+    eth_device_init(&(apm32_eth_device.parent), "e0");
+
+    /* start phy monitor */
+    {
+        rt_thread_t tid;
+        tid = rt_thread_create("phy",
+                               phy_monitor_thread_entry,
+                               RT_NULL,
+                               512,
+                               RT_THREAD_PRIORITY_MAX - 2,
+                               2);
+        if (tid != RT_NULL)
+            rt_thread_startup(tid);
+    }
+
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_apm32_eth_init);
+
+#endif /* BSP_USING_ETH */

+ 92 - 0
project_0/libraries/Drivers/drv_eth.h

@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-10-20     luobeihai    first version
+ */
+
+#ifndef __DRV_ETH_H__
+#define __DRV_ETH_H__
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include <board.h>
+
+/* The PHY ID one register */
+#define PHY_ID1_REG                 0x02U
+
+
+#ifdef PHY_USING_LAN8720A
+/*  The PHY interrupt source flag register. */
+#define PHY_INTERRUPT_FLAG_REG      0x1DU
+/*  The PHY interrupt mask register. */
+#define PHY_INTERRUPT_MASK_REG      0x1EU
+#define PHY_LINK_DOWN_MASK          (1<<4)
+#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
+
+/*  The PHY status register. */
+#define PHY_Status_REG              0x1FU
+#define PHY_10M_MASK                (1<<2)
+#define PHY_100M_MASK               (1<<3)
+#define PHY_FULL_DUPLEX_MASK        (1<<4)
+#define PHY_Status_SPEED_10M(sr)    ((sr) & PHY_10M_MASK)
+#define PHY_Status_SPEED_100M(sr)   ((sr) & PHY_100M_MASK)
+#define PHY_Status_FULL_DUPLEX(sr)  ((sr) & PHY_FULL_DUPLEX_MASK)
+
+#elif defined(PHY_USING_DM9161CEP)
+#define PHY_Status_REG              0x11U
+#define PHY_10M_MASK                ((1<<12) || (1<<13))
+#define PHY_100M_MASK               ((1<<14) || (1<<15))
+#define PHY_FULL_DUPLEX_MASK        ((1<<15) || (1<<13))
+#define PHY_Status_SPEED_10M(sr)    ((sr) & PHY_10M_MASK)
+#define PHY_Status_SPEED_100M(sr)   ((sr) & PHY_100M_MASK)
+#define PHY_Status_FULL_DUPLEX(sr)  ((sr) & PHY_FULL_DUPLEX_MASK)
+/*  The PHY interrupt source flag register. */
+#define PHY_INTERRUPT_FLAG_REG      0x15U
+/*  The PHY interrupt mask register. */
+#define PHY_INTERRUPT_MASK_REG      0x15U
+#define PHY_LINK_CHANGE_FLAG        (1<<2)
+#define PHY_LINK_CHANGE_MASK        (1<<9)
+#define PHY_INT_MASK                0
+
+#elif defined(PHY_USING_DP83848C)
+#define PHY_Status_REG              0x10U
+#define PHY_10M_MASK                (1<<1)
+#define PHY_FULL_DUPLEX_MASK        (1<<2)
+#define PHY_Status_SPEED_10M(sr)    ((sr) & PHY_10M_MASK)
+#define PHY_Status_SPEED_100M(sr)   (!PHY_Status_SPEED_10M(sr))
+#define PHY_Status_FULL_DUPLEX(sr)  ((sr) & PHY_FULL_DUPLEX_MASK)
+/*  The PHY interrupt source flag register. */
+#define PHY_INTERRUPT_FLAG_REG      0x12U
+#define PHY_LINK_CHANGE_FLAG        (1<<13)
+/*  The PHY interrupt control register. */
+#define PHY_INTERRUPT_CTRL_REG      0x11U
+#define PHY_INTERRUPT_EN            ((1<<0)|(1<<1))
+/*  The PHY interrupt mask register. */
+#define PHY_INTERRUPT_MASK_REG      0x12U
+#define PHY_INT_MASK                (1<<5)
+#endif
+
+#ifdef PHY_USING_LAN8742A
+/*  The PHY interrupt source flag register. */
+#define PHY_INTERRUPT_FLAG_REG      0x1DU
+/*  The PHY interrupt mask register. */
+#define PHY_INTERRUPT_MASK_REG      0x1EU
+#define PHY_LINK_DOWN_MASK          (1<<4)
+#define PHY_AUTO_NEGO_COMPLETE_MASK (1<<6)
+
+/*  The PHY status register. */
+#define PHY_Status_REG              0x1FU
+#define PHY_10M_MASK                (1<<2)
+#define PHY_100M_MASK               (1<<3)
+#define PHY_FULL_DUPLEX_MASK        (1<<4)
+#define PHY_Status_SPEED_10M(sr)    ((sr) & PHY_10M_MASK)
+#define PHY_Status_SPEED_100M(sr)   ((sr) & PHY_100M_MASK)
+#define PHY_Status_FULL_DUPLEX(sr)  ((sr) & PHY_FULL_DUPLEX_MASK)
+#endif /* PHY_USING_LAN8742A */
+
+#endif /* __DRV_ETH_H__ */

+ 238 - 111
project_0/libraries/Drivers/drv_gpio.c

@@ -7,6 +7,7 @@
  * Date           Author            Notes
  * 2020-08-20     Abbcc             first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
@@ -19,7 +20,6 @@
 #define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
 
 #define PIN_APMPORT(pin) ((GPIO_T *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
-
 #define PIN_APMPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
 
 #if defined(GPIOZ)
@@ -55,6 +55,24 @@
 
 static const struct pin_irq_map pin_irq_map[] =
 {
+#if defined(SOC_SERIES_APM32F0)
+    {GPIO_PIN_0, EINT0_1_IRQn},
+    {GPIO_PIN_1, EINT0_1_IRQn},
+    {GPIO_PIN_2, EINT2_3_IRQn},
+    {GPIO_PIN_3, EINT2_3_IRQn},
+    {GPIO_PIN_4, EINT4_15_IRQn},
+    {GPIO_PIN_5, EINT4_15_IRQn},
+    {GPIO_PIN_6, EINT4_15_IRQn},
+    {GPIO_PIN_7, EINT4_15_IRQn},
+    {GPIO_PIN_8, EINT4_15_IRQn},
+    {GPIO_PIN_9, EINT4_15_IRQn},
+    {GPIO_PIN_10, EINT4_15_IRQn},
+    {GPIO_PIN_11, EINT4_15_IRQn},
+    {GPIO_PIN_12, EINT4_15_IRQn},
+    {GPIO_PIN_13, EINT4_15_IRQn},
+    {GPIO_PIN_14, EINT4_15_IRQn},
+    {GPIO_PIN_15, EINT4_15_IRQn},   
+#else
     {GPIO_PIN_0, EINT0_IRQn},
     {GPIO_PIN_1, EINT1_IRQn},
     {GPIO_PIN_2, EINT2_IRQn},
@@ -71,6 +89,7 @@ static const struct pin_irq_map pin_irq_map[] =
     {GPIO_PIN_13, EINT15_10_IRQn},
     {GPIO_PIN_14, EINT15_10_IRQn},
     {GPIO_PIN_15, EINT15_10_IRQn},
+#endif
 };
 
 static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
@@ -96,7 +115,7 @@ static uint32_t pin_irq_enable_mask = 0;
 
 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
 
-static rt_base_t _pin_get(const char *name)
+static rt_base_t apm32_pin_get(const char *name)
 {
     rt_base_t pin = 0;
     int hw_port_num, hw_pin_num = 0;
@@ -133,7 +152,7 @@ static rt_base_t _pin_get(const char *name)
     return pin;
 }
 
-static void _pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
+static void apm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
 {
     GPIO_T *gpio_port;
     uint16_t gpio_pin;
@@ -142,12 +161,15 @@ static void _pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
     {
         gpio_port = PIN_APMPORT(pin);
         gpio_pin = PIN_APMPIN(pin);
-
+#if defined(SOC_SERIES_APM32F0)
+        GPIO_WriteBitValue(gpio_port, gpio_pin, (GPIO_BSRET_T)value);
+#else
         GPIO_WriteBitValue(gpio_port, gpio_pin, (uint8_t)value);
+#endif
     }
 }
 
-static int _pin_read(rt_device_t dev, rt_base_t pin)
+static int apm32_pin_read(rt_device_t dev, rt_base_t pin)
 {
     GPIO_T *gpio_port;
     uint16_t gpio_pin;
@@ -163,7 +185,7 @@ static int _pin_read(rt_device_t dev, rt_base_t pin)
     return value;
 }
 
-static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
+static void apm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
 {
     GPIO_Config_T gpioConfig;
 
@@ -173,7 +195,7 @@ static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
     }
 
     /* Configure gpioConfigure */
-#if defined(APM32F10X_HD)
+#if defined(SOC_SERIES_APM32F1)
     gpioConfig.pin = PIN_APMPIN(pin);
     gpioConfig.mode = GPIO_MODE_OUT_PP;
     gpioConfig.speed = GPIO_SPEED_50MHz;
@@ -203,7 +225,7 @@ static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
         /* output setting: od. */
         gpioConfig.mode = GPIO_MODE_OUT_OD;
     }
-#elif defined( APM32F40X)
+#elif defined(SOC_SERIES_APM32F4)
     gpioConfig.pin = PIN_APMPIN(pin);
     gpioConfig.mode = GPIO_MODE_OUT;
     gpioConfig.otype = GPIO_OTYPE_PP;
@@ -239,6 +261,43 @@ static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
         gpioConfig.mode = GPIO_MODE_OUT;
         gpioConfig.otype = GPIO_OTYPE_OD;
     }
+#elif defined(SOC_SERIES_APM32F0)
+    gpioConfig.pin = PIN_APMPIN(pin);
+    gpioConfig.mode = GPIO_MODE_OUT;
+    gpioConfig.outtype = GPIO_OUT_TYPE_PP;
+    gpioConfig.pupd = GPIO_PUPD_NO;
+    gpioConfig.speed = GPIO_SPEED_50MHz;
+
+    if (mode == PIN_MODE_OUTPUT)
+    {
+        /* output setting */
+        gpioConfig.mode = GPIO_MODE_OUT;
+        gpioConfig.outtype = GPIO_OUT_TYPE_PP;
+    }
+    else if (mode == PIN_MODE_INPUT)
+    {
+        /* input setting: not pull. */
+        gpioConfig.mode = GPIO_MODE_IN;
+        gpioConfig.pupd = GPIO_PUPD_NO;
+    }
+    else if (mode == PIN_MODE_INPUT_PULLUP)
+    {
+        /* input setting: pull up. */
+        gpioConfig.mode = GPIO_MODE_IN;
+        gpioConfig.pupd = GPIO_PUPD_PU;
+    }
+    else if (mode == PIN_MODE_INPUT_PULLDOWN)
+    {
+        /* input setting: pull down. */
+        gpioConfig.mode = GPIO_MODE_IN;
+        gpioConfig.pupd = GPIO_PUPD_PD;
+    }
+    else if (mode == PIN_MODE_OUTPUT_OD)
+    {
+        /* output setting: od. */
+        gpioConfig.mode = GPIO_MODE_OUT;
+        gpioConfig.outtype = GPIO_OUT_TYPE_OD;
+    }
 #endif
     GPIO_Config(PIN_APMPORT(pin), &gpioConfig);
 }
@@ -266,7 +325,7 @@ rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
     return &pin_irq_map[mapindex];
 };
 
-static rt_err_t _pin_attach_irq(struct rt_device *device, rt_int32_t pin,
+static rt_err_t apm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
                                 rt_uint32_t mode, void (*hdr)(void *args), void *args)
 {
     rt_base_t level;
@@ -306,7 +365,7 @@ static rt_err_t _pin_attach_irq(struct rt_device *device, rt_int32_t pin,
     return RT_EOK;
 }
 
-static rt_err_t _pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
+static rt_err_t apm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
 {
     rt_base_t level;
     rt_int32_t irqindex = -1;
@@ -337,13 +396,14 @@ static rt_err_t _pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
     return RT_EOK;
 }
 
-static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
+static rt_err_t apm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
                                 rt_uint32_t enabled)
 {
     const struct pin_irq_map *irqmap;
     rt_base_t level;
     rt_int32_t irqindex = -1;
     GPIO_Config_T gpioConfig;
+    EINT_Config_T eintConfig;
 
     if (PIN_PORT(pin) >= PIN_APMPORT_MAX)
     {
@@ -373,34 +433,75 @@ static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
         gpioConfig.speed = GPIO_SPEED_50MHz;
         switch (pin_irq_hdr_tab[irqindex].mode)
         {
-#if defined(APM32F10X_HD)
+#if defined(SOC_SERIES_APM32F0)
+        case PIN_IRQ_MODE_RISING:
+            gpioConfig.mode = GPIO_MODE_IN;
+            gpioConfig.pupd = GPIO_PUPD_PD;
+            eintConfig.trigger = EINT_TRIGGER_RISING;
+            break;
+        case PIN_IRQ_MODE_FALLING:
+            gpioConfig.mode = GPIO_MODE_IN;
+            gpioConfig.pupd = GPIO_PUPD_PU;
+            eintConfig.trigger = EINT_TRIGGER_FALLING;
+            break;
+        case PIN_IRQ_MODE_RISING_FALLING:
+            gpioConfig.mode = GPIO_MODE_IN;
+            gpioConfig.pupd = GPIO_PUPD_NO;
+            eintConfig.trigger = EINT_TRIGGER_ALL;
+            break;
+#elif defined(SOC_SERIES_APM32F1)
         case PIN_IRQ_MODE_RISING:
             gpioConfig.mode = GPIO_MODE_IN_PD;
+            eintConfig.trigger = EINT_TRIGGER_RISING;
             break;
         case PIN_IRQ_MODE_FALLING:
             gpioConfig.mode = GPIO_MODE_IN_PU;
+            eintConfig.trigger = EINT_TRIGGER_FALLING;
             break;
         case PIN_IRQ_MODE_RISING_FALLING:
             gpioConfig.mode = GPIO_MODE_IN_FLOATING;
+            eintConfig.trigger = EINT_TRIGGER_RISING_FALLING;
             break;
-#elif defined( APM32F40X)
+#elif defined(SOC_SERIES_APM32F4)
         case PIN_IRQ_MODE_RISING:
             gpioConfig.mode = GPIO_MODE_IN;
             gpioConfig.pupd = GPIO_PUPD_DOWN;
+            eintConfig.trigger = EINT_TRIGGER_RISING;
             break;
         case PIN_IRQ_MODE_FALLING:
             gpioConfig.mode = GPIO_MODE_IN;
             gpioConfig.pupd = GPIO_PUPD_UP;
+            eintConfig.trigger = EINT_TRIGGER_FALLING;
             break;
         case PIN_IRQ_MODE_RISING_FALLING:
             gpioConfig.mode = GPIO_MODE_IN;
             gpioConfig.pupd = GPIO_PUPD_NOPULL;
+            eintConfig.trigger = EINT_TRIGGER_RISING_FALLING;
             break;
 #endif
         }
         GPIO_Config(PIN_APMPORT(pin), &gpioConfig);
-
+        
+#if defined(SOC_SERIES_APM32F0)
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
+        SYSCFG_EINTLine((SYSCFG_PORT_T)(((pin) >> 4) & 0xFu), (SYSCFG_PIN_T)irqindex);
+#elif defined(SOC_SERIES_APM32F1)
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_AFIO);
+        GPIO_ConfigEINTLine((GPIO_PORT_SOURCE_T)(((pin) >> 4) & 0xFu), (GPIO_PIN_SOURCE_T)irqindex);
+#elif defined(SOC_SERIES_APM32F4)
+        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
+        SYSCFG_ConfigEINTLine((SYSCFG_PORT_T)(((pin) >> 4) & 0xFu), (SYSCFG_PIN_T)irqindex);
+#endif
+        eintConfig.line = (EINT_LINE_T)(1u << PIN_NO(pin));
+        eintConfig.mode = EINT_MODE_INTERRUPT;
+        eintConfig.lineCmd = ENABLE;
+        EINT_Config(&eintConfig);
+        
+#if defined(SOC_SERIES_APM32F0)
+        NVIC_EnableIRQRequest(irqmap->irqno, 5);
+#else
         NVIC_EnableIRQRequest(irqmap->irqno, 5, 0);
+#endif
         pin_irq_enable_mask |= irqmap->pinbit;
 
         rt_hw_interrupt_enable(level);
@@ -416,7 +517,35 @@ static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
         level = rt_hw_interrupt_disable();
 
         pin_irq_enable_mask &= ~irqmap->pinbit;
-
+        
+#if defined(SOC_SERIES_APM32F0)
+        if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1))
+        {
+            if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1)))
+            {
+                NVIC_DisableIRQRequest(irqmap->irqno);
+            }
+        }
+        else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3))
+        {
+            if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3)))
+            {
+                NVIC_DisableIRQRequest(irqmap->irqno);
+            }
+        }
+        else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15))
+        {
+            if (!(pin_irq_enable_mask & (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 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
+            {
+                NVIC_DisableIRQRequest(irqmap->irqno);
+            }
+        }
+        else
+        {
+            NVIC_DisableIRQRequest(irqmap->irqno);
+        }
+#else
         if ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9))
         {
             if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9)))
@@ -435,6 +564,7 @@ static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
         {
             NVIC_DisableIRQRequest(irqmap->irqno);
         }
+#endif
         rt_hw_interrupt_enable(level);
     }
     else
@@ -444,15 +574,16 @@ static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
 
     return RT_EOK;
 }
-const static struct rt_pin_ops _apm32_pin_ops =
+
+const static struct rt_pin_ops apm32_pin_ops =
 {
-    _pin_mode,
-    _pin_write,
-    _pin_read,
-    _pin_attach_irq,
-    _pin_dettach_irq,
-    _pin_irq_enable,
-    _pin_get,
+    apm32_pin_mode,
+    apm32_pin_write,
+    apm32_pin_read,
+    apm32_pin_attach_irq,
+    apm32_pin_dettach_irq,
+    apm32_pin_irq_enable,
+    apm32_pin_get,
 };
 
 rt_inline void pin_irq_hdr(int irqno)
@@ -463,140 +594,115 @@ rt_inline void pin_irq_hdr(int irqno)
     }
 }
 
-
-void GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
+void GPIO_EXTI_IRQHandler(uint8_t exti_line)
 {
-    pin_irq_hdr(bit2bitno(GPIO_Pin));
+#if defined(SOC_SERIES_APM32F0)
+    if (EINT_ReadIntFlag(1U << exti_line) != RESET)
+#else
+    if (EINT_ReadIntFlag((EINT_LINE_T)(1U << exti_line)) != RESET)
+#endif
+    {
+        EINT_ClearIntFlag(1U << exti_line);
+        pin_irq_hdr(exti_line);
+    }
 }
 
+#if defined(SOC_SERIES_APM32F0)
+void EINT0_1_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GPIO_EXTI_IRQHandler(0);
+    GPIO_EXTI_IRQHandler(1);
+    rt_interrupt_leave();
+}
 
+void EINT2_3_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GPIO_EXTI_IRQHandler(2);
+    GPIO_EXTI_IRQHandler(3);
+    rt_interrupt_leave();
+}
+void EINT4_15_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    GPIO_EXTI_IRQHandler(4);
+    GPIO_EXTI_IRQHandler(5);
+    GPIO_EXTI_IRQHandler(6);
+    GPIO_EXTI_IRQHandler(7);
+    GPIO_EXTI_IRQHandler(8);
+    GPIO_EXTI_IRQHandler(9);
+    GPIO_EXTI_IRQHandler(10);
+    GPIO_EXTI_IRQHandler(11);
+    GPIO_EXTI_IRQHandler(12);
+    GPIO_EXTI_IRQHandler(13);
+    GPIO_EXTI_IRQHandler(14);
+    GPIO_EXTI_IRQHandler(15);
+    rt_interrupt_leave();
+}
+#else
 void EINT0_IRQHandler(void)
 {
     rt_interrupt_enter();
-
-    if (EINT_ReadIntFlag(EINT_LINE_0))
-    {
-        EINT_ClearIntFlag(EINT_LINE_0);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_0);
-    }
-
+    GPIO_EXTI_IRQHandler(0);
     rt_interrupt_leave();
 }
 
 void EINT1_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_1))
-    {
-        EINT_ClearIntFlag(EINT_LINE_1);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_1);
-    }
+    GPIO_EXTI_IRQHandler(1);
     rt_interrupt_leave();
 }
 
 void EINT2_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_2))
-    {
-        EINT_ClearIntFlag(EINT_LINE_2);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_2);
-    }
+    GPIO_EXTI_IRQHandler(2);
     rt_interrupt_leave();
 }
 
 void EINT3_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_3))
-    {
-        EINT_ClearIntFlag(EINT_LINE_3);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_3);
-    }
+    GPIO_EXTI_IRQHandler(3);
     rt_interrupt_leave();
 }
 
 void EINT4_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_4))
-    {
-        EINT_ClearIntFlag(EINT_LINE_4);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_4);
-    }
+    GPIO_EXTI_IRQHandler(4);
     rt_interrupt_leave();
 }
 
 void EINT9_5_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_5))
-    {
-        EINT_ClearIntFlag(EINT_LINE_5);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_5);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_6))
-    {
-        EINT_ClearIntFlag(EINT_LINE_6);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_6);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_7))
-    {
-        EINT_ClearIntFlag(EINT_LINE_7);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_7);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_8))
-    {
-        EINT_ClearIntFlag(EINT_LINE_8);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_8);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_9))
-    {
-        EINT_ClearIntFlag(EINT_LINE_9);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_9);
-    }
+    GPIO_EXTI_IRQHandler(5);
+    GPIO_EXTI_IRQHandler(6);
+    GPIO_EXTI_IRQHandler(7);
+    GPIO_EXTI_IRQHandler(8);
+    GPIO_EXTI_IRQHandler(9);
     rt_interrupt_leave();
 }
 
 void EINT15_10_IRQHandler(void)
 {
     rt_interrupt_enter();
-    if (EINT_ReadIntFlag(EINT_LINE_10))
-    {
-        EINT_ClearIntFlag(EINT_LINE_10);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_10);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_11))
-    {
-        EINT_ClearIntFlag(EINT_LINE_11);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_11);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_12))
-    {
-        EINT_ClearIntFlag(EINT_LINE_12);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_12);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_13))
-    {
-        EINT_ClearIntFlag(EINT_LINE_13);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_13);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_14))
-    {
-        EINT_ClearIntFlag(EINT_LINE_14);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_14);
-    }
-    if (EINT_ReadIntFlag(EINT_LINE_15))
-    {
-        EINT_ClearIntFlag(EINT_LINE_15);
-        GPIO_EXTI_IRQHandler(GPIO_PIN_15);
-    }
+    GPIO_EXTI_IRQHandler(10);
+    GPIO_EXTI_IRQHandler(11);
+    GPIO_EXTI_IRQHandler(12);
+    GPIO_EXTI_IRQHandler(13);
+    GPIO_EXTI_IRQHandler(14);
+    GPIO_EXTI_IRQHandler(15);
     rt_interrupt_leave();
 }
+#endif
 
 int rt_hw_pin_init(void)
 {
-#if defined(APM32F10X_HD)
+#if defined(SOC_SERIES_APM32F1)
 #ifdef GPIOA
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
 #endif
@@ -619,7 +725,7 @@ int rt_hw_pin_init(void)
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOG);
 #endif
     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_AFIO);
-#elif defined(APM32F40X)
+#elif defined(SOC_SERIES_APM32F4)
 #ifdef GPIOA
     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
 #endif
@@ -653,9 +759,30 @@ int rt_hw_pin_init(void)
 #ifdef GPIOK
     RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOK);
 #endif
+
+#elif defined(SOC_SERIES_APM32F0)
+#ifdef GPIOA
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
+#endif
+#ifdef GPIOB
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
 #endif
+#ifdef GPIOC
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOC);
+#endif
+#ifdef GPIOD
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOD);
+#endif
+#ifdef GPIOE
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOE);
+#endif
+#ifdef GPIOF
+    RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOF);
+#endif
+
+#endif /* SOC_SERIES_APM32F0 */
 
-    return rt_device_pin_register("pin", &_apm32_pin_ops, RT_NULL);
+    return rt_device_pin_register("pin", &apm32_pin_ops, RT_NULL);
 }
 
 #endif /* RT_USING_PIN */

+ 230 - 115
project_0/libraries/Drivers/drv_hwtimer.c

@@ -7,17 +7,18 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
 
-#define LOG_TAG               "drv.hwtimer"
+#define DBG_TAG               "drv.hwtimer"
 #define DBG_LVL               DBG_INFO
 #include <rtdbg.h>
 
 #ifdef RT_USING_HWTIMER
 
-static const struct rt_hwtimer_info _info =
+static const struct rt_hwtimer_info apm32_timer_info =
 {
     .maxfreq = 1000000,
     .minfreq = 2000,
@@ -78,6 +79,15 @@ enum
 #ifdef BSP_USING_TMR14
     TMR14_INDEX,
 #endif
+#ifdef BSP_USING_TMR15
+    TMR15_INDEX,
+#endif
+#ifdef BSP_USING_TMR16
+    TMR16_INDEX,
+#endif
+#ifdef BSP_USING_TMR17
+    TMR17_INDEX,
+#endif
 };
 
 static struct apm32_timer tmr_config[] =
@@ -86,10 +96,12 @@ static struct apm32_timer tmr_config[] =
     {
         "timer1",
         TMR1,
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
         TMR1_UP_IRQn,
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
         TMR1_UP_TMR10_IRQn,
+#elif defined(SOC_SERIES_APM32F0)
+        TMR1_BRK_UP_TRG_COM_IRQn
 #endif
     },
 #endif
@@ -125,9 +137,11 @@ static struct apm32_timer tmr_config[] =
     {
         "timer6",
         TMR6,
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1) || defined(APM32F030) || defined(APM32F070)
         TMR6_IRQn,
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4) 
+        TMR6_DAC_IRQn
+#elif defined(SOC_SERIES_APM32F0) && !defined(APM32F030) && !defined(APM32F070)
         TMR6_DAC_IRQn
 #endif
     },
@@ -143,9 +157,9 @@ static struct apm32_timer tmr_config[] =
     {
         "timer8",
         TMR8,
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
         TMR8_UP_IRQn,
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
         TMR8_UP_TMR13_IRQn,
 #endif
     },
@@ -189,30 +203,122 @@ static struct apm32_timer tmr_config[] =
     {
         "timer14",
         TMR14,
+#if defined(SOC_SERIES_APM32F0)
+        TMR14_IRQn,
+#elif defined(SOC_SERIES_APM32F4)
         TMR8_TRG_COM_TMR14_IRQn,
+#endif
+    },
+#endif
+#ifdef BSP_USING_TMR15
+    {
+        "timer15",
+        TMR15,
+        TMR15_IRQn,
+    },
+#endif
+#ifdef BSP_USING_TMR16
+    {
+        "timer16",
+        TMR16,
+        TMR16_IRQn,
+    },
+#endif
+#ifdef BSP_USING_TMR17
+    {
+        "timer17",
+        TMR17,
+        TMR17_IRQn,
     },
 #endif
 };
 
-static rt_uint32_t _hwtimer_clock_get(TMR_T *tmr)
+static rt_uint32_t apm32_hwtimer_clock_get(TMR_T *tmr)
 {
+#if defined(SOC_SERIES_APM32F0)
+    uint32_t pclk1;
+    
+    pclk1 = RCM_ReadPCLKFreq();
+    
+    return (rt_uint32_t)(pclk1 * ((RCM->CFG1_B.APB1PSC != 0) ? 2 : 1));
+#else
     uint32_t pclk1, pclk2;
 
     RCM_ReadPCLKFreq(&pclk1, &pclk2);
 
     if (tmr == TMR1 || tmr == TMR8 || tmr == TMR9 || tmr == TMR10 || tmr == TMR11)
     {
-        return (rt_uint32_t)(pclk2 * ((RCM->CFG_B.APB2PSC != RCM_APB_DIV_1) ? 2 : 1));
+        return (rt_uint32_t)(pclk2 * ((RCM->CFG_B.APB2PSC != 0) ? 2 : 1));
     }
     else
     {
-        return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != RCM_APB_DIV_1) ? 2 : 1));
+        return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != 0) ? 2 : 1));
     }
+#endif
 }
 
-static void _hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
+static void apm32_hwtimer_enable_clock(void)
 {
+#ifdef BSP_USING_TMR1
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
+#endif
+#ifdef BSP_USING_TMR2
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);
+#endif
+#ifdef BSP_USING_TMR3
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
+#endif
+#ifdef BSP_USING_TMR4
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
+#endif
+#ifdef BSP_USING_TMR5
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR5);
+#endif
+#ifdef BSP_USING_TMR6
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);
+#endif
+#ifdef BSP_USING_TMR7
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR7);
+#endif
+#ifdef BSP_USING_TMR8
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
+#endif
+#ifdef BSP_USING_TMR9
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
+#endif
+#ifdef BSP_USING_TMR10
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR10);
+#endif
+#ifdef BSP_USING_TMR11
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR11);
+#endif
+#ifdef BSP_USING_TMR12
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR12);
+#endif
+#ifdef BSP_USING_TMR13
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR13);
+#endif
+#ifdef BSP_USING_TMR14
+    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);
+#endif
+#ifdef BSP_USING_TMR15
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR15);
+#endif
+#ifdef BSP_USING_TMR16
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR16);
+#endif
+#ifdef BSP_USING_TMR17
+    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR17);
+#endif
+}
+
+static void apm32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
+{
+#if defined(SOC_SERIES_APM32F0)
+    TMR_TimeBase_T   base_config;
+#else
     TMR_BaseConfig_T base_config;
+#endif
     uint32_t prescaler = 0;
     struct apm32_timer *timer_config;
 
@@ -221,77 +327,24 @@ static void _hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
     if (state)
     {
         timer_config = (struct apm32_timer *)timer->parent.user_data;
-        if (timer_config->tmr == TMR2)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);
-        }
-        else if (timer_config->tmr == TMR3)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
-        }
-        else if (timer_config->tmr == TMR4)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
-        }
-        else if (timer_config->tmr == TMR5)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR5);
-        }
-        else if (timer_config->tmr == TMR6)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);
-        }
-        else if (timer_config->tmr == TMR7)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR7);
-        }
-#ifdef APM32F10X_HD
-        else if (timer_config->tmr == TMR1)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
-        }
-        else if (timer_config->tmr == TMR8)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
-        }
-#endif
-#ifdef APM32F40X
-        else if (timer_config->tmr == TMR1)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
-        }
-        else if (timer_config->tmr == TMR8)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
-        }
-        else if (timer_config->tmr == TMR9)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
-        }
-        else if (timer_config->tmr == TMR10)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR10);
-        }
-        else if (timer_config->tmr == TMR11)
-        {
-            RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR11);
-        }
-        else if (timer_config->tmr == TMR12)
-        {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR12);
-        }
-        else if (timer_config->tmr == TMR13)
+        
+        apm32_hwtimer_enable_clock();
+        
+        prescaler = (uint32_t)(apm32_hwtimer_clock_get(timer_config->tmr) / 10000) - 1;
+
+        base_config.period          = 10000 - 1;
+#if defined(SOC_SERIES_APM32F0)
+        base_config.div               = prescaler;
+        base_config.clockDivision     = TMR_CKD_DIV1;
+        if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
         {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR13);
+            base_config.counterMode   = TMR_COUNTER_MODE_UP;
         }
-        else if (timer_config->tmr == TMR14)
+        else
         {
-            RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);
+            base_config.counterMode   = TMR_COUNTER_MODE_DOWN;
         }
-#endif
-        prescaler = (uint32_t)(_hwtimer_clock_get(timer_config->tmr) / 10000) - 1;
-
-        base_config.period          = 10000 - 1;
+#else
         base_config.division        = prescaler;
         base_config.clockDivision   = TMR_CLOCK_DIV_1;
         if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
@@ -302,21 +355,28 @@ static void _hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
         {
             base_config.countMode   = TMR_COUNTER_MODE_DOWN;
         }
+#endif
         base_config.repetitionCounter = 0;
         TMR_ConfigTimeBase(timer_config->tmr, &base_config);
-
+        
+#if defined(SOC_SERIES_APM32F0)
+        /* set the TIMx priority */
+        NVIC_EnableIRQRequest(timer_config->irqn, 3);
+        /* enable update request source */
+        TMR_ConfigUPdateRequest(timer_config->tmr, TMR_UPDATE_SOURCE_REGULAR);
+#else
         /* set the TIMx priority */
         NVIC_EnableIRQRequest(timer_config->irqn, 3, 0);
-
-        /* clear update flag */
-        TMR_ClearStatusFlag(timer_config->tmr, TMR_FLAG_UPDATE);
         /* enable update request source */
         TMR_ConfigUpdateRequest(timer_config->tmr, TMR_UPDATE_SOURCE_REGULAR);
+#endif
+        /* clear update flag */
+        TMR_ClearStatusFlag(timer_config->tmr, TMR_FLAG_UPDATE);
         LOG_D("%s init success", timer_config->name);
     }
 }
 
-static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
+static rt_err_t apm32_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
 {
     rt_err_t result = RT_EOK;
     struct apm32_timer *timer_config = RT_NULL;
@@ -326,41 +386,46 @@ static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mo
     timer_config = (struct apm32_timer *)timer->parent.user_data;
 
     /* set timer_config counter */
-    TMR_ConfigCounter(timer_config->tmr, 0);
+    timer_config->tmr->CNT = 0;
     /* set timer_config autoReload */
-    TMR_ConfigAutoreload(timer_config->tmr, t - 1);
+    timer_config->tmr->AUTORLD = t - 1;
 
     if (opmode == HWTIMER_MODE_ONESHOT)
     {
         /* set timer to single mode */
-        TMR_ConfigSinglePulseMode(timer_config->tmr, TMR_SPM_SINGLE);
+        timer_config->tmr->CTRL1_B.SPMEN = 1;
     }
     else
     {
-        TMR_ConfigSinglePulseMode(timer_config->tmr, TMR_SPM_REPETITIVE);
+        timer_config->tmr->CTRL1_B.SPMEN = 0;
     }
 
     TMR_EnableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
 
-    if (timer_config->tmr == TMR1 || timer_config->tmr == TMR8 || timer_config->tmr == TMR2 || \
-            timer_config->tmr == TMR3 || timer_config->tmr == TMR4 || timer_config->tmr == TMR5 || \
-            timer_config->tmr == TMR9 || timer_config->tmr == TMR12)
+#if defined(SOC_SERIES_APM32F0)
+    if (timer_config->tmr == TMR1 || timer_config->tmr == TMR2 || timer_config->tmr == TMR3 || \
+        timer_config->tmr == TMR15)
+#else
+    if (timer_config->tmr == TMR1 || timer_config->tmr == TMR2 || timer_config->tmr == TMR3 || \
+        timer_config->tmr == TMR4 || timer_config->tmr == TMR5 || timer_config->tmr == TMR8 || \
+        timer_config->tmr == TMR9 || timer_config->tmr == TMR12)
+#endif
     {
-        if (timer_config->tmr->SMCTRL_B.SMFSEL != TMR_SLAVE_MODE_TRIGGER)
+        if (timer_config->tmr->SMCTRL_B.SMFSEL != 0x06)
         {
             TMR_Enable(timer_config->tmr);
-            result = -RT_EOK;
+            result = RT_EOK;
         }
     }
     else
     {
         TMR_Enable(timer_config->tmr);
-        result = -RT_EOK;
+        result = RT_EOK;
     }
     return result;
 }
 
-static void _hwtimer_stop(rt_hwtimer_t *timer)
+static void apm32_hwtimer_stop(rt_hwtimer_t *timer)
 {
     struct apm32_timer *timer_config = RT_NULL;
     RT_ASSERT(timer != RT_NULL);
@@ -368,10 +433,10 @@ static void _hwtimer_stop(rt_hwtimer_t *timer)
 
     TMR_DisableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
     TMR_Enable(timer_config->tmr);
-    TMR_ConfigCounter(timer_config->tmr, 0);
+    timer_config->tmr->CNT = 0;
 }
 
-static rt_err_t _hwtimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
+static rt_err_t apm32_hwtimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
 {
     struct apm32_timer *timer_config = RT_NULL;
     rt_err_t result = RT_EOK;
@@ -389,18 +454,21 @@ static rt_err_t _hwtimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
         /* set timer frequence */
         freq = *((rt_uint32_t *)arg);
 
-        val = _hwtimer_clock_get(timer_config->tmr) / freq;
+        val = apm32_hwtimer_clock_get(timer_config->tmr) / freq;
 
-        TMR_ConfigPrescaler(timer_config->tmr, val - 1, TMR_PSC_RELOAD_IMMEDIATE);
+        /* Configures the timer prescaler */
+        timer_config->tmr->PSC_B.PSC = val - 1;
+        timer_config->tmr->CEG_B.UEG = 1;
         break;
     default:
+        LOG_E("invalid cmd: 0x%x\n", cmd);
         result = -RT_ENOSYS;
         break;
     }
     return result;
 }
 
-static rt_uint32_t _hwtimer_counter_get(rt_hwtimer_t *timer)
+static rt_uint32_t apm32_hwtimer_counter_get(rt_hwtimer_t *timer)
 {
     struct apm32_timer *timer_config = RT_NULL;
     RT_ASSERT(timer != RT_NULL);
@@ -409,16 +477,27 @@ static rt_uint32_t _hwtimer_counter_get(rt_hwtimer_t *timer)
     return timer_config->tmr->CNT;
 }
 
-static const struct rt_hwtimer_ops _hwtimer_ops =
+static const struct rt_hwtimer_ops apm32_hwtimer_ops =
 {
-    .init  = _hwtimer_init,
-    .start = _hwtimer_start,
-    .stop  = _hwtimer_stop,
-    .count_get = _hwtimer_counter_get,
-    .control = _hwtimer_ctrl,
+    .init  = apm32_hwtimer_init,
+    .start = apm32_hwtimer_start,
+    .stop  = apm32_hwtimer_stop,
+    .count_get = apm32_hwtimer_counter_get,
+    .control = apm32_hwtimer_ctrl,
 };
 
-#ifdef APM32F10X_HD
+
+#if defined(SOC_SERIES_APM32F0)
+#ifdef BSP_USING_TMR1
+void TMR1_BRK_UP_TRG_COM_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    rt_device_hwtimer_isr(&tmr_config[TMR1_INDEX].device);
+    TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
+    rt_interrupt_leave();
+}
+#endif
+#elif defined(SOC_SERIES_APM32F1)
 #ifdef BSP_USING_TMR1
 void TMR1_UP_IRQHandler(void)
 {
@@ -428,7 +507,7 @@ void TMR1_UP_IRQHandler(void)
     rt_interrupt_leave();
 }
 #endif
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
 #if (defined(BSP_USING_TMR1) || defined(BSP_USING_TMR10))
 void TMR1_UP_TMR10_IRQHandler(void)
 {
@@ -489,9 +568,11 @@ void TMR5_IRQHandler(void)
 #endif
 
 #ifdef BSP_USING_TMR6
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1) || defined(APM32F030) || defined(APM32F070)
     void TMR6_IRQHandler(void)
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
+    void TMR6_DAC_IRQHandler(void)
+#elif defined(SOC_SERIES_APM32F0) && !defined(APM32F030) && !defined(APM32F070)
     void TMR6_DAC_IRQHandler(void)
 #endif
 {
@@ -512,7 +593,7 @@ void TMR7_IRQHandler(void)
 }
 #endif
 
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
 #ifdef BSP_USING_TMR8
 void TMR8_UP_IRQHandler(void)
 {
@@ -522,7 +603,7 @@ void TMR8_UP_IRQHandler(void)
     rt_interrupt_leave();
 }
 #endif
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F4)
 #if (defined(BSP_USING_TMR8) || defined(BSP_USING_TMR13))
 void TMR8_UP_TMR13_IRQHandler(void)
 {
@@ -573,7 +654,11 @@ void TMR8_BRK_TMR12_IRQHandler(void)
 #endif
 
 #ifdef BSP_USING_TMR14
-void TMR8_TRG_COM_TMR14_IRQHandler(void)
+#if defined(SOC_SERIES_APM32F0)
+    void TMR14_IRQHandler(void)
+#elif defined(SOC_SERIES_APM32F4)
+    void TMR8_TRG_COM_TMR14_IRQHandler(void)
+#endif
 {
     rt_interrupt_enter();
     rt_device_hwtimer_isr(&tmr_config[TMR14_INDEX].device);
@@ -582,6 +667,36 @@ void TMR8_TRG_COM_TMR14_IRQHandler(void)
 }
 #endif
 
+#ifdef BSP_USING_TMR15
+void TMR15_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    rt_device_hwtimer_isr(&tmr_config[TMR15_INDEX].device);
+    TMR_ClearIntFlag(TMR15, TMR_INT_UPDATE);
+    rt_interrupt_leave();
+}
+#endif
+
+#ifdef BSP_USING_TMR16
+void TMR16_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    rt_device_hwtimer_isr(&tmr_config[TMR16_INDEX].device);
+    TMR_ClearIntFlag(TMR16, TMR_INT_UPDATE);
+    rt_interrupt_leave();
+}
+#endif
+
+#ifdef BSP_USING_TMR17
+void TMR17_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    rt_device_hwtimer_isr(&tmr_config[TMR17_INDEX].device);
+    TMR_ClearIntFlag(TMR17, TMR_INT_UPDATE);
+    rt_interrupt_leave();
+}
+#endif
+
 static int rt_hw_hwtimer_init(void)
 {
     int i = 0;
@@ -589,8 +704,8 @@ static int rt_hw_hwtimer_init(void)
 
     for (i = 0; i < sizeof(tmr_config) / sizeof(tmr_config[0]); i++)
     {
-        tmr_config[i].device.info = &_info;
-        tmr_config[i].device.ops  = &_hwtimer_ops;
+        tmr_config[i].device.info = &apm32_timer_info;
+        tmr_config[i].device.ops  = &apm32_hwtimer_ops;
         if (rt_device_hwtimer_register(&tmr_config[i].device, tmr_config[i].name, &tmr_config[i]) == RT_EOK)
         {
             LOG_D("%s register success", tmr_config[i].name);

+ 27 - 0
project_0/libraries/Drivers/drv_log.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-12-19                  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>

+ 149 - 135
project_0/libraries/Drivers/drv_pwm.c

@@ -7,6 +7,7 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
@@ -14,7 +15,7 @@
 #ifdef RT_USING_PWM
 #include <drivers/rt_drv_pwm.h>
 
-#define LOG_TAG               "drv.pwm"
+#define DBG_TAG               "drv.pwm"
 #define DBG_LVL               DBG_INFO
 #include <rtdbg.h>
 
@@ -22,28 +23,8 @@
 #define MIN_PERIOD 3
 #define MIN_PULSE  2
 
-#ifdef APM32F10X_HD
-#define _PWM_GPIO_INIT(port_num, pin_num) \
-do \
-{ \
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIO##port_num); \
-    gpio_config->pin = GPIO_PIN_##pin_num; \
-    gpio_config->mode = GPIO_MODE_AF_PP; \
-    gpio_config->speed = GPIO_SPEED_50MHz; \
-    GPIO_Config(GPIO##port_num, gpio_config); \
-} while (0)
-#elif APM32F40X
-#define _PWM_GPIO_INIT(port_num, pin_num) \
-do \
-{ \
-    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIO##port_num); \
-    gpio_config->pin = GPIO_PIN_##pin_num; \
-    gpio_config->mode = GPIO_MODE_AF; \
-    gpio_config->otype = GPIO_OTYPE_PP; \
-    gpio_config->speed = GPIO_SPEED_50MHz; \
-    GPIO_Config(GPIO##port_num, gpio_config); \
-} while (0)
-#endif
+/* Init timer gpio and enable clock */
+extern void apm32_msp_timer_init(void *Instance);
 
 enum
 {
@@ -83,6 +64,15 @@ enum
 #ifdef BSP_USING_PWM14
     PWM14_INDEX,
 #endif
+#ifdef BSP_USING_PWM15
+    PWM15_INDEX,
+#endif
+#ifdef BSP_USING_PWM16
+    PWM16_INDEX,
+#endif
+#ifdef BSP_USING_PWM17
+    PWM17_INDEX,
+#endif
 };
 
 struct apm32_pwm
@@ -179,207 +169,200 @@ static struct apm32_pwm pwm_config[] =
         0,
     },
 #endif
+#ifdef BSP_USING_PWM15
+    {
+        "pwm15",
+        TMR15,
+        0,
+    },
+#endif
+#ifdef BSP_USING_PWM16
+    {
+        "pwm16",
+        TMR16,
+        0,
+    },
+#endif
+#ifdef BSP_USING_PWM17
+    {
+        "pwm17",
+        TMR17,
+        0,
+    },
+#endif
 };
 
-static void _pwm_channel_init(GPIO_Config_T *gpio_config)
+static void pwm_channel_init(void)
 {
 #ifdef BSP_USING_PWM1_CH1
     pwm_config[PWM1_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(A, 8);
 #endif
 #ifdef BSP_USING_PWM1_CH2
     pwm_config[PWM1_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(A, 9);
 #endif
 #ifdef BSP_USING_PWM1_CH3
     pwm_config[PWM1_INDEX].channel |= 1 << 2;
-    _PWM_GPIO_INIT(A, 10);
 #endif
 #ifdef BSP_USING_PWM1_CH4
     pwm_config[PWM1_INDEX].channel |= 1 << 3;
-    _PWM_GPIO_INIT(A, 11);
 #endif
 #ifdef BSP_USING_PWM2_CH1
     pwm_config[PWM2_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(A, 0);
 #endif
 #ifdef BSP_USING_PWM2_CH2
     pwm_config[PWM2_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(A, 1);
 #endif
 #ifdef BSP_USING_PWM2_CH3
     pwm_config[PWM2_INDEX].channel |= 1 << 2;
-    _PWM_GPIO_INIT(A, 2);
 #endif
 #ifdef BSP_USING_PWM2_CH4
     pwm_config[PWM2_INDEX].channel |= 1 << 3;
-    _PWM_GPIO_INIT(A, 3);
 #endif
-
-#ifdef APM32F10X_HD
 #ifdef BSP_USING_PWM3_CH1
     pwm_config[PWM3_INDEX].channel |= 1 << 0;
-    GPIO_ConfigPinRemap(GPIO_FULL_REMAP_TMR3);
-    _PWM_GPIO_INIT(C, 6);
 #endif
 #ifdef BSP_USING_PWM3_CH2
     pwm_config[PWM3_INDEX].channel |= 1 << 1;
-    GPIO_ConfigPinRemap(GPIO_FULL_REMAP_TMR3);
-    _PWM_GPIO_INIT(C, 7);
 #endif
 #ifdef BSP_USING_PWM3_CH3
     pwm_config[PWM3_INDEX].channel |= 1 << 2;
-    GPIO_ConfigPinRemap(GPIO_FULL_REMAP_TMR3);
-    _PWM_GPIO_INIT(C, 8);
 #endif
 #ifdef BSP_USING_PWM3_CH4
     pwm_config[PWM3_INDEX].channel |= 1 << 3;
-    GPIO_ConfigPinRemap(GPIO_FULL_REMAP_TMR3);
-    _PWM_GPIO_INIT(C, 9);
-#endif
-#elif APM32F40X
-#ifdef BSP_USING_PWM3_CH1
-    pwm_config[PWM3_INDEX].channel |= 1 << 0;
-    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
-    _PWM_GPIO_INIT(C, 6);
 #endif
-#ifdef BSP_USING_PWM3_CH2
-    pwm_config[PWM3_INDEX].channel |= 1 << 1;
-    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
-    _PWM_GPIO_INIT(C, 7);
-#endif
-#ifdef BSP_USING_PWM3_CH3
-    pwm_config[PWM3_INDEX].channel |= 1 << 2;
-    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_8, GPIO_AF_TMR3);
-    _PWM_GPIO_INIT(C, 8);
-#endif
-#ifdef BSP_USING_PWM3_CH4
-    pwm_config[PWM3_INDEX].channel |= 1 << 3;
-    GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_9, GPIO_AF_TMR3);
-    _PWM_GPIO_INIT(C, 9);
-#endif
-#endif
-
 #ifdef BSP_USING_PWM4_CH1
     pwm_config[PWM4_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(B, 6);
 #endif
 #ifdef BSP_USING_PWM4_CH2
     pwm_config[PWM4_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(B, 7);
 #endif
 #ifdef BSP_USING_PWM4_CH3
     pwm_config[PWM4_INDEX].channel |= 1 << 2;
-    _PWM_GPIO_INIT(B, 8);
 #endif
 #ifdef BSP_USING_PWM4_CH4
     pwm_config[PWM4_INDEX].channel |= 1 << 3;
-    _PWM_GPIO_INIT(B, 9);
 #endif
 #ifdef BSP_USING_PWM5_CH1
     pwm_config[PWM5_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(A, 0);
 #endif
 #ifdef BSP_USING_PWM5_CH2
     pwm_config[PWM5_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(A, 1);
 #endif
 #ifdef BSP_USING_PWM5_CH3
     pwm_config[PWM5_INDEX].channel |= 1 << 2;
-    _PWM_GPIO_INIT(A, 2);
 #endif
 #ifdef BSP_USING_PWM5_CH4
     pwm_config[PWM5_INDEX].channel |= 1 << 3;
-    _PWM_GPIO_INIT(A, 3);
 #endif
 #ifdef BSP_USING_PWM8_CH1
     pwm_config[PWM8_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(C, 6);
 #endif
 #ifdef BSP_USING_PWM8_CH2
     pwm_config[PWM8_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(C, 7);
 #endif
 #ifdef BSP_USING_PWM8_CH3
     pwm_config[PWM8_INDEX].channel |= 1 << 2;
-    _PWM_GPIO_INIT(C, 8);
 #endif
 #ifdef BSP_USING_PWM8_CH4
     pwm_config[PWM8_INDEX].channel |= 1 << 3;
-    _PWM_GPIO_INIT(C, 9);
 #endif
-#ifdef APM32F40X
 #ifdef BSP_USING_PWM9_CH1
     pwm_config[PWM9_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(E, 5);
 #endif
 #ifdef BSP_USING_PWM9_CH2
     pwm_config[PWM9_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(E, 6);
 #endif
 #ifdef BSP_USING_PWM10_CH1
     pwm_config[PWM10_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(F, 6);
 #endif
 #ifdef BSP_USING_PWM11_CH1
     pwm_config[PWM11_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(F, 7);
 #endif
 #ifdef BSP_USING_PWM12_CH1
-    pwm_config[PWM9_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(H, 6);
+    pwm_config[PWM12_INDEX].channel |= 1 << 0;
 #endif
 #ifdef BSP_USING_PWM12_CH2
-    pwm_config[PWM9_INDEX].channel |= 1 << 1;
-    _PWM_GPIO_INIT(H, 9);
+    pwm_config[PWM12_INDEX].channel |= 1 << 1;
 #endif
 #ifdef BSP_USING_PWM13_CH1
-    pwm_config[PWM10_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(F, 8);
+    pwm_config[PWM13_INDEX].channel |= 1 << 0;
 #endif
 #ifdef BSP_USING_PWM14_CH1
-    pwm_config[PWM11_INDEX].channel |= 1 << 0;
-    _PWM_GPIO_INIT(F, 9);
+    pwm_config[PWM14_INDEX].channel |= 1 << 0;
 #endif
+#ifdef BSP_USING_PWM15_CH1
+    pwm_config[PWM15_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_PWM15_CH2
+    pwm_config[PWM15_INDEX].channel |= 1 << 1;
+#endif
+#ifdef BSP_USING_PWM16_CH1
+    pwm_config[PWM16_INDEX].channel |= 1 << 0;
+#endif
+#ifdef BSP_USING_PWM17_CH1
+    pwm_config[PWM17_INDEX].channel |= 1 << 0;
 #endif
 }
 
-static rt_err_t _pwm_hw_init(struct apm32_pwm *device)
+static rt_err_t apm32_pwm_hw_init(struct apm32_pwm *device)
 {
     rt_err_t result = RT_EOK;
     TMR_T *tmr = RT_NULL;
-    TMR_BaseConfig_T   base_config;
+    
+    RT_ASSERT(device != RT_NULL);
+    tmr = (TMR_T *)device->tmr;
+    
+    /* Init timer gpio and enable clock */
+    apm32_msp_timer_init(tmr);
+    
+#if defined(SOC_SERIES_APM32F0)
+    TMR_TimeBase_T   base_config;
     TMR_OCConfig_T     oc_config;
+    
+    /* configure the tmrer to pwm mode */
+    base_config.div = 0;
+    base_config.counterMode = TMR_COUNTER_MODE_UP;
+    base_config.period = 0;
+    base_config.clockDivision = TMR_CKD_DIV1;
+    TMR_ConfigTimeBase(tmr, &base_config);
 
-    RT_ASSERT(device != RT_NULL);
+    TMR_SelectOutputTrigger(tmr, TMR_TRGOSOURCE_RESET);
+    TMR_DisableMasterSlaveMode(tmr);
 
-    tmr = (TMR_T *)device->tmr;
+    oc_config.OC_Mode = TMR_OC_MODE_PWM1;
+    oc_config.Pulse = 0;
+    oc_config.OC_Polarity = TMR_OC_POLARITY_HIGH;
+    oc_config.OC_NIdlestate = TMR_OCNIDLESTATE_RESET;
+    oc_config.OC_Idlestate  = TMR_OCIDLESTATE_RESET;
+    oc_config.OC_OutputState = TMR_OUTPUT_STATE_ENABLE;
 
-    if (tmr == TMR1)
-    {
-        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
-    }
-    else if (tmr == TMR8)
-    {
-        RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
-    }
-    else if (tmr == TMR2)
+    /* config pwm channel */
+    if (device->channel & 0x01)
     {
-        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);
+        TMR_OC1Config(tmr, &oc_config);
     }
-    else if (tmr == TMR3)
+
+    if (device->channel & 0x02)
     {
-        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
+        TMR_OC2Config(tmr, &oc_config);
     }
-    else if (tmr == TMR4)
+
+    if (device->channel & 0x04)
     {
-        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
+        TMR_OC3Config(tmr, &oc_config);
     }
-    else if (tmr == TMR5)
+
+    if (device->channel & 0x08)
     {
-        RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR5);
+        TMR_OC4Config(tmr, &oc_config);
     }
 
+    /* enable update request source */
+    TMR_ConfigUPdateRequest(tmr, TMR_UPDATE_SOURCE_REGULAR);
+#else
+    TMR_BaseConfig_T   base_config;
+    TMR_OCConfig_T     oc_config;
+
     /* configure the tmrer to pwm mode */
     base_config.division = 0;
     base_config.countMode = TMR_COUNTER_MODE_UP;
@@ -420,20 +403,36 @@ static rt_err_t _pwm_hw_init(struct apm32_pwm *device)
 
     /* enable update request source */
     TMR_ConfigUpdateRequest(tmr, TMR_UPDATE_SOURCE_REGULAR);
+#endif
 
     return result;
 }
 
-static rt_uint32_t _pwm_timer_clock_get(TMR_T *tmr)
+static rt_uint32_t timer_clock_get(TMR_T *tmr)
 {
+#if defined(SOC_SERIES_APM32F0)
     uint32_t pclk1;
+    
+    pclk1 = RCM_ReadPCLKFreq();
+    
+    return (rt_uint32_t)(pclk1 * ((RCM->CFG1_B.APB1PSC != 0) ? 2 : 1));
+#else
+    uint32_t pclk1, pclk2;
 
-    RCM_ReadPCLKFreq(&pclk1, NULL);
+    RCM_ReadPCLKFreq(&pclk1, &pclk2);
 
-    return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != RCM_APB_DIV_1) ? 2 : 1));
+    if (tmr == TMR1 || tmr == TMR8 || tmr == TMR9 || tmr == TMR10 || tmr == TMR11)
+    {
+        return (rt_uint32_t)(pclk2 * ((RCM->CFG_B.APB2PSC != 0) ? 2 : 1));
+    }
+    else
+    {
+        return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != 0) ? 2 : 1));
+    }
+#endif
 }
 
-static rt_err_t _pwm_enable(TMR_T *tmr, struct rt_pwm_configuration *configuration, rt_bool_t enable)
+static rt_err_t drv_pwm_enable(TMR_T *tmr, struct rt_pwm_configuration *configuration, rt_bool_t enable)
 {
     rt_uint32_t channel = (configuration->channel - 1) << 2;
 
@@ -447,7 +446,11 @@ static rt_err_t _pwm_enable(TMR_T *tmr, struct rt_pwm_configuration *configurati
         {
             TMR_EnableCCxChannel(tmr, (TMR_CHANNEL_T)(0x01 << (channel & 0x1FU)));
         }
+#if defined(SOC_SERIES_APM32F0)
+        if (tmr == TMR1 || tmr == TMR15 || tmr == TMR16 || tmr == TMR17)
+#else
         if (tmr == TMR1 || tmr == TMR8)
+#endif
         {
             TMR_EnablePWMOutputs(tmr);
         }
@@ -463,7 +466,11 @@ static rt_err_t _pwm_enable(TMR_T *tmr, struct rt_pwm_configuration *configurati
         {
             TMR_DisableCCxChannel(tmr, (TMR_CHANNEL_T)(0x01 << (channel & 0x1FU)));
         }
+#if defined(SOC_SERIES_APM32F0)
+        if (tmr == TMR1 || tmr == TMR15 || tmr == TMR16 || tmr == TMR17)
+#else
         if (tmr == TMR1 || tmr == TMR8)
+#endif
         {
             TMR_DisablePWMOutputs(tmr);
         }
@@ -473,24 +480,32 @@ static rt_err_t _pwm_enable(TMR_T *tmr, struct rt_pwm_configuration *configurati
     return RT_EOK;
 }
 
-static rt_err_t _pwm_get(TMR_T *tmr, struct rt_pwm_configuration *configuration)
+static rt_err_t drv_pwm_get(TMR_T *tmr, struct rt_pwm_configuration *configuration)
 {
     /* Converts the channel number to the channel number of library */
     rt_uint32_t channel = (configuration->channel - 1) << 2;
     rt_uint64_t timer_clock;
     rt_uint32_t timer_reload, timer_psc;
 
-    timer_clock = _pwm_timer_clock_get(tmr);
-
+    timer_clock = timer_clock_get(tmr);
+    
+#if defined(SOC_SERIES_APM32F0)
+    if (tmr->CTRL1_B.CLKDIV == TMR_CKD_DIV2)
+#else
     if (tmr->CTRL1_B.CLKDIV == TMR_CLOCK_DIV_2)
+#endif
     {
-        timer_clock <<= 1;
+        timer_clock = timer_clock / 2;
     }
+#if defined(SOC_SERIES_APM32F0)
+    if (tmr->CTRL1_B.CLKDIV == TMR_CKD_DIV4)
+#else
     else if (tmr->CTRL1_B.CLKDIV == TMR_CLOCK_DIV_4)
+#endif
     {
-        timer_clock <<= 2;
+        timer_clock = timer_clock / 4;
     }
-
+    
     uint32_t temp;
     temp = (uint32_t)tmr;
     temp += (uint32_t)(0x34 + channel);
@@ -501,18 +516,18 @@ static rt_err_t _pwm_get(TMR_T *tmr, struct rt_pwm_configuration *configuration)
     timer_psc = tmr->PSC;
     configuration->period = (timer_reload + 1) * (timer_psc + 1) * 1000UL / timer_clock;
     configuration->pulse = ((*(__IO uint32_t *)temp) + 1) * (timer_psc + 1) * 1000UL / timer_clock;
-
+    
     return RT_EOK;
 }
 
-static rt_err_t _pwm_set(TMR_T *tmr, struct rt_pwm_configuration *configuration)
+static rt_err_t drv_pwm_set(TMR_T *tmr, struct rt_pwm_configuration *configuration)
 {
     rt_uint32_t period, pulse;
     rt_uint64_t timer_clock, psc;
     rt_uint32_t channel = 0x04 * (configuration->channel - 1);
     uint32_t temp = (uint32_t)tmr;
-
-    timer_clock = _pwm_timer_clock_get(tmr);
+    
+    timer_clock = timer_clock_get(tmr);
 
     /* Convert nanosecond to frequency and duty cycle. */
     timer_clock /= 1000000UL;
@@ -548,7 +563,7 @@ static rt_err_t _pwm_set(TMR_T *tmr, struct rt_pwm_configuration *configuration)
     return RT_EOK;
 }
 
-static rt_err_t _pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
+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;
     TMR_T *tmr = (TMR_T *)device->parent.user_data;
@@ -558,37 +573,36 @@ static rt_err_t _pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
     case PWMN_CMD_ENABLE:
         configuration->complementary = RT_TRUE;
     case PWM_CMD_ENABLE:
-        return _pwm_enable(tmr, configuration, RT_TRUE);
+        return drv_pwm_enable(tmr, configuration, RT_TRUE);
     case PWMN_CMD_DISABLE:
         configuration->complementary = RT_FALSE;
     case PWM_CMD_DISABLE:
-        return _pwm_enable(tmr, configuration, RT_FALSE);
+        return drv_pwm_enable(tmr, configuration, RT_FALSE);
     case PWM_CMD_SET:
-        return _pwm_set(tmr, configuration);
+        return drv_pwm_set(tmr, configuration);
     case PWM_CMD_GET:
-        return _pwm_get(tmr, configuration);
+        return drv_pwm_get(tmr, configuration);
     default:
         return RT_EINVAL;
     }
 }
 
-static const struct rt_pwm_ops _pwm_ops =
+static const struct rt_pwm_ops drv_pwm_ops =
 {
-    _pwm_control
+    drv_pwm_control
 };
 
 static int rt_hw_pwm_init(void)
 {
     rt_uint32_t i = 0;
     rt_err_t result = RT_EOK;
-    GPIO_Config_T gpio_config;
 
-    _pwm_channel_init(&gpio_config);
+    pwm_channel_init();
 
     for (i = 0; i < sizeof(pwm_config) / sizeof(pwm_config[0]); i++)
     {
         /* pwm init */
-        if (_pwm_hw_init(&pwm_config[i]) != RT_EOK)
+        if (apm32_pwm_hw_init(&pwm_config[i]) != RT_EOK)
         {
             LOG_E("%s init failed", pwm_config[i].name);
             return -RT_ERROR;
@@ -598,7 +612,7 @@ static int rt_hw_pwm_init(void)
             LOG_D("%s init success", pwm_config[i].name);
 
             /* register pwm device */
-            if (rt_device_pwm_register(&pwm_config[i].pwm_device, pwm_config[i].name, &_pwm_ops, pwm_config[i].tmr) == RT_EOK)
+            if (rt_device_pwm_register(&pwm_config[i].pwm_device, pwm_config[i].name, &drv_pwm_ops, pwm_config[i].tmr) == RT_EOK)
             {
                 LOG_D("%s register success", pwm_config[i].name);
             }

+ 76 - 31
project_0/libraries/Drivers/drv_rtc.c

@@ -7,6 +7,7 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include "board.h"
@@ -14,7 +15,7 @@
 
 #ifdef BSP_USING_ONCHIP_RTC
 
-#define LOG_TAG               "drv.rtc"
+#define DBG_TAG               "drv.rtc"
 #define DBG_LVL               DBG_INFO
 #include <rtdbg.h>
 
@@ -25,7 +26,7 @@
     #define  LSE_VALUE            ((uint32_t)32768)
 #endif
 
-#define DRV_RTC_TIME_OUT      0xFFF
+#define DRV_RTC_TIME_OUT      0xFFFFF
 
 static rt_rtc_dev_t apm32_rtc_dev;
 static rt_uint8_t rtc_init_flag = RESET;
@@ -35,17 +36,17 @@ static rt_uint8_t rtc_init_flag = RESET;
  *
  * @return   RT_EOK indicates successful initialize, other value indicates failed;
  */
-static rt_err_t _rtc_init(void)
+static rt_err_t apm32_rtc_init(void)
 {
     volatile rt_uint32_t counter = 0;
-
+    
     /* Enable RTC Clock */
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR);
-#elif APM32F40X
+#elif defined(SOC_SERIES_APM32F0) || defined(SOC_SERIES_APM32F4)
     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
 #endif
-
+    
     PMU_EnableBackupAccess();
 
     /* Config RTC clock */
@@ -60,6 +61,7 @@ static rt_err_t _rtc_init(void)
     }
     RCM_ConfigRTCCLK(RCM_RTCCLK_LSI);
 #else
+    RCM_DisableLSI();
     RCM_ConfigLSE(RCM_LSE_OPEN);
     while (!RCM_ReadStatusFlag(RCM_FLAG_LSERDY))
     {
@@ -69,12 +71,12 @@ static rt_err_t _rtc_init(void)
         }
     }
     RCM_ConfigRTCCLK(RCM_RTCCLK_LSE);
-#endif
+#endif /* BSP_RTC_USING_LSI */
 
     RCM_EnableRTCCLK();
     RTC_WaitForSynchro();
 
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
     counter = 0;
     while (!RTC_ReadStatusFlag(RTC_FLAG_OC))
     {
@@ -92,13 +94,29 @@ static rt_err_t _rtc_init(void)
     RTC_ConfigPrescaler(LSI_VALUE - 1);
 #else
     RTC_ConfigPrescaler(LSE_VALUE - 1);
-#endif
-#elif APM32F40X
+#endif /* BSP_RTC_USING_LSI */
+
+#elif defined(SOC_SERIES_APM32F4)
     RTC_EnableInit();
     RTC_Config_T rtcConfig;
     RTC_ConfigStructInit(&rtcConfig);
     RTC_Config(&rtcConfig);
-#endif
+    
+#elif defined(SOC_SERIES_APM32F0)
+    RTC_EnableInit();
+    RTC_Config_T rtcConfig;
+    RTC_ConfigStructInit(&rtcConfig);
+    
+#ifdef BSP_RTC_USING_LSI
+    rtcConfig.AsynchPrediv = 0x63;
+    rtcConfig.SynchPrediv  = 0x18F;
+#else
+    rtcConfig.AsynchPrediv = 0x7F;
+    rtcConfig.SynchPrediv  = 0x130;
+#endif /* BSP_RTC_USING_LSI */
+    RTC_Config(&rtcConfig);
+
+#endif /* SOC_SERIES_APM32F1 */
 
     if (!rtc_init_flag)
     {
@@ -107,13 +125,13 @@ static rt_err_t _rtc_init(void)
     return RT_EOK;
 }
 
-#ifdef APM32F10X_HD
+#if defined(SOC_SERIES_APM32F1)
 /**
  * @brief    This function will initialize the rtc on chip.
  *
  * @return   RT_EOK indicates successful initialize, other value indicates failed;
  */
-static rt_err_t _rtc_get_secs(void *args)
+static rt_err_t apm32_rtc_get_secs(void *args)
 {
     volatile rt_uint32_t counter = 0;
 
@@ -130,13 +148,13 @@ static rt_err_t _rtc_get_secs(void *args)
     return RT_EOK;
 }
 
-static rt_err_t _rtc_set_secs(void *args)
+static rt_err_t apm32_rtc_set_secs(void *args)
 {
     volatile rt_uint32_t counter = 0;
 
     if (!rtc_init_flag)
     {
-        _rtc_init();
+        apm32_rtc_init();
     }
 
     while (!RTC_ReadStatusFlag(RTC_FLAG_OC))
@@ -151,11 +169,19 @@ static rt_err_t _rtc_set_secs(void *args)
 
     return RT_EOK;
 }
-#elif APM32F40X
-static void get_rtc_timeval(struct timeval *tv)
+#elif defined(SOC_SERIES_APM32F0) || defined(SOC_SERIES_APM32F4)
+static rt_err_t apm32_rtc_get_timeval(void *args)
 {
+    struct timeval *tv = (struct timeval *) args;
+
+#if defined(SOC_SERIES_APM32F0)
+    RTC_TIME_T timeConfig;
+    RTC_DATE_T dateConfig;
+#elif defined(SOC_SERIES_APM32F4)
     RTC_TimeConfig_T timeConfig;
     RTC_DateConfig_T dateConfig;
+#endif
+
     struct tm tm_new = {0};
 
     RTC_ReadTime(RTC_FORMAT_BIN, &timeConfig);
@@ -169,17 +195,25 @@ static void get_rtc_timeval(struct timeval *tv)
     tm_new.tm_year = dateConfig.year + 100;
 
     tv->tv_sec = timegm(&tm_new);
+
+    return RT_EOK;
 }
 
-static rt_err_t set_rtc_timeval(time_t time_stamp)
+static rt_err_t set_rtc_time_stamp(time_t time_stamp)
 {
+#if defined(SOC_SERIES_APM32F0)
+    RTC_TIME_T timeConfig;
+    RTC_DATE_T dateConfig;
+#elif defined(SOC_SERIES_APM32F4)
     RTC_TimeConfig_T timeConfig;
     RTC_DateConfig_T dateConfig;
+#endif
+
     struct tm tm = {0};
 
     if (!rtc_init_flag)
     {
-        _rtc_init();
+        apm32_rtc_init();
     }
 
     gmtime_r(&time_stamp, &tm);
@@ -192,13 +226,21 @@ static rt_err_t set_rtc_timeval(time_t time_stamp)
     timeConfig.minutes = tm.tm_min ;
     timeConfig.hours   = tm.tm_hour;
     dateConfig.date    = tm.tm_mday;
+#if defined(SOC_SERIES_APM32F4)
+    dateConfig.month   = (RTC_MONTH_T)(tm.tm_mon + 1);
+    dateConfig.weekday = (RTC_WEEKDAY_T)(tm.tm_wday + 1);
+#else
     dateConfig.month   = tm.tm_mon + 1 ;
-    dateConfig.year    = tm.tm_year - 100;
     dateConfig.weekday = tm.tm_wday + 1;
+#endif
+    dateConfig.year    = tm.tm_year - 100;
 
     RTC_ConfigTime(RTC_FORMAT_BIN, &timeConfig);
     RTC_ConfigDate(RTC_FORMAT_BIN, &dateConfig);
 
+    /* wait for set time completed */
+    for (int i = 0; i < 0xFFFF; i++);
+
     return RT_EOK;
 }
 
@@ -207,20 +249,20 @@ static rt_err_t set_rtc_timeval(time_t time_stamp)
  *
  * @return   RT_EOK indicates successful initialize, other value indicates failed;
  */
-static rt_err_t _rtc_get_secs(void *args)
+static rt_err_t apm32_rtc_get_secs(void *args)
 {
     struct timeval tv;
-    get_rtc_timeval(&tv);
+    apm32_rtc_get_timeval(&tv);
     *(rt_uint32_t *) args = tv.tv_sec;
 
     return RT_EOK;
 }
 
-static rt_err_t _rtc_set_secs(void *args)
+static rt_err_t apm32_rtc_set_secs(void *args)
 {
     rt_err_t result = RT_EOK;
 
-    if (set_rtc_timeval(*(rt_uint32_t *)args))
+    if (set_rtc_time_stamp(*(rt_uint32_t *)args))
     {
         result = -RT_ERROR;
     }
@@ -229,14 +271,18 @@ static rt_err_t _rtc_set_secs(void *args)
 }
 #endif
 
-static const struct rt_rtc_ops _rtc_ops =
+static const struct rt_rtc_ops apm32_rtc_ops =
 {
-    _rtc_init,
-    _rtc_get_secs,
-    _rtc_set_secs,
+    apm32_rtc_init,
+    apm32_rtc_get_secs,
+    apm32_rtc_set_secs,
     RT_NULL,
     RT_NULL,
+#if defined(SOC_SERIES_APM32F0) || defined(SOC_SERIES_APM32F4)
+    apm32_rtc_get_timeval,
+#else
     RT_NULL,
+#endif
     RT_NULL,
 };
 
@@ -249,7 +295,7 @@ static int rt_hw_rtc_init(void)
 {
     rt_err_t result = RT_EOK;
 
-    apm32_rtc_dev.ops = &_rtc_ops;
+    apm32_rtc_dev.ops = &apm32_rtc_ops;
 
     if (rt_hw_rtc_register(&apm32_rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR, RT_NULL) != RT_EOK)
     {
@@ -263,7 +309,6 @@ static int rt_hw_rtc_init(void)
 
     return result;
 }
-
 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
 
 #endif /* BSP_USING_ONCHIP_RTC */

+ 22 - 22
project_0/libraries/Drivers/drv_soft_i2c.c

@@ -13,7 +13,7 @@
 
 #ifdef RT_USING_I2C
 
-#define LOG_TAG              "drv.i2c"
+#define DBG_TAG              "drv.i2c"
 #define DBG_LVL               DBG_INFO
 #include <rtdbg.h>
 
@@ -43,28 +43,28 @@ static const struct apm32_soft_i2c_config soft_i2c_config[] =
         BSP_I2C1_SCL_PIN,
         BSP_I2C1_SDA_PIN,
         "i2c1"
-    }
+    },
 #endif
 #ifdef BSP_USING_I2C2
     {
         BSP_I2C2_SCL_PIN,
         BSP_I2C2_SDA_PIN,
         "i2c2"
-    }
+    },
 #endif
 #ifdef BSP_USING_I2C3
     {
         BSP_I2C3_SCL_PIN,
         BSP_I2C3_SDA_PIN,
         "i2c3"
-    }
+    },
 #endif
 #ifdef BSP_USING_I2C4
     {
         BSP_I2C4_SCL_PIN,
         BSP_I2C4_SDA_PIN,
         "i2c4"
-    }
+    },
 #endif
 };
 
@@ -75,7 +75,7 @@ static struct apm32_soft_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_c
  *
  * @param    i2c is a pointer to the object of soft i2c.
  */
-static void _soft_i2c_gpio_init(struct apm32_soft_i2c *i2c)
+static void apm32_soft_i2c_gpio_init(struct apm32_soft_i2c *i2c)
 {
     struct apm32_soft_i2c_config *cfg = (struct apm32_soft_i2c_config *)i2c->ops.data;
 
@@ -93,7 +93,7 @@ static void _soft_i2c_gpio_init(struct apm32_soft_i2c *i2c)
  *
  * @param    state is the level of sda pin.
  */
-static void _soft_i2c_set_sda(void *data, rt_int32_t state)
+static void apm32_soft_i2c_set_sda(void *data, rt_int32_t state)
 {
     struct apm32_soft_i2c_config *cfg = (struct apm32_soft_i2c_config *)data;
 
@@ -107,7 +107,7 @@ static void _soft_i2c_set_sda(void *data, rt_int32_t state)
  *
  * @param    state is the level of scl pin.
  */
-static void _soft_i2c_set_scl(void *data, rt_int32_t state)
+static void apm32_soft_i2c_set_scl(void *data, rt_int32_t state)
 {
     struct apm32_soft_i2c_config *cfg = (struct apm32_soft_i2c_config *)data;
 
@@ -119,7 +119,7 @@ static void _soft_i2c_set_scl(void *data, rt_int32_t state)
  *
  * @param    data is a pointer to the i2c config class.
  */
-static rt_int32_t _soft_i2c_get_sda(void *data)
+static rt_int32_t apm32_soft_i2c_get_sda(void *data)
 {
     struct apm32_soft_i2c_config *cfg = (struct apm32_soft_i2c_config *)data;
     return rt_pin_read(cfg->sda_pin);
@@ -130,7 +130,7 @@ static rt_int32_t _soft_i2c_get_sda(void *data)
  *
  * @param    data is a pointer to the i2c config class.
  */
-static rt_int32_t _soft_i2c_get_scl(void *data)
+static rt_int32_t apm32_soft_i2c_get_scl(void *data)
 {
     struct apm32_soft_i2c_config *cfg = (struct apm32_soft_i2c_config *)data;
     return rt_pin_read(cfg->scl_pin);
@@ -141,7 +141,7 @@ static rt_int32_t _soft_i2c_get_scl(void *data)
  *
  * @param    us is the microseconds to delay.
  */
-static void _soft_i2c_udelay(rt_uint32_t us)
+static void apm32_soft_i2c_udelay(rt_uint32_t us)
 {
     rt_uint32_t count_old = SysTick->VAL;
     rt_uint32_t count_now;
@@ -183,9 +183,9 @@ static rt_err_t apm32_i2c_bus_unlock(const struct apm32_soft_i2c_config *cfg)
         while (i++ < 9)
         {
             rt_pin_write(cfg->scl_pin, PIN_HIGH);
-            _soft_i2c_udelay(100);
+            apm32_soft_i2c_udelay(100);
             rt_pin_write(cfg->scl_pin, PIN_LOW);
-            _soft_i2c_udelay(100);
+            apm32_soft_i2c_udelay(100);
         }
     }
     if (PIN_LOW == rt_pin_read(cfg->sda_pin))
@@ -199,11 +199,11 @@ static rt_err_t apm32_i2c_bus_unlock(const struct apm32_soft_i2c_config *cfg)
 static const struct rt_i2c_bit_ops apm32_bit_ops_default =
 {
     .data     = RT_NULL,
-    .set_sda  = _soft_i2c_set_sda,
-    .set_scl  = _soft_i2c_set_scl,
-    .get_sda  = _soft_i2c_get_sda,
-    .get_scl  = _soft_i2c_get_scl,
-    .udelay   = _soft_i2c_udelay,
+    .set_sda  = apm32_soft_i2c_set_sda,
+    .set_scl  = apm32_soft_i2c_set_scl,
+    .get_sda  = apm32_soft_i2c_get_sda,
+    .get_scl  = apm32_soft_i2c_get_scl,
+    .udelay   = apm32_soft_i2c_udelay,
     .delay_us = 1,
     .timeout  = 100
 };
@@ -223,7 +223,7 @@ int rt_hw_i2c_init(void)
         i2c_obj[i].ops = apm32_bit_ops_default;
         i2c_obj[i].ops.data = (void *)&soft_i2c_config[i];
         i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
-        _soft_i2c_gpio_init(&i2c_obj[i]);
+        apm32_soft_i2c_gpio_init(&i2c_obj[i]);
 
         result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
 
@@ -231,10 +231,10 @@ int rt_hw_i2c_init(void)
 
         apm32_i2c_bus_unlock(&soft_i2c_config[i]);
 
-        LOG_D("software simulation %s init done, pin scl: %s, pin sda: %s",
+        LOG_D("software simulation %s init done, pin scl: %d, pin sda: %d",
               soft_i2c_config[i].bus_name,
-              soft_i2c_config[i].scl_pin_name,
-              soft_i2c_config[i].sda_pin_name);
+              soft_i2c_config[i].scl_pin,
+              soft_i2c_config[i].sda_pin);
     }
 
     return RT_EOK;

+ 175 - 165
project_0/libraries/Drivers/drv_spi.c

@@ -7,34 +7,128 @@
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
  * 2022-07-15     Aligagago         add apm32F4 serie MCU support
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include "drv_spi.h"
 
+//#define DRV_DEBUG
 #define LOG_TAG               "drv.spi"
-#define DBG_LVL               DBG_INFO
-#include <rtdbg.h>
+#include "drv_log.h"
 
 #if defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2) || defined(BSP_USING_SPI3)
 
-static rt_err_t _spi_configure(struct rt_spi_device *spi_drv, struct rt_spi_configuration *cfg)
+static struct apm32_spi_config spi_config[] = {
+#ifdef BSP_USING_SPI1
+    {SPI1, "spi1"},
+#endif
+
+#ifdef BSP_USING_SPI2
+    {SPI2, "spi2"},
+#endif
+
+#ifdef BSP_USING_SPI3
+    {SPI3, "spi3"},
+#endif
+};
+
+static struct apm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};
+
+/**
+  * 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, GPIO_T *cs_gpiox, uint16_t cs_gpio_pin)
 {
-    RT_ASSERT(spi_drv != RT_NULL);
+    RT_ASSERT(bus_name != RT_NULL);
+    RT_ASSERT(device_name != RT_NULL);
+
+    rt_err_t result;
+    struct rt_spi_device *spi_device;
+    struct apm32_spi_cs *cs_pin;
+    GPIO_Config_T GPIO_InitStructure;
+    
+    /* initialize the cs pin && select the slave */
+#if defined(SOC_SERIES_APM32F0)
+    GPIO_ConfigStructInit(&GPIO_InitStructure);
+    GPIO_InitStructure.pin = cs_gpio_pin;
+    GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
+    GPIO_InitStructure.mode = GPIO_MODE_OUT;
+    GPIO_InitStructure.outtype = GPIO_OUT_TYPE_PP;
+    GPIO_InitStructure.pupd = GPIO_PUPD_NO;
+    GPIO_Config(cs_gpiox, &GPIO_InitStructure);
+    GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, Bit_SET);
+#elif defined(SOC_SERIES_APM32F1)
+    GPIO_ConfigStructInit(&GPIO_InitStructure);
+    GPIO_InitStructure.pin = cs_gpio_pin;
+    GPIO_InitStructure.mode = GPIO_MODE_OUT_PP;
+    GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
+    GPIO_Config(cs_gpiox, &GPIO_InitStructure);
+    GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, BIT_SET);
+#elif defined(SOC_SERIES_APM32F4)
+    GPIO_ConfigStructInit(&GPIO_InitStructure);
+    GPIO_InitStructure.pin = cs_gpio_pin;
+    GPIO_InitStructure.speed = GPIO_SPEED_100MHz;
+    GPIO_InitStructure.mode = GPIO_MODE_OUT;
+    GPIO_InitStructure.otype = GPIO_OTYPE_PP;
+    GPIO_InitStructure.pupd = GPIO_PUPD_NOPULL;
+    GPIO_Config(cs_gpiox, &GPIO_InitStructure);
+    GPIO_WriteBitValue(cs_gpiox, cs_gpio_pin, BIT_SET);
+#endif
+
+    /* 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);
+    cs_pin = (struct apm32_spi_cs *)rt_malloc(sizeof(struct apm32_spi_cs));
+    RT_ASSERT(cs_pin != RT_NULL);
+    cs_pin->GPIOx = cs_gpiox;
+    cs_pin->GPIO_Pin = cs_gpio_pin;
+    result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
+
+    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;
+}
+
+static rt_err_t apm32_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
+{
+    RT_ASSERT(device != RT_NULL);
     RT_ASSERT(cfg != RT_NULL);
+    
     SPI_Config_T hw_spi_config;
-    SPI_T *spi = (SPI_T *)spi_drv->bus->parent.user_data;
+    
+    struct rt_spi_bus * apm32_spi_bus = (struct rt_spi_bus *)device->bus;
+    struct apm32_spi *spi_device = (struct apm32_spi *)apm32_spi_bus->parent.user_data;
+    SPI_T *spi = spi_device->config->spi_x;
+    
     uint32_t hw_spi_apb_clock;
 #if (DBG_LVL == DBG_LOG)
     uint32_t hw_spi_sys_clock = RCM_ReadSYSCLKFreq();
 #endif
+    
+    /* apm32 spi gpio init and enable clock */
+    extern void apm32_msp_spi_init(void *Instance);
+    apm32_msp_spi_init(spi);
 
+    /* apm32 spi init */
     hw_spi_config.mode = (cfg->mode & RT_SPI_SLAVE) ? SPI_MODE_SLAVE : SPI_MODE_MASTER;
     hw_spi_config.direction = (cfg->mode & RT_SPI_3WIRE) ? SPI_DIRECTION_1LINE_RX : SPI_DIRECTION_2LINES_FULLDUPLEX;
     hw_spi_config.phase = (cfg->mode & RT_SPI_CPHA) ? SPI_CLKPHA_2EDGE : SPI_CLKPHA_1EDGE;
     hw_spi_config.polarity = (cfg->mode & RT_SPI_CPOL) ? SPI_CLKPOL_HIGH : SPI_CLKPOL_LOW;
+#if defined(SOC_SERIES_APM32F0)
+    hw_spi_config.slaveSelect = (cfg->mode & RT_SPI_NO_CS) ? SPI_SSC_DISABLE : SPI_SSC_ENABLE;
+    hw_spi_config.firstBit = (cfg->mode & RT_SPI_MSB) ? SPI_FIRST_BIT_MSB : SPI_FIRST_BIT_LSB;
+#else
     hw_spi_config.nss = (cfg->mode & RT_SPI_NO_CS) ? SPI_NSS_HARD : SPI_NSS_SOFT;
     hw_spi_config.firstBit = (cfg->mode & RT_SPI_MSB) ? SPI_FIRSTBIT_MSB : SPI_FIRSTBIT_LSB;
-
+#endif
+    
     if (cfg->data_width == 8)
     {
         hw_spi_config.length = SPI_DATA_LENGTH_8B;
@@ -48,7 +142,18 @@ static rt_err_t _spi_configure(struct rt_spi_device *spi_drv, struct rt_spi_conf
         return RT_EIO;
     }
 
-    RCM_ReadPCLKFreq(NULL, &hw_spi_apb_clock);
+#if defined(SOC_SERIES_APM32F0)
+    hw_spi_apb_clock = RCM_ReadPCLKFreq();
+#else
+    if (spi == SPI1)
+    {
+        RCM_ReadPCLKFreq(NULL, &hw_spi_apb_clock);
+    }
+    else
+    {
+        RCM_ReadPCLKFreq(&hw_spi_apb_clock, NULL);
+    }
+#endif
 
     if (cfg->max_hz >= hw_spi_apb_clock / 2)
     {
@@ -80,32 +185,46 @@ static rt_err_t _spi_configure(struct rt_spi_device *spi_drv, struct rt_spi_conf
     }
     else
     {
-        /*  min prescaler 256 */
+        /* min prescaler 256 */
         hw_spi_config.baudrateDiv = SPI_BAUDRATE_DIV_256;
     }
 
     LOG_D("sys freq: %d, pclk2 freq: %d, SPI limiting freq: %d, BaudRatePrescaler: %d",
           hw_spi_sys_clock, hw_spi_apb_clock, cfg->max_hz, hw_spi_config.baudrateDiv);
-
+    
+#if defined(SOC_SERIES_APM32F0)
+    SPI_DisableCRC(spi);
+    SPI_EnableSSoutput(spi);
+    SPI_ConfigFIFOThreshold(spi, SPI_RXFIFO_QUARTER);
+#endif
+    
     SPI_Config(spi, &hw_spi_config);
     SPI_Enable(spi);
 
     return RT_EOK;
 }
 
-static rt_uint32_t _spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
+static rt_uint32_t apm32_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
 {
     RT_ASSERT(device != NULL);
     RT_ASSERT(message != NULL);
 
-    rt_base_t cs_pin = (rt_base_t)device->parent.user_data;
-    SPI_T *spi = (SPI_T *)device->bus->parent.user_data;
     struct rt_spi_configuration *config = &device->config;
+    
+    struct apm32_spi_cs *cs = device->parent.user_data;
+    
+    struct rt_spi_bus * apm32_spi_bus = (struct rt_spi_bus *)device->bus;
+    struct apm32_spi *spi_device = (struct apm32_spi *)apm32_spi_bus->parent.user_data;
+    SPI_T *spi = spi_device->config->spi_x;
 
     /* take CS */
     if (message->cs_take)
     {
-        rt_pin_write(cs_pin, PIN_LOW);
+#if defined(SOC_SERIES_APM32F0)
+        GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, (GPIO_BSRET_T)RESET);
+#else
+        GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, RESET);
+#endif
         LOG_D("spi take cs\n");
     }
 
@@ -126,16 +245,24 @@ static rt_uint32_t _spi_xfer(struct rt_spi_device *device, struct rt_spi_message
                 data = *send_ptr++;
             }
 
+#if defined(SOC_SERIES_APM32F0)
+            /* Wait until the transmit buffer is empty */
+            while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
+            SPI_TxData8(spi, data);
+    
+            /* Wait until a data is received */
+            while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
+            data = SPI_RxData8(spi);
+#else
             /* Wait until the transmit buffer is empty */
             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
-
             SPI_I2S_TxData(spi, data);
 
             /* Wait until a data is received */
             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
-
             data = SPI_I2S_RxData(spi);
-
+#endif
+            
             if (recv_ptr != RT_NULL)
             {
                 *recv_ptr++ = data;
@@ -157,17 +284,27 @@ static rt_uint32_t _spi_xfer(struct rt_spi_device *device, struct rt_spi_message
             {
                 data = *send_ptr++;
             }
-
-            /*Wait until the transmit buffer is empty */
+            
+#if defined(SOC_SERIES_APM32F0)
+            /* Wait until the transmit buffer is empty */
+            while (SPI_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
+            SPI_I2S_TxData16(spi, data);
+    
+            /* Wait until a data is received */
+            while (SPI_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
+            data = SPI_I2S_RxData16(spi);
+#else
+            /* Wait until the transmit buffer is empty */
             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_TXBE) == RESET);
             /* Send the byte */
             SPI_I2S_TxData(spi, data);
 
-            /*Wait until a data is received */
+            /* Wait until a data is received */
             while (SPI_I2S_ReadStatusFlag(spi, SPI_FLAG_RXBNE) == RESET);
             /* Get the received data */
             data = SPI_I2S_RxData(spi);
-
+#endif
+            
             if (recv_ptr != RT_NULL)
             {
                 *recv_ptr++ = data;
@@ -178,164 +315,37 @@ static rt_uint32_t _spi_xfer(struct rt_spi_device *device, struct rt_spi_message
     /* release CS */
     if (message->cs_release)
     {
-        rt_pin_write(cs_pin, PIN_HIGH);
+#if defined(SOC_SERIES_APM32F0)
+        GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, (GPIO_BSRET_T)SET);
+#else
+        GPIO_WriteBitValue(cs->GPIOx, cs->GPIO_Pin, SET);
+#endif
         LOG_D("spi release cs\n");
     }
 
     return message->length;
 };
 
-static const struct rt_spi_ops _spi_ops =
+static const struct rt_spi_ops apm32_spi_ops =
 {
-    _spi_configure,
-    _spi_xfer
+    apm32_spi_configure,
+    apm32_spi_xfer
 };
 
 static int rt_hw_spi_init(void)
 {
-    int result = 0;
-    GPIO_Config_T gpio_config;
-
-#ifdef APM32F10X_HD
-#ifdef BSP_USING_SPI1
-    static struct rt_spi_bus spi_bus1;
-    spi_bus1.parent.user_data = (void *)SPI1;
-
-    result = rt_spi_bus_register(&spi_bus1, "spi1", &_spi_ops);
-
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);
-
-    /* SPI1_SCK(PA5)  SPI1_MOSI(PA7) */
-    gpio_config.mode = GPIO_MODE_AF_PP;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = (GPIO_PIN_5 | GPIO_PIN_7);
-    GPIO_Config(GPIOA, &gpio_config);
-    /* SPI1_MISO(PA6) */
-    gpio_config.mode = GPIO_MODE_IN_FLOATING;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = GPIO_PIN_6;
-    GPIO_Config(GPIOA, &gpio_config);
-#endif
-
-#ifdef BSP_USING_SPI2
-    static struct rt_spi_bus spi_bus2;
-    spi_bus2.parent.user_data = (void *)SPI2;
-
-    result = rt_spi_bus_register(&spi_bus2, "spi2", &_spi_ops);
-
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);
-    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI2);
-
-    /* SPI2_SCK(PB13)  SPI2_MOSI(PB15) */
-    gpio_config.mode = GPIO_MODE_AF_PP;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = (GPIO_PIN_13 | GPIO_PIN_15);
-    GPIO_Config(GPIOB, &gpio_config);
-    /* SPI2_MISO(PB14) */
-    gpio_config.mode = GPIO_MODE_IN_FLOATING;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = GPIO_PIN_14;
-    GPIO_Config(GPIOB, &gpio_config);
-#endif
-
-#ifdef BSP_USING_SPI3
-    static struct rt_spi_bus spi_bus3;
-    spi_bus3.parent.user_data = (void *)SPI3;
-
-    result = rt_spi_bus_register(&spi_bus3, "spi3", &_spi_ops);
-
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOB);
-    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI3);
-
-    /* SPI3_SCK(PB3)  SPI3_MOSI(PB5) */
-    gpio_config.mode = GPIO_MODE_AF_PP;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = (GPIO_PIN_3 | GPIO_PIN_5);
-    GPIO_Config(GPIOB, &gpio_config);
-    /* SPI3_MISO(PB4) */
-    gpio_config.mode = GPIO_MODE_IN_FLOATING;
-    gpio_config.speed = GPIO_SPEED_50MHz;
-    gpio_config.pin = GPIO_PIN_4;
-    GPIO_Config(GPIOB, &gpio_config);
-#endif
-#elif APM32F40X
-#ifdef BSP_USING_SPI1
-    static struct rt_spi_bus spi_bus1;
-    spi_bus1.parent.user_data = (void *)SPI1;
-
-    result = rt_spi_bus_register(&spi_bus1, "spi1", &_spi_ops);
-
-    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
-    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SPI1);
-
-    /* Config SPI1 PinAF */
-    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_4, GPIO_AF_SPI1);
-    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_5, GPIO_AF_SPI1);
-    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_6, GPIO_AF_SPI1);
-    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_SPI1);
-
-    /* SPI1_NSS(PA4) SPI1_SCK(PA5) SPI1_MISO(PA6) SPI1_MOSI(PA7) */
-    gpio_config.mode = GPIO_MODE_AF;
-    gpio_config.speed = GPIO_SPEED_100MHz;
-    gpio_config.otype = GPIO_OTYPE_PP;
-    gpio_config.pupd = GPIO_PUPD_NOPULL;
-    gpio_config.pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
-    GPIO_Config(GPIOA, &gpio_config);
-#endif
+    rt_err_t result;
+    
+    for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
+    {
+        spi_bus_obj[i].config = &spi_config[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_config[i].spi_bus_name, &apm32_spi_ops);
+        RT_ASSERT(result == RT_EOK);
 
-#ifdef BSP_USING_SPI2
-    static struct rt_spi_bus spi_bus2;
-    spi_bus2.parent.user_data = (void *)SPI2;
-
-    result = rt_spi_bus_register(&spi_bus2, "spi2", &_spi_ops);
-
-    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
-    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI2);
-
-    /* Config SPI2 PinAF */
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_12, GPIO_AF_SPI2);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_13, GPIO_AF_SPI2);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_14, GPIO_AF_SPI2);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_15, GPIO_AF_SPI2);
-
-    /* SPI2_NSS(PB12) SPI2_SCK(PB13) SPI2_MISO(PB14) SPI2_MOSI(PB15) */
-    gpio_config.mode = GPIO_MODE_AF;
-    gpio_config.speed = GPIO_SPEED_100MHz;
-    gpio_config.otype = GPIO_OTYPE_PP;
-    gpio_config.pupd = GPIO_PUPD_NOPULL;
-    gpio_config.pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
-    GPIO_Config(GPIOB, &gpio_config);
-#endif
+        LOG_D("%s bus init done", spi_config[i].spi_bus_name);
+    }
 
-#ifdef BSP_USING_SPI3
-    static struct rt_spi_bus spi_bus3;
-    spi_bus3.parent.user_data = (void *)SPI3;
-
-    result = rt_spi_bus_register(&spi_bus3, "spi3", &_spi_ops);
-
-    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
-    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
-    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_SPI3);
-
-    /* Config SPI3 PinAF */
-    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_4, GPIO_AF_SPI3);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_3, GPIO_AF_SPI3);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_4, GPIO_AF_SPI3);
-    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_5, GPIO_AF_SPI3);
-
-    /* SPI3_SCK(PB3) SPI3_MISO(PB4) SPI3_MOSI(PB5) */
-    gpio_config.mode = GPIO_MODE_AF;
-    gpio_config.speed = GPIO_SPEED_100MHz;
-    gpio_config.otype = GPIO_OTYPE_PP;
-    gpio_config.pupd = GPIO_PUPD_NOPULL;
-    gpio_config.pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
-    GPIO_Config(GPIOB, &gpio_config);
-    /* SPI3_NSS(PA4) */
-    gpio_config.pin = GPIO_PIN_4;
-    GPIO_Config(GPIOA, &gpio_config);
-#endif
-#endif
     return result;
 }
 INIT_BOARD_EXPORT(rt_hw_spi_init);

+ 16 - 0
project_0/libraries/Drivers/drv_spi.h

@@ -12,6 +12,20 @@
 #define __DRV_SPI_H__
 
 #include "board.h"
+#include <rtthread.h>
+#include <drivers/spi.h>
+
+struct apm32_spi_config
+{
+    SPI_T *spi_x;
+    char *spi_bus_name;
+};
+
+struct apm32_spi
+{
+    struct apm32_spi_config *config;
+    struct rt_spi_bus spi_bus;
+};
 
 struct apm32_spi_cs
 {
@@ -19,4 +33,6 @@ struct apm32_spi_cs
     uint16_t GPIO_Pin;
 };
 
+rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, GPIO_T *cs_gpiox, uint16_t cs_gpio_pin);
+
 #endif /*__DRV_SPI_H__ */

+ 209 - 20
project_0/libraries/Drivers/drv_usart.c

@@ -6,14 +6,16 @@
  * Change Logs:
  * Date           Author       Notes
  * 2020-08-20     Abbcc        first version
+ * 2022-12-26     luobeihai    add apm32F0 serie MCU support
  */
 
 #include "board.h"
 #include "drv_usart.h"
 
-
 #ifdef RT_USING_SERIAL
-#if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2)
+#if !defined(BSP_USING_UART1) && !defined(BSP_USING_UART2) && \
+    !defined(BSP_USING_UART3) && !defined(BSP_USING_UART4) && \
+    !defined(BSP_USING_UART5) && !defined(BSP_USING_UART6)
     #error "Please define at least one BSP_USING_UARTx"
     /* this driver can be disabled at menuconfig -> RT-Thread Components -> Device Drivers */
 #endif
@@ -34,6 +36,18 @@ enum
 #ifdef BSP_USING_UART2
     UART2_INDEX,
 #endif
+#ifdef BSP_USING_UART3
+    UART3_INDEX,
+#endif
+#ifdef BSP_USING_UART4
+    UART4_INDEX,
+#endif
+#ifdef BSP_USING_UART5
+    UART5_INDEX,
+#endif
+#ifdef BSP_USING_UART6
+    UART6_INDEX,
+#endif
 };
 
 static struct apm32_usart usart_config[] =
@@ -52,9 +66,39 @@ static struct apm32_usart usart_config[] =
         USART2_IRQn,
     },
 #endif
+#if defined(SOC_SERIES_APM32F1) || defined(SOC_SERIES_APM32F4)
+#ifdef BSP_USING_UART3
+    {
+        "uart3",
+        USART3,
+        USART3_IRQn,
+    },
+#endif
+#ifdef BSP_USING_UART4
+    {
+        "uart4",
+        UART4,
+        UART4_IRQn,
+    },
+#endif
+#ifdef BSP_USING_UART5
+    {
+        "uart5",
+        UART5,
+        UART5_IRQn,
+    },
+#endif
+#ifdef BSP_USING_UART6
+    {
+        "uart6",
+        USART6,
+        USART6_IRQn,
+    },
+#endif
+#endif
 };
 
-static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+static rt_err_t apm32_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
 {
     USART_Config_T USART_ConfigStruct;
     RT_ASSERT(serial != RT_NULL);
@@ -64,10 +108,38 @@ static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_c
 
     apm32_usart_init();
 
-    USART_ConfigStruct.baudRate = cfg->baud_rate;;
-    USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
+    USART_ConfigStruct.baudRate = cfg->baud_rate;
     USART_ConfigStruct.mode = USART_MODE_TX_RX;
     USART_ConfigStruct.parity = USART_PARITY_NONE;
+    
+#if defined(SOC_SERIES_APM32F0)
+    switch (cfg->flowcontrol)
+    {
+    case RT_SERIAL_FLOWCONTROL_NONE:
+
+        USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
+        break;
+    case RT_SERIAL_FLOWCONTROL_CTSRTS:
+        USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_RTS_CTS;
+        break;
+    default:
+        USART_ConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
+        break;
+    }
+#else
+    switch (cfg->flowcontrol)
+    {
+    case RT_SERIAL_FLOWCONTROL_NONE:
+        USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
+        break;
+    case RT_SERIAL_FLOWCONTROL_CTSRTS:
+        USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_RTS_CTS;
+        break;
+    default:
+        USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
+        break;
+    }
+#endif
 
     switch (cfg->data_bits)
     {
@@ -120,7 +192,7 @@ static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_c
     return RT_EOK;
 }
 
-static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+static rt_err_t apm32_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
 {
     struct apm32_usart *usart;
 
@@ -129,6 +201,30 @@ static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *ar
     usart = (struct apm32_usart *) serial->parent.user_data;
     RT_ASSERT(usart != RT_NULL);
 
+#if defined(SOC_SERIES_APM32F0)
+    switch (cmd)
+    {
+    /* disable interrupt */
+    case RT_DEVICE_CTRL_CLR_INT:
+
+        /* disable rx irq */
+        NVIC_DisableIRQRequest(usart->irq_type);
+
+        /* disable interrupt */
+        USART_DisableInterrupt(usart->usartx, USART_INT_RXBNEIE);
+
+        break;
+
+    /* enable interrupt */
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        NVIC_EnableIRQRequest(usart->irq_type, 1);
+
+        /* enable interrupt */
+        USART_EnableInterrupt(usart->usartx, USART_INT_RXBNEIE);
+        break;
+    }
+#else
     switch (cmd)
     {
     /* disable interrupt */
@@ -150,12 +246,12 @@ static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *ar
         /* enable interrupt */
         USART_EnableInterrupt(usart->usartx, USART_INT_RXBNE);
         break;
-
     }
+#endif
     return RT_EOK;
 }
 
-static int _uart_putc(struct rt_serial_device *serial, char c)
+static int apm32_uart_putc(struct rt_serial_device *serial, char c)
 {
     struct apm32_usart *usart;
     RT_ASSERT(serial != RT_NULL);
@@ -171,7 +267,7 @@ static int _uart_putc(struct rt_serial_device *serial, char c)
     return 1;
 }
 
-static int _uart_getc(struct rt_serial_device *serial)
+static int apm32_uart_getc(struct rt_serial_device *serial)
 {
     int ch;
     struct apm32_usart *usart;
@@ -197,33 +293,75 @@ static void usart_isr(struct rt_serial_device *serial)
 {
     struct apm32_usart *usart;
 
-    RT_ASSERT(serial != RT_NULL);
     RT_ASSERT(serial != RT_NULL);
     usart = (struct apm32_usart *) serial->parent.user_data;
 
     RT_ASSERT(usart != RT_NULL);
 
     /* UART in mode Receiver */
+#if defined(SOC_SERIES_APM32F0)
+    if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
+            (USART_ReadIntFlag(usart->usartx, USART_INT_FLAG_RXBNE) != RESET))
+#else
     if ((USART_ReadStatusFlag(usart->usartx, USART_FLAG_RXBNE) != RESET) &&
             (USART_ReadIntFlag(usart->usartx, USART_INT_RXBNE) != RESET))
+#endif
     {
         rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
-        USART_ClearStatusFlag(usart->usartx, USART_FLAG_RXBNE);
-        USART_ClearIntFlag(usart->usartx, USART_INT_RXBNE);
     }
-
     else
     {
+#if defined(SOC_SERIES_APM32F0)
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NEF) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_NEF);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FEF) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_FEF);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PEF) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_PEF);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTSF) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTSF);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBDF) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBDF);
+        }
+#else
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_OVRE) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_OVRE);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_NE) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_NE);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_FE) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_FE);
+        }
+        if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_PE) != RESET)
+        {
+            USART_ClearStatusFlag(usart->usartx, USART_FLAG_PE);
+        }
         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_CTS) != RESET)
         {
             USART_ClearStatusFlag(usart->usartx, USART_FLAG_CTS);
         }
-
         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_LBD) != RESET)
         {
             USART_ClearStatusFlag(usart->usartx, USART_FLAG_LBD);
         }
-
+#endif
         if (USART_ReadStatusFlag(usart->usartx, USART_FLAG_TXBE) != RESET)
         {
             USART_ClearStatusFlag(usart->usartx, USART_FLAG_TXBE);
@@ -256,15 +394,66 @@ void USART2_IRQHandler(void)
     /* leave interrupt */
     rt_interrupt_leave();
 }
-
 #endif /* BSP_USING_UART2 */
 
+#if defined(BSP_USING_UART3)
+void USART3_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    usart_isr(&(usart_config[UART3_INDEX].serial));
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* BSP_USING_UART3 */
+
+#if defined(BSP_USING_UART4)
+void UART4_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    usart_isr(&(usart_config[UART4_INDEX].serial));
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* BSP_USING_UART4 */
+
+#if defined(BSP_USING_UART5)
+void UART5_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    usart_isr(&(usart_config[UART5_INDEX].serial));
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* BSP_USING_UART5 */
+
+#if defined(BSP_USING_UART6)
+void USART6_IRQHandler(void)
+{
+    /* enter interrupt */
+    rt_interrupt_enter();
+
+    usart_isr(&(usart_config[UART6_INDEX].serial));
+
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+#endif /* BSP_USING_UART6 */
+
 static const struct rt_uart_ops apm32_usart_ops =
 {
-    .configure = _uart_configure,
-    .control = _uart_control,
-    .putc = _uart_putc,
-    .getc = _uart_getc,
+    .configure = apm32_uart_configure,
+    .control = apm32_uart_control,
+    .putc = apm32_uart_putc,
+    .getc = apm32_uart_getc,
     .dma_transmit = RT_NULL
 };
 

+ 18 - 6
project_0/libraries/Drivers/drv_wdt.c

@@ -6,6 +6,7 @@
  * Change Logs:
  * Date           Author            Notes
  * 2022-03-04     stevetong459      first version
+ * 2022-12-26     luobeihai         add apm32F0 serie MCU support
  */
 
 #include <board.h>
@@ -33,7 +34,7 @@ typedef struct
 
 static apm32_wdt_t wdt_config;
 
-static rt_err_t _iwdt_init(rt_watchdog_t *wdt)
+static rt_err_t apm32_iwdt_init(rt_watchdog_t *wdt)
 {
     rt_uint32_t counter = 0;
 
@@ -54,7 +55,11 @@ static rt_err_t _iwdt_init(rt_watchdog_t *wdt)
           wdt_config.min_threshold,
           wdt_config.max_threshold);
 
+#if defined(SOC_SERIES_APM32F0)
+    while (IWDT_ReadStatusFlag(IWDT_FLAG_DIVU))
+#else
     while (IWDT_ReadStatusFlag(IWDT_FLAG_PSCU))
+#endif
     {
         if (++counter > DRV_WDT_TIME_OUT)
         {
@@ -62,8 +67,15 @@ static rt_err_t _iwdt_init(rt_watchdog_t *wdt)
             return -RT_ERROR;
         }
     }
+    
     IWDT_EnableWriteAccess();
+    
+#if defined(SOC_SERIES_APM32F0)
+    IWDT_ConfigDivider(IWDT_DIV_256);
+#else
     IWDT_ConfigDivider(IWDT_DIVIDER_256);
+#endif
+    
     IWDT_DisableWriteAccess();
 
     return RT_EOK;
@@ -76,7 +88,7 @@ static rt_err_t _iwdt_init(rt_watchdog_t *wdt)
  *
  * @return   RT_EOK indicates successful , other value indicates failed.
  */
-static rt_err_t _iwdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
+static rt_err_t apm32_iwdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
 {
     volatile rt_uint32_t param, counter = 0;
 
@@ -125,15 +137,15 @@ static rt_err_t _iwdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
     return RT_EOK;
 }
 
-static struct rt_watchdog_ops _wdt_ops =
+static struct rt_watchdog_ops apm32_wdt_ops =
 {
-    _iwdt_init,
-    _iwdt_control,
+    apm32_iwdt_init,
+    apm32_iwdt_control,
 };
 
 static int rt_hw_wdt_init(void)
 {
-    wdt_config.wdt.ops = &_wdt_ops;
+    wdt_config.wdt.ops = &apm32_wdt_ops;
     /* register watchdog device */
     if (rt_hw_watchdog_register(&wdt_config.wdt, "wdt", \
                                 RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)

+ 6 - 1
project_0/libraries/Kconfig

@@ -1,6 +1,11 @@
 config SOC_FAMILY_APM32
     bool
 
+config SOC_SERIES_APM32F0
+    bool
+    select ARCH_ARM_CORTEX_M0
+    select SOC_FAMILY_APM32
+
 config SOC_SERIES_APM32F1
     bool
     select ARCH_ARM_CORTEX_M3
@@ -9,4 +14,4 @@ config SOC_SERIES_APM32F1
 config SOC_SERIES_APM32F4
     bool
     select ARCH_ARM_CORTEX_M4
-    select SOC_FAMILY_APM32
+    select SOC_FAMILY_APM32

+ 2 - 2
project_0/project.ewp

@@ -77,7 +77,7 @@
         </option>
         <option>
           <name>OGChipSelectEditMenu</name>
-          <state>APM32F407VG	Geehy APM32F407VG</state>
+          <state>APM32F407IG	Geehy APM32F407IG</state>
         </option>
         <option>
           <name>GenLowLevelInterface</name>
@@ -137,7 +137,7 @@
         </option>
         <option>
           <name>GFPUDeviceSlave</name>
-          <state>APM32F407VG	Geehy APM32F407VG</state>
+          <state>APM32F407IG	Geehy APM32F407IG</state>
         </option>
         <option>
           <name>FPU2</name>

+ 760 - 4
project_0/project.uvoptx

@@ -10,7 +10,7 @@
     <aExt>*.s*; *.src; *.a*</aExt>
     <oExt>*.obj; *.o</oExt>
     <lExt>*.lib</lExt>
-    <tExt>*.txt; *.h; *.inc</tExt>
+    <tExt>*.txt; *.h; *.inc; *.md</tExt>
     <pExt>*.plm</pExt>
     <CppX>*.cpp</CppX>
     <nMigrate>0</nMigrate>
@@ -120,12 +120,12 @@
         <SetRegEntry>
           <Number>0</Number>
           <Key>UL2CM3</Key>
-          <Name>UL2CM3(-S0 -C0 -P0 )  -FN1 -FC1000 -FD20000000 -FF0APM32F4xx_1024 -FL080000 -FS08000000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM)</Name>
+          <Name>UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0APM32F4xx_1024 -FL080000 -FS08000000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM)</Name>
         </SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Key>JL2CM3</Key>
-          <Name>-U59401308 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM)</Name>
+          <Name>-U150710805 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO15 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM)</Name>
         </SetRegEntry>
       </TargetDriverDllRegistry>
       <Breakpoint/>
@@ -175,11 +175,767 @@
   </Target>
 
   <Group>
-    <GroupName>Source Group 1</GroupName>
+    <GroupName>ADT</GroupName>
     <tvExp>0</tvExp>
     <tvExpOptDlg>0</tvExpOptDlg>
     <cbSel>0</cbSel>
     <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>1</GroupNumber>
+      <FileNumber>1</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\utilities\libadt\avl.c</PathWithFileName>
+      <FilenameWithoutPath>avl.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Applications</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>2</GroupNumber>
+      <FileNumber>2</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>applications\main.c</PathWithFileName>
+      <FilenameWithoutPath>main.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Compiler</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>3</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\armlibc\syscall_mem.c</PathWithFileName>
+      <FilenameWithoutPath>syscall_mem.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>4</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\armlibc\syscalls.c</PathWithFileName>
+      <FilenameWithoutPath>syscalls.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>5</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\cctype.c</PathWithFileName>
+      <FilenameWithoutPath>cctype.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>6</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\cstdio.c</PathWithFileName>
+      <FilenameWithoutPath>cstdio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>7</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\cstdlib.c</PathWithFileName>
+      <FilenameWithoutPath>cstdlib.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>8</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\cstring.c</PathWithFileName>
+      <FilenameWithoutPath>cstring.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>9</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\ctime.c</PathWithFileName>
+      <FilenameWithoutPath>ctime.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>10</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\libc\compilers\common\cwchar.c</PathWithFileName>
+      <FilenameWithoutPath>cwchar.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>CPU</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>11</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\libcpu\arm\common\div0.c</PathWithFileName>
+      <FilenameWithoutPath>div0.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>12</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\libcpu\arm\common\showmem.c</PathWithFileName>
+      <FilenameWithoutPath>showmem.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>13</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\libcpu\arm\cortex-m4\context_rvds.S</PathWithFileName>
+      <FilenameWithoutPath>context_rvds.S</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>4</GroupNumber>
+      <FileNumber>14</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\libcpu\arm\cortex-m4\cpuport.c</PathWithFileName>
+      <FilenameWithoutPath>cpuport.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>DeviceDrivers</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>15</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\completion.c</PathWithFileName>
+      <FilenameWithoutPath>completion.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>16</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\dataqueue.c</PathWithFileName>
+      <FilenameWithoutPath>dataqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>17</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\pipe.c</PathWithFileName>
+      <FilenameWithoutPath>pipe.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>18</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\ringblk_buf.c</PathWithFileName>
+      <FilenameWithoutPath>ringblk_buf.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>19</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\ringbuffer.c</PathWithFileName>
+      <FilenameWithoutPath>ringbuffer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>20</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\waitqueue.c</PathWithFileName>
+      <FilenameWithoutPath>waitqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>21</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\ipc\workqueue.c</PathWithFileName>
+      <FilenameWithoutPath>workqueue.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>22</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\misc\pin.c</PathWithFileName>
+      <FilenameWithoutPath>pin.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>23</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\drivers\serial\serial.c</PathWithFileName>
+      <FilenameWithoutPath>serial.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Drivers</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>24</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>board\board.c</PathWithFileName>
+      <FilenameWithoutPath>board.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>25</FileNumber>
+      <FileType>2</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\Device\Geehy\APM32F4xx\Source\arm\startup_apm32f40x.s</PathWithFileName>
+      <FilenameWithoutPath>startup_apm32f40x.s</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>26</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\Drivers\drv_common.c</PathWithFileName>
+      <FilenameWithoutPath>drv_common.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>27</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\Drivers\drv_gpio.c</PathWithFileName>
+      <FilenameWithoutPath>drv_gpio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>6</GroupNumber>
+      <FileNumber>28</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\Drivers\drv_usart.c</PathWithFileName>
+      <FilenameWithoutPath>drv_usart.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Filesystem</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>29</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\dfs\src\dfs_posix.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_posix.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>30</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\dfs\src\dfs_fs.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_fs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>31</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\dfs\src\dfs.c</PathWithFileName>
+      <FilenameWithoutPath>dfs.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>7</GroupNumber>
+      <FileNumber>32</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\dfs\src\dfs_file.c</PathWithFileName>
+      <FilenameWithoutPath>dfs_file.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Finsh</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>33</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\finsh\shell.c</PathWithFileName>
+      <FilenameWithoutPath>shell.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>34</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\finsh\msh.c</PathWithFileName>
+      <FilenameWithoutPath>msh.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>35</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\finsh\msh_parse.c</PathWithFileName>
+      <FilenameWithoutPath>msh_parse.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>36</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\finsh\cmd.c</PathWithFileName>
+      <FilenameWithoutPath>cmd.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>8</GroupNumber>
+      <FileNumber>37</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\components\finsh\msh_file.c</PathWithFileName>
+      <FilenameWithoutPath>msh_file.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Kernel</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>38</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\clock.c</PathWithFileName>
+      <FilenameWithoutPath>clock.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>39</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\components.c</PathWithFileName>
+      <FilenameWithoutPath>components.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>40</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\device.c</PathWithFileName>
+      <FilenameWithoutPath>device.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>41</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\idle.c</PathWithFileName>
+      <FilenameWithoutPath>idle.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>42</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\ipc.c</PathWithFileName>
+      <FilenameWithoutPath>ipc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>43</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\irq.c</PathWithFileName>
+      <FilenameWithoutPath>irq.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>44</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\kservice.c</PathWithFileName>
+      <FilenameWithoutPath>kservice.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>45</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\mem.c</PathWithFileName>
+      <FilenameWithoutPath>mem.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>46</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\mempool.c</PathWithFileName>
+      <FilenameWithoutPath>mempool.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>47</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\object.c</PathWithFileName>
+      <FilenameWithoutPath>object.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>48</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\scheduler.c</PathWithFileName>
+      <FilenameWithoutPath>scheduler.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>49</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\thread.c</PathWithFileName>
+      <FilenameWithoutPath>thread.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>9</GroupNumber>
+      <FileNumber>50</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\..\..\src\timer.c</PathWithFileName>
+      <FilenameWithoutPath>timer.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+  </Group>
+
+  <Group>
+    <GroupName>Libraries</GroupName>
+    <tvExp>0</tvExp>
+    <tvExpOptDlg>0</tvExpOptDlg>
+    <cbSel>0</cbSel>
+    <RteFlg>0</RteFlg>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>51</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_usart.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_usart.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>52</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_syscfg.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_syscfg.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>53</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_rcm.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_rcm.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>54</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_eint.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_eint.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>55</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_misc.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_misc.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>56</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_gpio.c</PathWithFileName>
+      <FilenameWithoutPath>apm32f4xx_gpio.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>10</GroupNumber>
+      <FileNumber>57</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\libraries\APM32F4xx_Library\Device\Geehy\APM32F4xx\Source\system_apm32f4xx.c</PathWithFileName>
+      <FilenameWithoutPath>system_apm32f4xx.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
 </ProjectOpt>

+ 76 - 154
project_0/project.uvprojx

@@ -1,43 +1,46 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
 <Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
+
   <SchemaVersion>2.1</SchemaVersion>
+
   <Header>### uVision Project, (C) Keil Software</Header>
+
   <Targets>
     <Target>
       <TargetName>rt-thread</TargetName>
       <ToolsetNumber>0x4</ToolsetNumber>
       <ToolsetName>ARM-ADS</ToolsetName>
-      <pCCUsed>5060750::V5.06 update 6 (build 750)::ARMCC</pCCUsed>
+      <pCCUsed>5060960::V5.06 update 7 (build 960)::.\ARMCC</pCCUsed>
       <uAC6>0</uAC6>
       <TargetOption>
         <TargetCommonOption>
-          <Device>APM32F407VG</Device>
+          <Device>APM32F407IG</Device>
           <Vendor>Geehy</Vendor>
-          <PackID>Geehy.APM32F4xx_DFP.1.0.1</PackID>
+          <PackID>Geehy.APM32F4xx_DFP.1.0.2</PackID>
           <PackURL>https://www.geehy.com/uploads/tool/</PackURL>
           <Cpu>IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
-          <FlashUtilSpec />
-          <StartupFile />
-          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL080000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM))</FlashDriverDll>
+          <FlashUtilSpec></FlashUtilSpec>
+          <StartupFile></StartupFile>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL080000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM))</FlashDriverDll>
           <DeviceId>0</DeviceId>
-          <RegisterFile />
-          <MemoryEnv />
-          <Cmp />
-          <Asm />
-          <Linker />
-          <OHString />
-          <InfinionOptionDll />
-          <SLE66CMisc />
-          <SLE66AMisc />
-          <SLE66LinkerMisc />
-          <SFDFile>$$Device:APM32F407VG$SVD\APM32F40x.svd</SFDFile>
+          <RegisterFile></RegisterFile>
+          <MemoryEnv></MemoryEnv>
+          <Cmp></Cmp>
+          <Asm></Asm>
+          <Linker></Linker>
+          <OHString></OHString>
+          <InfinionOptionDll></InfinionOptionDll>
+          <SLE66CMisc></SLE66CMisc>
+          <SLE66AMisc></SLE66AMisc>
+          <SLE66LinkerMisc></SLE66LinkerMisc>
+          <SFDFile>$$Device:APM32F407IG$SVD\APM32F40x.svd</SFDFile>
           <bCustSvd>0</bCustSvd>
           <UseEnv>0</UseEnv>
-          <BinPath />
-          <IncludePath />
-          <LibPath />
-          <RegisterFilePath />
-          <DBRegisterFilePath />
+          <BinPath></BinPath>
+          <IncludePath></IncludePath>
+          <LibPath></LibPath>
+          <RegisterFilePath></RegisterFilePath>
+          <DBRegisterFilePath></DBRegisterFilePath>
           <TargetStatus>
             <Error>0</Error>
             <ExitCodeStop>0</ExitCodeStop>
@@ -59,8 +62,8 @@
           <BeforeCompile>
             <RunUserProg1>0</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name />
-            <UserProg2Name />
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
             <nStopU1X>0</nStopU1X>
@@ -69,8 +72,8 @@
           <BeforeMake>
             <RunUserProg1>0</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
-            <UserProg1Name />
-            <UserProg2Name />
+            <UserProg1Name></UserProg1Name>
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
             <nStopB1X>0</nStopB1X>
@@ -80,14 +83,14 @@
             <RunUserProg1>1</RunUserProg1>
             <RunUserProg2>0</RunUserProg2>
             <UserProg1Name>fromelf --bin !L --output rtthread.bin</UserProg1Name>
-            <UserProg2Name />
+            <UserProg2Name></UserProg2Name>
             <UserProg1Dos16Mode>0</UserProg1Dos16Mode>
             <UserProg2Dos16Mode>0</UserProg2Dos16Mode>
             <nStopA1X>0</nStopA1X>
             <nStopA2X>0</nStopA2X>
           </AfterMake>
           <SelectedForBatchBuild>0</SelectedForBatchBuild>
-          <SVCSIdString />
+          <SVCSIdString></SVCSIdString>
         </TargetCommonOption>
         <CommonProperty>
           <UseCPPCompiler>0</UseCPPCompiler>
@@ -101,8 +104,8 @@
           <AssembleAssemblyFile>0</AssembleAssemblyFile>
           <PublicsOnly>0</PublicsOnly>
           <StopOnExitCode>3</StopOnExitCode>
-          <CustomArgument />
-          <IncludeLibraryModules />
+          <CustomArgument></CustomArgument>
+          <IncludeLibraryModules></IncludeLibraryModules>
           <ComprImg>1</ComprImg>
         </CommonProperty>
         <DllOption>
@@ -135,11 +138,11 @@
           </Flash1>
           <bUseTDR>1</bUseTDR>
           <Flash2>BIN\UL2CM3.DLL</Flash2>
-          <Flash3 />
-          <Flash4 />
-          <pFcarmOut />
-          <pFcarmGrp />
-          <pFcArmRoot />
+          <Flash3></Flash3>
+          <Flash4></Flash4>
+          <pFcarmOut></pFcarmOut>
+          <pFcarmGrp></pFcarmGrp>
+          <pFcArmRoot></pFcArmRoot>
           <FcArmLst>0</FcArmLst>
         </Utilities>
         <TargetArmAds>
@@ -172,7 +175,7 @@
             <RvctClst>0</RvctClst>
             <GenPPlst>0</GenPPlst>
             <AdsCpuType>"Cortex-M4"</AdsCpuType>
-            <RvctDeviceName />
+            <RvctDeviceName></RvctDeviceName>
             <mOS>0</mOS>
             <uocRom>0</uocRom>
             <uocRam>0</uocRam>
@@ -182,6 +185,7 @@
             <uocXRam>0</uocXRam>
             <RvdsVP>2</RvdsVP>
             <RvdsMve>0</RvdsMve>
+            <RvdsCdeCp>0</RvdsCdeCp>
             <hadIRAM2>1</hadIRAM2>
             <hadIROM2>0</hadIROM2>
             <StupSel>8</StupSel>
@@ -305,7 +309,7 @@
                 <Size>0x10000</Size>
               </OCR_RVCT10>
             </OnChipMemories>
-            <RvctStartVector />
+            <RvctStartVector></RvctStartVector>
           </ArmAdsMisc>
           <Cads>
             <interw>1</interw>
@@ -332,10 +336,10 @@
             <v6WtE>0</v6WtE>
             <v6Rtti>0</v6Rtti>
             <VariousControls>
-              <MiscControls />
-              <Define>__STDC_LIMIT_MACROS, USE_STDPERIPH_DRIVER, RT_USING_LIBC, APM32F40X, __CLK_TCK=RT_TICK_PER_SECOND, __RTTHREAD__, RT_USING_ARM_LIBC</Define>
-              <Undefine />
-              <IncludePath>applications;..\..\..\components\libc\compilers\common\include;..\..\..\components\libc\compilers\common\extension;..\..\..\components\libc\compilers\common\extension\fcntl\octal;..\..\..\libcpu\arm\common;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\drivers\include;..\..\..\components\drivers\include;..\..\..\components\drivers\include;board;..\libraries\Drivers;..\libraries\Drivers\config;..\..\..\components\dfs\include;..\..\..\components\finsh;.;..\..\..\include;..\libraries\APM32F4xx_Library\Device\Geehy\APM32F4xx\Include;..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\inc;..\libraries\APM32F4xx_Library\CMSIS\Include;..\..\..\components\libc\posix\io\poll;..\..\..\components\libc\posix\io\stdio;..\..\..\components\libc\posix\ipc</IncludePath>
+              <MiscControls></MiscControls>
+              <Define>__STDC_LIMIT_MACROS, RT_USING_ARMLIBC, USE_STDPERIPH_DRIVER, RT_USING_LIBC, APM32F40X, __CLK_TCK=RT_TICK_PER_SECOND, __RTTHREAD__</Define>
+              <Undefine></Undefine>
+              <IncludePath>.;..\..\..\components\drivers\include;..\libraries\Drivers\config;..\..\..\components\drivers\include;..\..\..\components\libc\compilers\common\include;..\..\..\components\finsh;..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\inc;..\..\..\components\libc\compilers\common\extension;..\..\..\components\libc\posix\io\poll;applications;..\..\..\components\drivers\include;..\..\..\components\libc\posix\ipc;..\..\..\components\libc\compilers\common\extension\fcntl\octal;board;..\libraries\APM32F4xx_Library\APM32F4xx_ETH_Driver\inc;..\..\..\components\utilities\libadt;..\libraries\Drivers;..\..\..\include;..\libraries\APM32F4xx_Library\CMSIS\Include;..\..\..\libcpu\arm\common;..\..\..\components\dfs\include;..\..\..\libcpu\arm\cortex-m4;..\..\..\components\libc\posix\io\stdio;..\libraries\APM32F4xx_Library\Device\Geehy\APM32F4xx\Include</IncludePath>
             </VariousControls>
           </Cads>
           <Aads>
@@ -348,12 +352,12 @@
             <NoWarn>0</NoWarn>
             <uSurpInc>0</uSurpInc>
             <useXO>0</useXO>
-            <uClangAs>0</uClangAs>
+            <ClangAsOpt>4</ClangAsOpt>
             <VariousControls>
-              <MiscControls />
-              <Define />
-              <Undefine />
-              <IncludePath />
+              <MiscControls></MiscControls>
+              <Define></Define>
+              <Undefine></Undefine>
+              <IncludePath></IncludePath>
             </VariousControls>
           </Aads>
           <LDads>
@@ -365,17 +369,27 @@
             <useFile>0</useFile>
             <TextAddressRange>0x08000000</TextAddressRange>
             <DataAddressRange>0x20000000</DataAddressRange>
-            <pXoBase />
+            <pXoBase></pXoBase>
             <ScatterFile>.\board\linker_scripts\link.sct</ScatterFile>
-            <IncludeLibs />
-            <IncludeLibsPath />
-            <Misc />
-            <LinkerInputFile />
-            <DisabledWarnings />
+            <IncludeLibs></IncludeLibs>
+            <IncludeLibsPath></IncludeLibsPath>
+            <Misc></Misc>
+            <LinkerInputFile></LinkerInputFile>
+            <DisabledWarnings></DisabledWarnings>
           </LDads>
         </TargetArmAds>
       </TargetOption>
       <Groups>
+        <Group>
+          <GroupName>ADT</GroupName>
+          <Files>
+            <File>
+              <FileName>avl.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\..\..\components\utilities\libadt\avl.c</FilePath>
+            </File>
+          </Files>
+        </Group>
         <Group>
           <GroupName>Applications</GroupName>
           <Files>
@@ -394,50 +408,36 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\armlibc\syscall_mem.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>syscalls.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\armlibc\syscalls.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cctype.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\common\cctype.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cstdio.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\common\cstdio.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cstdlib.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\common\cstdlib.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cstring.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\common\cstring.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ctime.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\libc\compilers\common\ctime.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cwchar.c</FileName>
               <FileType>1</FileType>
@@ -447,35 +447,22 @@
         </Group>
         <Group>
           <GroupName>CPU</GroupName>
-          <Files>
-            <File>
-              <FileName>backtrace.c</FileName>
-              <FileType>1</FileType>
-              <FilePath>..\..\..\libcpu\arm\common\backtrace.c</FilePath>
-            </File>
-          </Files>
           <Files>
             <File>
               <FileName>div0.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\libcpu\arm\common\div0.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>showmem.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\libcpu\arm\common\showmem.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>context_rvds.S</FileName>
               <FileType>2</FileType>
               <FilePath>..\..\..\libcpu\arm\cortex-m4\context_rvds.S</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cpuport.c</FileName>
               <FileType>1</FileType>
@@ -491,57 +478,41 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\completion.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>dataqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\dataqueue.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pipe.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\pipe.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ringblk_buf.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\ringblk_buf.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ringbuffer.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\ringbuffer.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>waitqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\waitqueue.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>workqueue.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\ipc\workqueue.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>pin.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\drivers\misc\pin.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>serial.c</FileName>
               <FileType>1</FileType>
@@ -557,29 +528,21 @@
               <FileType>1</FileType>
               <FilePath>board\board.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>startup_apm32f40x.s</FileName>
               <FileType>2</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\Device\Geehy\APM32F4xx\Source\arm\startup_apm32f40x.s</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>drv_common.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\Drivers\drv_common.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>drv_gpio.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\Drivers\drv_gpio.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>drv_usart.c</FileName>
               <FileType>1</FileType>
@@ -595,22 +558,16 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\components\dfs\src\dfs_posix.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>dfs_fs.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\dfs\src\dfs_fs.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>dfs.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\dfs\src\dfs.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>dfs_file.c</FileName>
               <FileType>1</FileType>
@@ -626,29 +583,21 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\components\finsh\shell.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>msh.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\finsh\msh.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>msh_parse.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\finsh\msh_parse.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>cmd.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\components\finsh\cmd.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>msh_file.c</FileName>
               <FileType>1</FileType>
@@ -664,85 +613,61 @@
               <FileType>1</FileType>
               <FilePath>..\..\..\src\clock.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>components.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\components.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>device.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\device.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>idle.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\idle.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>ipc.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\ipc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>irq.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\irq.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>kservice.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\kservice.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>mem.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\mem.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>mempool.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\mempool.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>object.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\object.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>scheduler.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\scheduler.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>thread.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\..\..\src\thread.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>timer.c</FileName>
               <FileType>1</FileType>
@@ -758,36 +683,31 @@
               <FileType>1</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_usart.c</FilePath>
             </File>
-          </Files>
-          <Files>
+            <File>
+              <FileName>apm32f4xx_syscfg.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_syscfg.c</FilePath>
+            </File>
             <File>
               <FileName>apm32f4xx_rcm.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_rcm.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>apm32f4xx_eint.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_eint.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>apm32f4xx_misc.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_misc.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>apm32f4xx_gpio.c</FileName>
               <FileType>1</FileType>
               <FilePath>..\libraries\APM32F4xx_Library\APM32F4xx_StdPeriphDriver\src\apm32f4xx_gpio.c</FilePath>
             </File>
-          </Files>
-          <Files>
             <File>
               <FileName>system_apm32f4xx.c</FileName>
               <FileType>1</FileType>
@@ -798,9 +718,11 @@
       </Groups>
     </Target>
   </Targets>
+
   <RTE>
-    <apis />
-    <components />
-    <files />
+    <apis/>
+    <components/>
+    <files/>
   </RTE>
+
 </Project>

+ 43 - 10
project_0/rtconfig.h

@@ -7,7 +7,7 @@
 /* RT-Thread Kernel */
 
 #define RT_NAME_MAX 8
-#define RT_ALIGN_SIZE 4
+#define RT_ALIGN_SIZE 8
 #define RT_THREAD_PRIORITY_32
 #define RT_THREAD_PRIORITY_MAX 32
 #define RT_TICK_PER_SECOND 1000
@@ -36,6 +36,7 @@
 
 /* Memory Management */
 
+#define RT_PAGE_MAX_ORDER 11
 #define RT_USING_MEMPOOL
 #define RT_USING_SMALL_MEM
 #define RT_USING_SMALL_MEM_AS_HEAP
@@ -47,9 +48,9 @@
 #define RT_USING_CONSOLE
 #define RT_CONSOLEBUF_SIZE 128
 #define RT_CONSOLE_DEVICE_NAME "uart1"
-#define RT_VER_NUM 0x40101
-#define ARCH_ARM
+#define RT_VER_NUM 0x50000
 #define RT_USING_CPU_FFS
+#define ARCH_ARM
 #define ARCH_ARM_CORTEX_M
 #define ARCH_ARM_CORTEX_M4
 
@@ -82,6 +83,7 @@
 /* Device Drivers */
 
 #define RT_USING_DEVICE_IPC
+#define RT_UNAMED_PIPE_NUMBER 64
 #define RT_USING_SERIAL
 #define RT_USING_SERIAL_V1
 #define RT_SERIAL_USING_DMA
@@ -148,9 +150,6 @@
 /* u8g2: a monochrome graphic library */
 
 
-/* PainterEngine: A cross-platform graphics application framework written in C language */
-
-
 /* tools packages */
 
 
@@ -170,6 +169,11 @@
 
 /* peripheral libraries and drivers */
 
+/* sensors drivers */
+
+
+/* touch drivers */
+
 
 /* Kendryte SDK */
 
@@ -177,6 +181,9 @@
 /* AI packages */
 
 
+/* Signal Processing and Control Algorithm Packages */
+
+
 /* miscellaneous packages */
 
 /* project laboratory */
@@ -187,20 +194,46 @@
 /* entertainment: terminal games and other interesting software packages */
 
 
-/* Privated Packages of RealThread */
+/* Arduino libraries */
+
+
+/* Projects */
+
+
+/* Sensors */
+
+
+/* Display */
+
+
+/* Timing */
+
+
+/* Data Processing */
+
+
+/* Data Storage */
+
+/* Communication */
+
+
+/* Device Control */
+
+
+/* Other */
 
 
-/* Network Utilities */
+/* Signal IO */
 
 
-/* RT-Thread Smart */
+/* Uncategorized */
 
 #define SOC_FAMILY_APM32
 #define SOC_SERIES_APM32F4
 
 /* Hardware Drivers Config */
 
-#define SOC_APM32F407VG
+#define SOC_APM32F407IG
 
 /* On-chip Peripheral Drivers */
 

+ 1 - 2
project_0/rtconfig_preinc.h

@@ -6,9 +6,8 @@
 /* RT-Thread pre-include file */
 
 #define APM32F40X
-#define HAVE_CCONFIG_H
 #define RT_USING_LIBC
-#define RT_USING_NEWLIB
+#define RT_USING_NEWLIBC
 #define USE_STDPERIPH_DRIVER
 #define _POSIX_C_SOURCE 1
 #define __RTTHREAD__

+ 2 - 2
project_0/template.ewp

@@ -78,7 +78,7 @@
                 </option>
                 <option>
                     <name>OGChipSelectEditMenu</name>
-                    <state>APM32F407VG	Geehy APM32F407VG</state>
+                    <state>APM32F407IG	Geehy APM32F407IG</state>
                 </option>
                 <option>
                     <name>GenLowLevelInterface</name>
@@ -138,7 +138,7 @@
                 </option>
                 <option>
                     <name>GFPUDeviceSlave</name>
-                    <state>APM32F407VG	Geehy APM32F407VG</state>
+                    <state>APM32F407IG	Geehy APM32F407IG</state>
                 </option>
                 <option>
                     <name>FPU2</name>

+ 2 - 2
project_0/template.uvoptx

@@ -120,12 +120,12 @@
         <SetRegEntry>
           <Number>0</Number>
           <Key>UL2CM3</Key>
-          <Name>UL2CM3(-S0 -C0 -P0 )  -FN1 -FC1000 -FD20000000 -FF0APM32F4xx_1024 -FL080000 -FS08000000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM)</Name>
+          <Name>UL2CM3(-S0 -C0 -P0 ) -FN1 -FC1000 -FD20000000 -FF0APM32F4xx_1024 -FL080000 -FS08000000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM)</Name>
         </SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Key>JL2CM3</Key>
-          <Name>-U59401308 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM)</Name>
+          <Name>-U59401308 -O78 -S2 -ZTIFSpeedSel5000 -A0 -C0 -JU1 -JI127.0.0.1 -JP0 -RST0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -TB1 -TFE0 -FO7 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM)</Name>
         </SetRegEntry>
       </TargetDriverDllRegistry>
       <Breakpoint/>

+ 3 - 3
project_0/template.uvprojx

@@ -14,14 +14,14 @@
       <uAC6>0</uAC6>
       <TargetOption>
         <TargetCommonOption>
-          <Device>APM32F407VG</Device>
+          <Device>APM32F407IG</Device>
           <Vendor>Geehy</Vendor>
           <PackID>Geehy.APM32F4xx_DFP.1.0.1</PackID>
           <PackURL>https://www.geehy.com/uploads/tool/</PackURL>
           <Cpu>IRAM(0x20000000,0x00020000) IRAM2(0x10000000,0x00010000) IROM(0x08000000,0x00100000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE</Cpu>
           <FlashUtilSpec></FlashUtilSpec>
           <StartupFile></StartupFile>
-          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL080000 -FP0($$Device:APM32F407VG$Flash\APM32F4xx_1024.FLM))</FlashDriverDll>
+          <FlashDriverDll>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0APM32F4xx_1024 -FS08000000 -FL080000 -FP0($$Device:APM32F407IG$Flash\APM32F4xx_1024.FLM))</FlashDriverDll>
           <DeviceId>0</DeviceId>
           <RegisterFile></RegisterFile>
           <MemoryEnv></MemoryEnv>
@@ -33,7 +33,7 @@
           <SLE66CMisc></SLE66CMisc>
           <SLE66AMisc></SLE66AMisc>
           <SLE66LinkerMisc></SLE66LinkerMisc>
-          <SFDFile>$$Device:APM32F407VG$SVD\APM32F40x.svd</SFDFile>
+          <SFDFile>$$Device:APM32F407IG$SVD\APM32F40x.svd</SFDFile>
           <bCustSvd>0</bCustSvd>
           <UseEnv>0</UseEnv>
           <BinPath></BinPath>

+ 1 - 1
sdk-bsp-apm32f407vg-geehy-mini.yaml

@@ -66,7 +66,7 @@ features_zh:
 - 调试接口:JTAG/SWD
 pkg_type: Board_Support_Packages
 pkg_vendor: Geehy
-pkg_version: 1.0.0
+pkg_version: 1.0.1
 template_projects:
 - builtin_files:
   - files_and_folders:

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.