Ver código fonte

add gokemicro gkipc bsp

gokemicro 7 anos atrás
pai
commit
e2ea23990b
100 arquivos alterados com 28066 adições e 0 exclusões
  1. 340 0
      bsp/gkipc/.config
  2. 134 0
      bsp/gkipc/Kconfig
  3. 59 0
      bsp/gkipc/README.md
  4. 19 0
      bsp/gkipc/SConscript
  5. 33 0
      bsp/gkipc/SConstruct
  6. 10 0
      bsp/gkipc/applications/SConscript
  7. 41 0
      bsp/gkipc/applications/main.c
  8. 10 0
      bsp/gkipc/armv6/SConscript
  9. 376 0
      bsp/gkipc/armv6/arm1176_mmu.gcc.s
  10. 64 0
      bsp/gkipc/armv6/arm1176_mmu_ttb.c
  11. 34 0
      bsp/gkipc/armv6/arm1176_mmu_ttb.h
  12. 62 0
      bsp/gkipc/armv6/arm1176_vfp_fast_gcc.s
  13. 160 0
      bsp/gkipc/armv6/context_gcc.s
  14. 297 0
      bsp/gkipc/armv6/cpuport.c
  15. 81 0
      bsp/gkipc/armv6/gk7101.h
  16. 148 0
      bsp/gkipc/armv6/interrupt.c
  17. 563 0
      bsp/gkipc/armv6/mmu.c
  18. 73 0
      bsp/gkipc/armv6/mmu.h
  19. 39 0
      bsp/gkipc/armv6/reset.c
  20. 27 0
      bsp/gkipc/armv6/rtos.h
  21. 1450 0
      bsp/gkipc/armv6/rtos_lib.c
  22. 236 0
      bsp/gkipc/armv6/rtos_lib.h
  23. 130 0
      bsp/gkipc/armv6/rtos_memory.h
  24. 77 0
      bsp/gkipc/armv6/stack.c
  25. 481 0
      bsp/gkipc/armv6/start_gcc.s
  26. 56 0
      bsp/gkipc/armv6/system_clock.c
  27. 250 0
      bsp/gkipc/armv6/trap.c
  28. 24 0
      bsp/gkipc/drivers/SConscript
  29. 131 0
      bsp/gkipc/drivers/board.c
  30. 32 0
      bsp/gkipc/drivers/board.h
  31. 237 0
      bsp/gkipc/drivers/drv_adc.c
  32. 77 0
      bsp/gkipc/drivers/drv_adc.h
  33. 226 0
      bsp/gkipc/drivers/drv_dma.c
  34. 121 0
      bsp/gkipc/drivers/drv_dma.h
  35. 349 0
      bsp/gkipc/drivers/drv_flash.c
  36. 6 0
      bsp/gkipc/drivers/drv_flash.h
  37. 519 0
      bsp/gkipc/drivers/drv_gmac.c
  38. 35 0
      bsp/gkipc/drivers/drv_gmac.h
  39. 304 0
      bsp/gkipc/drivers/drv_i2c.c
  40. 144 0
      bsp/gkipc/drivers/drv_i2c.h
  41. 342 0
      bsp/gkipc/drivers/drv_mmc.c
  42. 186 0
      bsp/gkipc/drivers/drv_mmc.h
  43. 512 0
      bsp/gkipc/drivers/drv_pwm.c
  44. 75 0
      bsp/gkipc/drivers/drv_pwm.h
  45. 1684 0
      bsp/gkipc/drivers/drv_sdio.c
  46. 41 0
      bsp/gkipc/drivers/drv_sdio.h
  47. 317 0
      bsp/gkipc/drivers/drv_ssi.c
  48. 43 0
      bsp/gkipc/drivers/drv_ssi.h
  49. 474 0
      bsp/gkipc/drivers/drv_uart.c
  50. 7 0
      bsp/gkipc/drivers/drv_uart.h
  51. 239 0
      bsp/gkipc/drivers/drv_wdt.c
  52. 40 0
      bsp/gkipc/drivers/drv_wdt.h
  53. 331 0
      bsp/gkipc/gk7102c_evb_sc1135_config
  54. 14 0
      bsp/gkipc/libraries/SConscript
  55. 15 0
      bsp/gkipc/libraries/drv/7102C/SConscript
  56. 18 0
      bsp/gkipc/libraries/drv/7102C/gd/SConscript
  57. 164 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_adc.h
  58. 191 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_audio.h
  59. 165 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_crypto.h
  60. 178 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_dma.h
  61. 408 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_ethernet.h
  62. 610 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_gpio.h
  63. 219 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_i2c.h
  64. 203 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_i2s.h
  65. 250 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_int.h
  66. 285 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_ir.h
  67. 84 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_pwm.h
  68. 244 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_sdio.h
  69. 375 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_sflash.h
  70. 315 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_spi.h
  71. 176 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_spieeprom.h
  72. 165 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_timer.h
  73. 313 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_uart.h
  74. 126 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_usb.h
  75. 334 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_vo_i80.h
  76. 56 0
      bsp/gkipc/libraries/drv/7102C/gd/inc/gd_wdog.h
  77. 44 0
      bsp/gkipc/libraries/drv/7102C/gd/src/SConscript
  78. 203 0
      bsp/gkipc/libraries/drv/7102C/gd/src/adc/gd_adc.c
  79. 1266 0
      bsp/gkipc/libraries/drv/7102C/gd/src/audio/gd_audio.c
  80. 347 0
      bsp/gkipc/libraries/drv/7102C/gd/src/crypto/gd_crypto.c
  81. 327 0
      bsp/gkipc/libraries/drv/7102C/gd/src/dma/gd_dma.c
  82. 1140 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_emac.c
  83. 253 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_emac.h
  84. 570 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_ephy.c
  85. 83 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_ephy.h
  86. 649 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy.c
  87. 100 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy.h
  88. 137 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_ar8032.c
  89. 82 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_ar8032.h
  90. 271 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_lan8700.c
  91. 83 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_lan8700.h
  92. 568 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_reg.h
  93. 138 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_rtl8201.c
  94. 82 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_rtl8201.h
  95. 126 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_priv.h
  96. 1452 0
      bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_ethernet.c
  97. 1045 0
      bsp/gkipc/libraries/drv/7102C/gd/src/gpio/gd_gpio.c
  98. 697 0
      bsp/gkipc/libraries/drv/7102C/gd/src/i2c/gd_i2c.c
  99. 918 0
      bsp/gkipc/libraries/drv/7102C/gd/src/i2c/gd_i2c_sw.c
  100. 831 0
      bsp/gkipc/libraries/drv/7102C/gd/src/i2s/gd_i2s.c

+ 340 - 0
bsp/gkipc/.config

@@ -0,0 +1,340 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=32
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+# CONFIG_RT_THREAD_PRIORITY_32 is not set
+CONFIG_RT_THREAD_PRIORITY_256=y
+CONFIG_RT_THREAD_PRIORITY_MAX=256
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_DEBUG=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=1024
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=10240
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+# CONFIG_RT_USING_MEMPOOL is not set
+CONFIG_RT_USING_MEMHEAP=y
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_INTERRUPT_INFO=y
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=16384
+
+#
+# C++ features
+#
+CONFIG_RT_USING_CPLUSPLUS=y
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=9
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=9
+CONFIG_DFS_FD_MAX=16
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+CONFIG_RT_USING_DFS_JFFS2=y
+CONFIG_RT_USING_DFS_NFS=y
+CONFIG_RT_NFS_HOST_EXPORT="192.168.10.82:/"
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+CONFIG_RT_USING_I2C_BITOPS=y
+CONFIG_RT_USING_PIN=y
+CONFIG_RT_USING_MTD_NOR=y
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_RTC is not set
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_SPI_MSD is not set
+# CONFIG_RT_USING_SFUD is not set
+# CONFIG_RT_USING_W25QXX is not set
+# CONFIG_RT_USING_GD is not set
+# CONFIG_RT_USING_ENC28J60 is not set
+# CONFIG_RT_USING_SPI_WIFI is not set
+CONFIG_RT_USING_WDT=y
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+CONFIG_RT_USING_PTHREADS=y
+# CONFIG_RT_USING_POSIX is not set
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+CONFIG_RT_USING_LWIP202=y
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_IGMP=y
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+# CONFIG_RT_LWIP_RAW is not set
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=64
+CONFIG_RT_LWIP_PBUF_NUM=16
+CONFIG_RT_LWIP_RAW_PCB_NUM=10
+CONFIG_RT_LWIP_UDP_PCB_NUM=64
+CONFIG_RT_LWIP_TCP_PCB_NUM=8
+CONFIG_RT_LWIP_TCP_SEG_NUM=256
+CONFIG_RT_LWIP_TCP_SND_BUF=12040
+CONFIG_RT_LWIP_TCP_WND=11680
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=100
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=32768
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=126
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
+CONFIG_LWIP_NETIF_LOOPBACK=0
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+CONFIG_LWIP_USING_DHCPD=y
+
+#
+# RT-Thread UI Engine
+#
+# CONFIG_RT_USING_GUIENGINE is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+
+# CONFIG_SOC_GK7101 is not set
+# CONFIG_SOC_GK7102 is not set
+# CONFIG_SOC_GK7101S is not set
+# CONFIG_SOC_GK7102S is not set
+CONFIG_SOC_GK7102C=y
+CONFIG_BOARD_GK7102C_EVB=y
+CONFIG_SENSOR_TYPE_SC1135=y
+# CONFIG_SENSOR_TYPE_SC1145 is not set
+# CONFIG_SENSOR_TYPE_JXH65 is not set
+# CONFIG_SENSOR_TYPE_OV9750 is not set
+# CONFIG_SENSOR_TYPE_AR0130 is not set
+# CONFIG_SENSOR_TYPE_JXH42 is not set
+CONFIG_TUNNING_TOOL_SUPPORT=y
+CONFIG_RT_USING_DMA_MEM=y
+CONFIG_ARM1176_USE_VFP=y
+CONFIG_RT_USING_VFP=y
+CONFIG_RT_USING_CPU_FFS=y
+
+#
+# Goke Peripheral Device Config
+#
+CONFIG_RT_USING_ADC=y
+CONFIG_RT_USING_GMAC=y
+CONFIG_RT_USING_PWM=y
+CONFIG_RT_USING_GK_DMA=y
+CONFIG_RT_USING_LIBZ=y
+CONFIG_RT_USING_LOGCAPTURE=y
+CONFIG_RT_ALIGN_UC_SIZE=8
+CONFIG_RT_ALIGN_DSP_SIZE=32
+CONFIG_RT_DEBUG_UC_MEM=0
+CONFIG_RT_DEBUG_DSP_MEM=0

+ 134 - 0
bsp/gkipc/Kconfig

@@ -0,0 +1,134 @@
+mainmenu "RT-Thread Configuration"
+
+config $BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config $RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../.."
+
+config $PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+
+
+choice
+    prompt "Device type"
+    default GK7102C
+    config SOC_GK7101
+        bool "GK7101"
+    config SOC_GK7102
+        bool "GK7102"
+    config SOC_GK7101S
+        bool "GK7101S"
+    config SOC_GK7102S
+        bool "GK7102S"
+    config SOC_GK7102C
+        bool "GK7102C"
+endchoice
+
+choice
+    prompt "Board type"
+    default GK7102C_EVB
+    config BOARD_GK7101_EVB
+        bool "GK7101_EVB"
+        depends on SOC_GK7101
+    config BOARD_GK7101_EVB
+        bool "GK7101_EVB"
+        depends on SOC_GK7102
+    config BOARD_GK7101S_EVB
+        bool "GK7101S_EVB"
+        depends on SOC_GK7101S
+    config BOARD_GK7101S_EVB
+        bool "GK7101S_EVB"
+        depends on SOC_GK7102S
+    config BOARD_GK7102C_EVB
+        bool "GK7102C_EVB"
+        depends on SOC_GK7102C
+endchoice
+
+choice
+    prompt "Sensor type"
+    default SENSOR_TYPE_SC1135
+    config SENSOR_TYPE_SC1135
+        bool "SC1135"
+    config SENSOR_TYPE_SC1145
+        bool "SC1145"
+    config SENSOR_TYPE_JXH65
+        bool "JXH65"
+    config SENSOR_TYPE_OV9750
+        bool "OV9750"
+    config SENSOR_TYPE_AR0130
+        bool "AR0130"
+    config SENSOR_TYPE_JXH42
+        bool "JXH42"
+endchoice
+
+config TUNNING_TOOL_SUPPORT
+    bool "Using Tuning Tool"
+    default y
+    
+config RT_USING_DMA_MEM
+    bool "Enable DMA Mem"
+    default y  
+
+config ARM1176_USE_VFP
+    bool "Enable ARM1176 VFP"
+    default y  
+    
+config RT_USING_VFP
+    bool "Enable VFP"
+    default y  
+
+config RT_USING_CPU_FFS
+    bool "Enable CPU FFS"
+    default y
+      
+menu "Goke Peripheral Device Config"
+    config RT_USING_ADC
+        bool "Enable ADC"
+        default y    
+ 
+    config RT_USING_GMAC
+        bool "Enable GMAC"
+        default y     
+
+    config RT_USING_PWM
+        bool "Enable PWM"
+        default y    
+  
+    config RT_USING_GK_DMA
+        bool "Enable DMA"
+        default y    
+        
+    config RT_USING_LIBZ
+        bool "Enable Zlib for firmware uncompress"
+        default y  
+        
+    config RT_USING_LOGCAPTURE
+        bool "Enable DSP Logcaputure"
+        default y
+        
+    config RT_ALIGN_UC_SIZE
+        int "Align UC Size"
+        default 8
+    
+    config RT_ALIGN_DSP_SIZE
+        int "Align DSP Size"
+        default 32
+        
+    config RT_DEBUG_UC_MEM
+        int "Debug UC Memory"
+        default 0
+    
+    config RT_DEBUG_DSP_MEM
+        int "Debug DSP Memory"
+        default 0
+endmenu 

+ 59 - 0
bsp/gkipc/README.md

@@ -0,0 +1,59 @@
+# gkipc板级支持包
+
+标签: bsp说明文档
+
+---
+
+## 1. 简介
+
+GK7102C是针对高清IP Camera产品开发的一款低功耗高性能 SOC芯片,支持 960@30p多路码流 H.264 编码及高质量的 ISP 处理,内置  3D降噪和动态对比度提升模块,支持主流的多种并口 8bit/10bit/12bit sensor。视频输出支持 RGB 小型 LCD 屏显示接口。 GK7102C 内封 DDR2 DRAM 芯片,内置 Ethernet PHY, Audio codec,USB PHY 等模拟 IP。 GK7102C 拥有
+丰富的外设接口,如 USB2.0,SDIO,PWM,SPI,I2C 等等,支持最多 32 个GPIO,可灵活配置各功能模块的输出管脚,为实现高集成度 IPC提供了高性价比的解决方案。包括如下硬件特性:
+
+| 硬件 | 描述 |
+| -- | -- |
+|芯片型号| GK7102C |
+|CPU| ARM1176ZJFS |
+|主频| 432MHz |
+|片内DDR2|  512M bit@800MHz |
+
+
+## 2. 编译说明
+
+推荐使用[env工具][1],可以在console下进入到`bsp/gkipc`目录中,运行以下命令:
+
+    scons
+
+来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、rtthread.bin文件。其中rtthread.bin可以通过网络加载或者烧写到设备中进行运行。
+
+## 3. 烧写及执行
+
+[需要说明电源连接情况,串口连接情况]
+
+连接好串口,可以使用115200-N-8-1的配置方式连接到设备上。设备使用的串口引脚是:`[GPIO25/GPIO26]`
+
+当正确编译产生出rtthread.bin映像文件后,可以使用tftp的方式来加载到设备中运行。
+
+### 3.1 运行结果
+
+如果编译 & 烧写无误,当复位设备后,会在串口上看到RT-Thread的启动logo信息:
+
+## 4. 驱动支持情况及计划
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | ----  | :------:  |
+| UART | 支持 | UART0/1/2 |
+| clock | 支持 |  |
+| SPI |  | SPI0 |
+| ADC | 支持 |  |
+| DMA | 支持 |  |
+| GMAC | 支持 |  |
+| I2C | 支持 |  |
+| PWM | 支持 |  |
+| SDIO | 支持 | SDIO0/1 |
+| WDT | 支持 |  |
+| MMC | 支持 |  |
+| SSI | 支持 |  |
+
+## 5. 联系人信息
+
+维护人:gokemicro < gokemicro@yeah.net >

+ 19 - 0
bsp/gkipc/SConscript

@@ -0,0 +1,19 @@
+# for module compiling
+import os
+Import('RTT_ROOT')
+
+cwd = str(Dir('#'))
+objs = []
+list = os.listdir(cwd)
+
+print('------------------------------------------------')
+print('rtt_root:    ' + RTT_ROOT)
+print('current dir: ' + cwd)
+print('------------------------------------------------')
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 33 - 0
bsp/gkipc/SConstruct

@@ -0,0 +1,33 @@
+import os
+import sys
+import rtconfig
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.normpath(os.getcwd() + '/../..')
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = rtconfig.OUTPUT_NAME + rtconfig.TARGET_EXT
+
+# add rtconfig.h path to the assembler
+rtconfig.AFLAGS += ' -I' + str(Dir('#')) +' -I' + str(Dir('#')) + '/bsp'
+
+env = Environment(tools = ['mingw'],
+        AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+        CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
+        CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+        AR = rtconfig.AR, ARFLAGS = '-rc',
+        LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 10 - 0
bsp/gkipc/applications/SConscript

@@ -0,0 +1,10 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+
+CPPPATH = [cwd, cwd + '/../drivers', cwd + '/../libraries/inc']
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 41 - 0
bsp/gkipc/applications/main.c

@@ -0,0 +1,41 @@
+/*
+ * File      : main.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2017, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtthread.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef RT_USING_GMAC
+#include <drv_gmac.h>
+#endif
+
+int main(void)
+{
+#ifdef RT_USING_GMAC
+    rt_app_gk_gmac_init();
+#endif
+
+    printf("Hello\n");
+
+    return 0;
+}

+ 10 - 0
bsp/gkipc/armv6/SConscript

@@ -0,0 +1,10 @@
+from building import *
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+src += Glob('*.s')
+path = [cwd, cwd + '../../../include', cwd + '/../libraries/inc', cwd + '/../drivers']
+
+group = DefineGroup('armv6', src, depend = [''], CPPPATH = path)
+
+Return('group')

+ 376 - 0
bsp/gkipc/armv6/arm1176_mmu.gcc.s

@@ -0,0 +1,376 @@
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** Filename...: src/arm1176_mmu.gcc.s
+@** Source.....: src/arm1176_mmu.s
+@** Generator..: asm2gas.pl
+@** Note.......: DO NOT MODIFY THIS FILE BY HAND!
+@**
+@*******************************************************************************
+@*******************************************************************************
+
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** ARM1176 Startup, MMU initialization and data cache setup
+@**
+@** This module initialized the MMU in flat memory mode, all addresses are
+@** directly mapped, vitual addresses are equal to physical addresses. The
+@** MMU is required only to enable the cache mode of dedicated memory
+@** regions.
+@**
+@** Version: $Id: arm1176_mmu.gcc.s 9143 2012-04-25 09:33:55Z jrende $
+@**
+@** (C) Copyright 2012-2013 by Goke Microelectronics Shanghai Branch**
+@*******************************************************************************
+@*******************************************************************************
+
+    .text
+    .section ".ARM1176INIT"
+    .align 8
+
+    .extern _start
+    .extern _end_readonly
+    .extern |_start|
+    .extern |ARM1176_MMU_ttb0|
+    .extern |ARM1176_MMU_ttb1|
+	
+    .equ ARM1176_PHYSICAL_TTB0_BASE,      arm1176_mmu_ttb0 
+    .equ ARM1176_PHYSICAL_TTB1_BASE,      arm1176_mmu_ttb1 
+    .equ ARM1176_TTB_ENTRIES,             4096 
+
+    .if CPU_USE_GK710XS==1
+    .equ ARM1176_PHYSICAL_PERI_BASE,       0x90000000 
+    .else
+    .equ ARM1176_PHYSICAL_PERI_BASE,       0x60000000 
+    .endif
+    .equ ARM1176_PHYSICAL_PERI_SIZE,       0x20000000 
+    .equ ARM1176_REMAPPED_PERI_BASE,       ARM1176_PHYSICAL_PERI_BASE 
+
+    .equ ARM1176_PHYSICAL_PPM_BASE,        DDR_MEMORY_PPM_BASE 
+    .equ ARM1176_PHYSICAL_PPM_SIZE,        DDR_MEMORY_PPM_SIZE 
+    .equ ARM1176_REMAPPED_PPM_BASE,        ARM1176_PHYSICAL_PPM_BASE
+	
+    .equ ARM1176_PHYSICAL_RTOS_BASE,       DDR_MEMORY_OS_BASE 
+    .equ ARM1176_PHYSICAL_RTOS_SIZE,       DDR_MEMORY_OS_SIZE
+    .equ ARM1176_REMAPPED_RTOS_BASE,       ARM1176_PHYSICAL_RTOS_BASE
+
+@  use mmu map bsb address from 0xCxxxxxxx(DDR_MEMORY_BSB_BASE) to 0xD0000000|DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_REAMP_BASE,   0xD0000000
+    .equ ARM1176_PHYSICAL_BSB_BASE,        DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_SIZE,        DDR_MEMORY_BSB_SIZE 
+    .equ ARM1176_REMAPPED_BSB_BASE,        ARM1176_PHYSICAL_BSB_BASE|ARM1176_PHYSICAL_BSB_REAMP_BASE
+
+@  use mmu remap bsb address 0xCxxxxxxx(DDR_MEMORY_BSB_BASE) to ARM1176_REMAPPED_BSB_BASE+DDR_MEMORY_BSB_SIZE, it resolve bsb data revert.
+    .equ ARM1176_PHYSICAL_BSB_BASE,        DDR_MEMORY_BSB_BASE
+    .equ ARM1176_PHYSICAL_BSB_SIZE,        DDR_MEMORY_BSB_SIZE 
+    .equ ARM1176_REMAPPED_BSB_BASE_EXT,    ARM1176_REMAPPED_BSB_BASE+DDR_MEMORY_BSB_SIZE
+	
+	.equ ARM1176_PHYSICAL_DSP_BASE,        DDR_MEMORY_DSP_BASE 
+    .equ ARM1176_PHYSICAL_DSP_SIZE,        DDR_MEMORY_DSP_SIZE 
+    .equ ARM1176_REMAPPED_DSP_BASE,        ARM1176_PHYSICAL_DSP_BASE 
+	
+    .equ ARM1176_1MB_CACHE_NOBUFFER,      0x00000DEA  @ cachable/non-bufferable
+    .equ ARM1176_1MB_CACHE_BUFFER,        0x00000DEE  @ cachable/bufferable
+    .equ ARM1176_1MB_NOCACHE_NOBUFFER,    0x00000DE2  @ non-cachable/non-bufferable
+    .equ ARM1176_1MB_NORMAL_NOCACHE,      0x00001DE2  @ Normal memory, non-cachable/non-bufferable
+    .equ ARM1176_1MB_CACHE_BUFFER_RO,     0x000011EE  @ cachable/bufferable read-only
+    .equ ARM1176_1MB_NOCACHE_NOBUFFER_RO, 0x000011E2  @ non-cachable/non-bufferable read-only
+
+@*******************************************************************************
+@** Initialise the MMU
+@*******************************************************************************
+
+    .global ARM1176_MmuInitialise
+
+ARM1176_MmuInitialise:
+
+@*******************************************************************************
+@** save link register on r11 as we are using bl commands internally
+@*******************************************************************************
+
+    mov r11,lr
+
+@*******************************************************************************
+@** if MMU/MPU enabled - disable (useful for ARMulator tests)
+@*******************************************************************************
+
+    mrc p15,0,r0,c1,c0,0 @ read CP15 register 1 into r0
+    bic r0,r0,#0x1000    @ disable I-cache
+    bic r0,r0,#0x0004    @ disable D-cache
+    bic r0,r0,#0x0001    @ disable MMU
+    mcr p15,0,r0,c1,c0,0 @ write value back
+
+@*******************************************************************************
+@** MMU Configuration
+@**
+@** Configure system to use extended v6 format pagetables
+@** Set translation table base
+@** Specify v6 format pagetables with no subpages
+@** set bit 23 [XP] in CP15 control register.
+@** ARM1176 supports two translation tables
+@** Configure translation table base (TTB) control register cp15,c2
+@** to a value of all zeros, indicates we are using TTB register 0.
+@*******************************************************************************
+
+    mrc p15,0,r0,c1,c0,0 @ read CP15 register 1 into r0
+    mov r1,#0x800000
+    orr r0,r0,r1	 @ disable Subpage AP bits
+    mcr p15,0,r0,c1,c0,0 @ write value back
+    mov r0,#0x0
+    mcr p15,0,r0,c2,c0,2 @ Write Translation Table Base Control Register to 0, use Register 0
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    mcr p15,0,r0,c2,c0,0 @ Write Translation Table Base Register 0 to ARM1176_PHYSICAL_TTB0_BASE
+
+@*******************************************************************************
+@** PAGE TABLE generation
+@**
+@** Generate the page tables
+@** Build a flat translation table for the whole address space.
+@** ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
+@**
+@** |31................20|19..18|17|16| 15|14..12|11.10|9|8....5| 4|3.2|1.0|
+@** |section base address| 0   0|nG| S|APX|   TEX|  AP |P|Domain|XN|C B|1 0|
+@**
+@** Bits[31:20] Top 12 bits of VA is pointer into table
+@** nG[17]=0.   Non global, enables matching against ASID in the TLB when set.
+@** S[16]=0.    Indicates normal memory is shared when set.
+@** Access Permissions - configure for full read/write access in all modes
+@** APX[15]=0 and AP[11:10]=11
+@**
+@** Set attributes to normal memory, non cacheable.
+@** TEX[14:12]=001 and CB[3:2]= 00
+@** P[9]=0.     ECC enabled memory (not supported on ARM1136).
+@** Domain[5:8]=1111 = Set all pages to use domain 15
+@** XN[4]:=0    Execute never disabled.
+@** Bits[1:0]   Indicate entry is a 1MB section.
+@**
+@** r0 contains the address of the translation table base
+@** r1 is loop counter
+@** r2 is level1 descriptor (bits 19:0)
+@**
+@** use loop counter to create 4096 individual table entries
+@** this writes from address 0x7FFC down to 0x4000 in word steps (4bytes).
+@**
+@** In this example we will set the cacheable attribute in the first descriptor
+@**  only, so virtual memory from 0 to 1MB will be cacheable (write back mode).
+@** TEX[14:12]=000 and CB[3:2]=11
+@*******************************************************************************
+
+@*******************************************************************************
+@** create empty TTB entries to initialize entries 0..2047
+@** r0 = TTB base address
+@** r1 = unused
+@** r2 = unused
+@** r3 = virtual DDR address, upper 12 bits shifted 20 bits right (virt. index)
+@** r4 = remap size upper 12 bits shifted 20 bits right (table max. index)
+@** r5 = unused
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE       @ set the MMU table base address
+    ldr r1,=0x00000000                      @ 0x00000000 == disable access
+    ldr r2,=0x00000000                      @ remap addresses from 0x00000000..
+    ldr r3,=0x00000000                      @                   to 0x00000000..
+    ldr r4,=0x80000000                      @ fixed remap RAM size (2048MB)
+    bl  arm1176_update_mmu_table            @ update mmu table entries
+
+@*******************************************************************************
+@** set the peri
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_PERI_BASE
+    ldr r3,=ARM1176_REMAPPED_PERI_BASE
+    ldr r4,=ARM1176_PHYSICAL_PERI_SIZE
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the ppm
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_PPM_BASE
+    ldr r3,=ARM1176_REMAPPED_PPM_BASE
+    ldr r4,=ARM1176_PHYSICAL_PPM_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** set the rtos (nocache_section(1M)/code_heap(RTOSSIZE-1M))
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_NOCACHE_NOBUFFER
+    ldr r2,=ARM1176_PHYSICAL_RTOS_BASE
+    ldr r3,=ARM1176_REMAPPED_RTOS_BASE
+    ldr r4,=0x200000
+    bl  arm1176_update_mmu_table
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_RTOS_BASE+0x100000
+    ldr r3,=ARM1176_REMAPPED_RTOS_BASE+0x100000
+    ldr r4,=ARM1176_PHYSICAL_RTOS_SIZE-0x100000
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the bsb
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_BSB_BASE
+    ldr r3,=ARM1176_REMAPPED_BSB_BASE
+    ldr r4,=ARM1176_PHYSICAL_BSB_SIZE
+    bl  arm1176_update_mmu_table
+
+@*******************************************************************************
+@** set the bsb again for continues address for frame address
+@*******************************************************************************
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_BSB_BASE
+    ldr r3,=ARM1176_REMAPPED_BSB_BASE_EXT
+    ldr r4,=ARM1176_PHYSICAL_BSB_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** set the dsp
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,=ARM1176_1MB_CACHE_BUFFER
+    ldr r2,=ARM1176_PHYSICAL_DSP_BASE
+    ldr r3,=ARM1176_REMAPPED_DSP_BASE
+    ldr r4,=ARM1176_PHYSICAL_DSP_SIZE
+    bl  arm1176_update_mmu_table
+	
+@*******************************************************************************
+@** copy TTB0 into TTB1
+@*******************************************************************************
+
+    ldr r0,ARM1176_PHYSICAL_TTB0_BASE
+    ldr r1,ARM1176_PHYSICAL_TTB1_BASE
+    ldr r2,=ARM1176_TTB_ENTRIES
+    bl arm1176_copy_mmu_table
+
+@*******************************************************************************
+@** Setup domain control register
+@** Enable all domains to client mode
+@*******************************************************************************
+
+    mrc p15,0,r0,c3,c0,0 @ Read Domain Access Control Register
+    ldr r0,=0x55555555   @ Initialise every domain entry to b01 (client)
+    mcr p15,0,r0,c3,c0,0 @ Write Domain Access Control Register
+
+@*******************************************************************************
+@** Now the MMU is enabled, virtual to physical address translations will occur.
+@** This will affect the next instruction fetch.
+@**
+@** The two instructions currently in the ARM pipeline will have been fetched
+@** before the MMU was enabled. This property is useful because the next two
+@** instructions are safe even if new instruction fetches fail - If this
+@** routine was mapped out of the new virtual memory map, the branch to
+@** arm1176_BootLoaderMain would still succeed.
+@*******************************************************************************
+
+    mov r0,#0             @ move 0 into r0
+    mcr p15,0,r0,c7,c5,0  @ invalidate instruction cache
+    mcr p15,0,r0,c7,c6,0  @ invalidate data cache
+    mcr p15,0,r0,c7,c10,4 @ drain write barrier
+    mcr p15,0,r0,c8,c5,0  @ reset intruction TLB entries
+    mcr p15,0,r0,c8,c6,0  @ reset data TLB entries
+    mcr p15,0,r0,c8,c7,0  @ reset unified TLB entries
+
+    mrc p15,0,r0,c1,c0,0  @ read CP15 register c1 into r0
+    orr r0,r0,#0x00001000 @ enable I-cache
+    orr r0,r0,#0x00000004 @ enable D-cache
+    orr r0,r0,#0x00000001 @ enable MMU
+    orr r0,r0,#0x00400000 @ enable unaligned load/store
+    orr r0,r0,#0x00000100 @ system bit enabled
+    bic r0,r0,#0x00000200 @ rom bit disabled
+    mcr p15,0,r0,c1,c0,0  @ write r0 back to CP15 register c1
+    mov lr,r11            @ restore link register
+    bx lr                 @ branch back to caller
+
+@*******************************************************************************
+@** create TTB entries to remap 1MB junks of memory
+@** register arguments:
+@**   r0 = TTB base address
+@**   r1 = access mask, lower 20 bits only
+@**   r2 = physical address, upper 12 bits shifted 20 bits right (phys. index)
+@**   r3 = virtual address, upper 12 bits shifted 20 bits right (virt. index)
+@**   r4 = remap size upper 12 bits shifted 20 bits right (table max. index)
+@** internal used registers:
+@**   r5 = temporary vector to be written into TTB entry
+@*******************************************************************************
+
+arm1176_update_mmu_table:
+    lsr  r2,r2,#20	@ 1M
+    lsr  r3,r3,#20	@ 1M
+    lsr  r4,r4,#20	@ 1M
+    cmp  r4,#0x0
+    bxeq lr
+    add  r4,r4,r3
+arm1176_update_mmu_table_loop: @ update r4 times 1MB entries
+    orr  r5,r1,r2,LSL#20      @ r5 now contains full L1 descriptor to write
+    str  r5,[r0,r3,LSL#2]     @ store table entry at TTB base + loopcount*4
+    add  r3,r3,#1             @ increment virtual address index
+    add  r2,r2,#1             @ increment physical address index
+    cmp  r3,r4                @ check for last entry
+    bne  arm1176_update_mmu_table_loop
+    bx lr
+
+@*******************************************************************************
+@** copy one TTB into another
+@** register arguments:
+@**   r0 = address of 1st TTB
+@**   r1 = address of 2nd TTB
+@**   r2 = table entry count
+@** internal used registers:
+@**   r3 = temporary register holding read/wrrite values
+@*******************************************************************************
+
+arm1176_copy_mmu_table:
+    cmp  r2,#0x0
+    bxeq lr
+arm1176_copy_mmu_table_loop: @ load entry from 1st table
+    ldr  r3,[r0]            @ store entry into 2nd table
+    str  r3,[r1]            @ store table entry at TTB base + loopcount*4
+    add  r0,r0,#4           @ increment 1st table address by 4 byte
+    add  r1,r1,#4           @ increment 2nd table address  by 4 byte
+    sub  r2,r2,#1           @ decrement entry counter by 1
+    cmp  r2,#0x0
+    bne  arm1176_copy_mmu_table_loop
+    bx lr
+
+@*******************************************************************************
+@** local variables containing far addresses
+@*******************************************************************************
+
+    .ltorg
+
+arm1176_image_ro_base:
+    .long _start
+arm1176_image_ro_limit:
+    .long _end_readonly
+arm1176_image_start:
+    .long _start
+arm1176_mmu_ttb0:
+    .long ARM1176_MMU_ttb0
+arm1176_mmu_ttb1:
+    .long ARM1176_MMU_ttb1
+arm1176_mmu_video_cached_ptr:
+    .long arm1176_mmu_video_cached
+arm1176_mmu_video_cached:
+    .long 0x0
+
+    .global arm1176_mmu_video_cached
+    .weak arm1176_mmu_video_cached
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+
+    .end

+ 64 - 0
bsp/gkipc/armv6/arm1176_mmu_ttb.c

@@ -0,0 +1,64 @@
+/*
+********************************************************************************
+********************************************************************************
+**
+** \file        ./boot/startup/src/arm1176_mmu_ttb.c
+**
+** \version     $Id: arm1176_mmu_ttb.c 5280 2011-02-21 16:39:28Z wlaris $
+**
+** \brief       ARM1176 MMU page table.
+**
+** This files contains ARM1176 specific MMU page table variables.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+********************************************************************************
+*/
+#include <stdint.h>
+#include "arm1176_mmu_ttb.h"
+
+#define ARM1176_MMU_TTB_ALIGNMENT 14
+#define ARM1176_RVS_ALIGN(bits) __align(1UL<<bits)
+#define ARM1176_GCC_ALIGN(bits) __attribute__((aligned(1UL<<bits)))
+
+#if !defined(__GNUC__)
+#define ARM1176_MMU_ALIGN_PRE ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+#endif
+
+#if defined(__GNUC__)
+#define ARM1176_MMU_ALIGN_POST ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+#endif
+
+#if defined(__LINT__)
+#undef ARM1176_RVS_ALIGN
+#define ARM1176_RVS_ALIGN(bits)
+#undef ARM1176_GCC_ALIGN
+#define ARM1176_GCC_ALIGN(bits)
+#endif
+
+/*lint -save -e785 */
+
+#if !defined(__GNUC__)
+
+    ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+    uint32_t ARM1176_MMU_ttb0[ARM1176_MMU_TTB_ENTRIES] __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+    ARM1176_RVS_ALIGN(ARM1176_MMU_TTB_ALIGNMENT)
+    uint32_t ARM1176_MMU_ttb1[ARM1176_MMU_TTB_ENTRIES] __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+#endif
+
+#if defined(__GNUC__)
+
+    uint32_t ARM1176_MMU_ttb0[ARM1176_MMU_TTB_ENTRIES]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+    uint32_t ARM1176_MMU_ttb1[ARM1176_MMU_TTB_ENTRIES]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+#endif
+
+/*lint -restore */

+ 34 - 0
bsp/gkipc/armv6/arm1176_mmu_ttb.h

@@ -0,0 +1,34 @@
+/*
+********************************************************************************
+********************************************************************************
+**
+** \file        ./boot/startup/src/arm1176_mmu_ttb.h
+**
+** \version     $Id: arm1176_mmu_ttb.h 5280 2011-02-21 16:39:28Z wlaris $
+**
+** \brief       ARM1176 MMU page table.
+**
+** This files contains ARM1176 specific MMU page table variables.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+********************************************************************************
+*/
+#ifndef STARTUP_ARM1176_MMU_TTB_H
+#define STARTUP_ARM1176_MMU_TTB_H
+
+#define ARM1176_MMU_TTB_ENTRIES 4096
+
+#define ARM1176_MMU_TTB_NUMS    8
+
+#define ARM1176_1MB_NOCACHE_BUFFER      0x00000DE6  // non-cachable/bufferable
+#define ARM1176_1MB_CACHE_NOBUFFER      0x00000DEA  // cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER        0x00000DEE  // cachable/bufferable
+#define ARM1176_1MB_NOCACHE_NOBUFFER    0x00000DE2  // non-cachable/non-bufferable
+#define ARM1176_1MB_NORMAL_NOCACHE      0x00001DE2  // Normal memory, non-cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER_RO     0x000011EE  // cachable/bufferable read-only
+#define ARM1176_1MB_NOCACHE_NOBUFFER_RO 0x000011E2  // non-cachable/non-bufferable read-only
+#endif

+ 62 - 0
bsp/gkipc/armv6/arm1176_vfp_fast_gcc.s

@@ -0,0 +1,62 @@
+@*******************************************************************************
+@*******************************************************************************
+@**
+@** ARM1176 Startup, VFP initialization for fast mode
+@**
+@** This module initializes the VFP co-processor unit in fast mode
+@**
+@** Version: $Id: arm1176_vfp_fast.s 5280 2011-02-21 16:39:28Z wlaris $
+@**
+@** (C) Copyright 2006-2010 by Fujitsu Microelectronics Europe GmbH;**
+@** (C) Copyright 2010-2011 by Fujitsu Semiconductor Europe GmbH
+@*******************************************************************************
+@*******************************************************************************
+#if ARM1176_USE_VFP == 1
+    .text
+    .section ".ARM1176INIT"
+    .code 32
+
+@*******************************************************************************
+@** Bit pattern to enable RunFast mode
+@** - FPSCR [24] - Flush to Zero mode
+@** - FPSCR [25] - Default NaN mode
+@*******************************************************************************
+
+    .equ ARM1176_VFP_ENABLE,   0x40000000 @
+    .equ ARM1176_VFP_FASTMODE, 0x03000000 @ 2_11:SHL:24
+
+@*******************************************************************************
+@** enable the fast-mode of the VFP block
+@*******************************************************************************
+
+    .global ARM1176_VfpSetFastmode
+
+ARM1176_VfpSetFastmode:
+    mov r0,#ARM1176_VFP_FASTMODE
+    fmxr fpscr,r0
+    bx lr
+
+@*******************************************************************************
+@** enable the the VFP block
+@*******************************************************************************
+
+    .global ARM1176_VfpInitialise
+
+ARM1176_VfpInitialise:
+    mrc p15,0,r1,c1,c0,2  @ r1 = Access Control Register
+    orr r1,r1,#(0xf<<20)  @ enable full access for p10,11
+    mcr p15,0,r1,c1,c0,2  @ Access Control Register = r1
+    mov r1,#0             @
+    mcr p15,0,r1,c7,c5,4  @ flush prefetch buffer because of FMXR below and
+                          @ CP 10 & 11 were only just enabled
+    @ Enable VFP itself
+    mov  r0,#ARM1176_VFP_ENABLE
+    fmxr fpexc,r0
+    bx   lr
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+
+    .end
+#endif

+ 160 - 0
bsp/gkipc/armv6/context_gcc.s

@@ -0,0 +1,160 @@
+/*
+ * File      : context.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety    copy from mini2440
+ */
+
+#define NOINT			0xc0
+
+.globl __delay
+__delay:
+		subs	r0, r0, #1
+#if 1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+		movls	pc, lr
+		subs	r0, r0, #1
+#endif
+		bhi	__delay
+		mov	pc, lr
+
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+	mrs r0, cpsr
+	orr r1, r0, #NOINT
+	msr cpsr_c, r1
+	mov pc, lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+	msr cpsr, r0
+	mov pc, lr
+
+
+    .globl  restore_context
+    @.func   restore_context
+    
+    .globl  save_context
+    @.func   save_context
+
+save_context:
+    stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	mov pc, lr
+    bx lr                 @ branch back to caller
+
+
+restore_context:
+    ldr	sp, [r0]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	spsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}^	@ pop new task r0-r12, lr & pc
+
+    
+    
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
+ * r0 --> from
+ * r1 --> to
+ */
+.globl rt_hw_context_switch
+rt_hw_context_switch:
+	stmfd	sp!, {lr}		@ push pc (lr should be pushed in place of PC)
+	stmfd	sp!, {r0-r12, lr}	@ push lr & register file
+
+	mrs	r4, cpsr
+	stmfd	sp!, {r4}		@ push cpsr
+	mrs	r4, spsr
+	stmfd	sp!, {r4}		@ push spsr
+
+	str	sp, [r0]			@ store sp in preempted tasks TCB
+	ldr	sp, [r1]			@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	spsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}^	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to);
+ * r0 --> to
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+	ldr	sp, [r0]		@ get new task stack pointer
+
+	ldmfd	sp!, {r4}		@ pop new task spsr
+	msr	spsr_cxsf, r4
+	ldmfd	sp!, {r4}		@ pop new task cpsr
+	msr	cpsr_cxsf, r4
+
+	ldmfd	sp!, {r0-r12, lr, pc}	@ pop new task r0-r12, lr & pc
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.globl rt_thread_switch_interrupt_flag
+.globl rt_interrupt_from_thread
+.globl rt_interrupt_to_thread
+.globl rt_hw_context_switch_interrupt
+rt_hw_context_switch_interrupt:
+	ldr r2, =rt_thread_switch_interrupt_flag
+	ldr r3, [r2]
+	cmp r3, #1
+	beq _reswitch
+	mov r3, #1				@ set rt_thread_switch_interrupt_flag to 1
+	str r3, [r2]
+	ldr r2, =rt_interrupt_from_thread	@ set rt_interrupt_from_thread
+	str r0, [r2]
+_reswitch:
+	ldr r2, =rt_interrupt_to_thread		@ set rt_interrupt_to_thread
+	str r1, [r2]
+	mov pc, lr

+ 297 - 0
bsp/gkipc/armv6/cpuport.c

@@ -0,0 +1,297 @@
+/*
+ * File      : cpu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define ICACHE_MASK (rt_uint32_t)(1 << 12)
+#define DCACHE_MASK (rt_uint32_t)(1 << 2)
+
+extern void machine_reset(void);
+extern void machine_shutdown(void);
+
+#ifdef __GNUC__
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    __asm__ __volatile__(           \
+        "mrc  p15,0,r0,c1,c0,0\n\t" \
+        "orr  r0,r0,%0\n\t"         \
+        "mcr  p15,0,r0,c1,c0,0"     \
+        :                           \
+        :"r" (bit)                  \
+        :"memory");
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    __asm__ __volatile__(           \
+        "mrc  p15,0,r0,c1,c0,0\n\t" \
+        "bic  r0,r0,%0\n\t"         \
+        "mcr  p15,0,r0,c1,c0,0"     \
+        :                           \
+        :"r" (bit)                  \
+        :"memory");
+}
+#endif
+
+#ifdef __CC_ARM
+rt_inline rt_uint32_t cp15_rd(void)
+{
+    rt_uint32_t i;
+
+    __asm
+    {
+        mrc p15, 0, i, c1, c0, 0
+    }
+
+    return i;
+}
+
+rt_inline void cache_enable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+rt_inline void cache_disable(rt_uint32_t bit)
+{
+    rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, bit
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+#endif
+
+/**
+ * enable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_enable()
+{
+    cache_enable(ICACHE_MASK);
+}
+
+/**
+ * disable I-Cache
+ *
+ */
+void rt_hw_cpu_icache_disable()
+{
+    cache_disable(ICACHE_MASK);
+}
+
+/**
+ * return the status of I-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_icache_status()
+{
+    return (cp15_rd() & ICACHE_MASK);
+}
+
+/**
+ * enable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_enable()
+{
+    cache_enable(DCACHE_MASK);
+}
+
+/**
+ * disable D-Cache
+ *
+ */
+void rt_hw_cpu_dcache_disable()
+{
+    cache_disable(DCACHE_MASK);
+}
+
+/**
+ * return the status of D-Cache
+ *
+ */
+rt_base_t rt_hw_cpu_dcache_status()
+{
+    return (cp15_rd() & DCACHE_MASK);
+}
+
+/**
+ * reset cpu by dog's time-out
+ *
+ */
+void rt_hw_cpu_reset()
+{
+
+    rt_kprintf("Restarting system...\n");
+    machine_reset();
+
+    while(1);   /* loop forever and wait for reset to happen */
+
+    /* NEVER REACHED */
+}
+
+/**
+ *  shutdown CPU
+ *
+ */
+void rt_hw_cpu_shutdown()
+{
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    level = rt_hw_interrupt_disable();
+    machine_shutdown();
+    while (level)
+    {
+        RT_ASSERT(0);
+    }
+}
+
+#ifdef RT_USING_CPU_FFS
+/**
+ * This function finds the first bit set (beginning with the least significant bit)
+ * in value and return the index of that bit.
+ *
+ * Bits are numbered starting at 1 (the least significant bit).  A return value of
+ * zero from any of these functions means that the argument was zero.
+ *
+ * @return return the index of the first bit set. If value is 0, then this function
+ * shall return 0.
+ */
+#if defined(__CC_ARM)
+int __rt_ffs(int value)
+{
+    register rt_uint32_t x;
+
+    if (value == 0)
+        return value;
+
+    __asm
+    {
+        rsb x, value, #0
+        and x, x, value
+        clz x, x
+        rsb x, x, #32
+    }
+
+    return x;
+}
+#elif defined(__IAR_SYSTEMS_ICC__)
+int __rt_ffs(int value)
+{
+    if (value == 0)
+        return value;
+
+    __ASM("RSB  r4, r0, #0");
+    __ASM("AND  r4, r4, r0");
+    __ASM("CLZ  r4, r4");
+    __ASM("RSB  r0, r4, #32");
+}
+#elif defined(__GNUC__)
+int __rt_ffs(int value)
+{
+    if (value == 0)
+        return value;
+
+    value &= (-value);
+    asm ("clz %0, %1": "=r"(value) :"r"(value));
+
+    return (32 - value);
+}
+#endif
+
+#endif
+
+/*
+rt_base_t rt_hw_interrupt_disable()
+{
+    unsigned long old;
+    unsigned long tmp;
+
+    __asm__ __volatile__ (
+        "mrs %0, cpsr\n"
+        "orr %1, %0, #0xc0\n"
+        "msr cpsr_c, %1"
+        : "=r" (old), "=r" (tmp)
+        :
+        : "memory");
+
+    return old;
+}
+
+void rt_hw_interrupt_enable(rt_base_t level)
+{
+    unsigned long tmp;
+
+
+    __asm__ __volatile__ (
+        "mrs %0, cpsr\n"
+        "bic %0, %0, #0xc0\n"
+        "msr cpsr_c, %0"
+        : "=r" (tmp)
+        :
+        : "memory");
+
+}
+*/
+/*
+rt_base_t rt_hw_interrupt_disable()
+{
+    unsigned long old;
+    unsigned long tmp;
+
+    __asm__ __volatile__( "mrs %0,cpsr"     : "=r"(old) : "r"(tmp) );
+    __asm__ __volatile__( "orr %0,%1,#0xC0" : "=r"(tmp) : "r"(old) );
+    __asm__ __volatile__( "msr cpsr_c,%0"   : : "r"(tmp) );
+
+    return old;
+}
+
+void rt_hw_interrupt_enable(rt_base_t level)
+{
+
+   asm volatile ( "msr cpsr_c,%0" : : "r"(level) );
+
+}
+*/
+
+/*@}*/

+ 81 - 0
bsp/gkipc/armv6/gk7101.h

@@ -0,0 +1,81 @@
+/*
+ * File      : at91sam926x.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+
+ */
+
+#ifndef GK7101_H
+#define GK7101_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rtthread.h>
+
+
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE		0x10
+#define FIQMODE			0x11
+#define IRQMODE			0x12
+#define SVCMODE			0x13
+#define ABORTMODE		0x17
+#define UNDEFMODE		0x1b
+#define MODEMASK		0x1f
+#define NOINT			0xc0
+
+struct rt_hw_register
+{
+	rt_uint32_t r0;
+	rt_uint32_t r1;
+	rt_uint32_t r2;
+	rt_uint32_t r3;
+	rt_uint32_t r4;
+	rt_uint32_t r5;
+	rt_uint32_t r6;
+	rt_uint32_t r7;
+	rt_uint32_t r8;
+	rt_uint32_t r9;
+	rt_uint32_t r10;
+	rt_uint32_t fp;
+	rt_uint32_t ip;
+	rt_uint32_t sp;
+	rt_uint32_t lr;
+	rt_uint32_t pc;
+	rt_uint32_t cpsr;
+	rt_uint32_t ORIG_r0;
+};
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+extern struct clk *clk_get(const char *id);
+extern rt_uint32_t clk_get_rate(struct clk *clk);
+extern void rt_hw_clock_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+

+ 148 - 0
bsp/gkipc/armv6/interrupt.c

@@ -0,0 +1,148 @@
+/*
+ * File      : interrupt.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include "gk7101.h"
+
+#define MAX_HANDLERS    (64)
+
+extern rt_uint32_t rt_interrupt_nest;
+
+/* exception and interrupt handler table */
+struct rt_irq_desc irq_desc[MAX_HANDLERS];
+
+rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+
+/* --------------------------------------------------------------------
+ *  Interrupt initialization
+ * -------------------------------------------------------------------- */
+
+
+
+void rt_hw_interrupt_mask(int irq);
+void rt_hw_interrupt_umask(int irq);
+
+rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
+{
+    rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
+    return RT_NULL;
+}
+
+
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+    //rt_int32_t i;
+    //register rt_uint32_t idx;
+
+
+    /* init interrupt nest, and context in thread sp */
+    rt_interrupt_nest = 0;
+    rt_interrupt_from_thread = 0;
+    rt_interrupt_to_thread = 0;
+    rt_thread_switch_interrupt_flag = 0;
+}
+
+
+/**
+ * This function will mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_mask(int irq)
+{
+
+}
+
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int irq)
+{
+
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param handler the interrupt service routine to be installed
+ * @param param the interrupt service function parameter
+ * @param name the interrupt name
+ * @return old handler
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+                                    void *param, char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+
+    if(vector < MAX_HANDLERS)
+    {
+        old_handler = irq_desc[vector].handler;
+        if (handler != RT_NULL)
+        {
+
+#ifdef RT_USING_INTERRUPT_INFO
+            rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
+            irq_desc[vector].counter = 0;
+#endif
+            irq_desc[vector].handler = (rt_isr_handler_t)handler;
+            irq_desc[vector].param = param;
+        }
+    }
+
+    return old_handler;
+}
+
+/*@}*/
+
+
+
+#ifdef RT_USING_FINSH
+void list_irq(void)
+{
+    int irq;
+
+#ifdef RT_USING_INTERRUPT_INFO
+    rt_kprintf("number\tcount\tname\n");
+    for (irq = 0; irq < MAX_HANDLERS; irq++)
+    {
+        if (rt_strncmp(irq_desc[irq].name, "default", sizeof("default")))
+        {
+            rt_kprintf("%02ld: %10ld  %s\n", irq, irq_desc[irq].counter, irq_desc[irq].name);
+        }
+    }
+#endif
+}
+
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(list_irq, list system irq);
+
+#endif
+
+

+ 563 - 0
bsp/gkipc/armv6/mmu.c

@@ -0,0 +1,563 @@
+/*
+ * File      : mmu.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "mmu.h"
+#include "rtthread.h"
+
+#ifdef __CC_ARM
+void mmu_setttbase(rt_uint32_t i)
+{
+	register rt_uint32_t value;
+
+   /* Invalidates all TLBs.Domain access is selected as
+    * client by configuring domain access register,
+    * in that case access controlled by permission value
+    * set by page table entry
+    */
+	value = 0;
+    __asm
+    {
+        mcr p15, 0, value, c8, c7, 0
+	}
+
+	value = 0x55555555;
+	__asm
+	{
+        mcr p15, 0, value, c3, c0, 0
+        mcr p15, 0, i, c2, c0, 0
+    }
+}
+
+void mmu_set_domain(rt_uint32_t i)
+{
+    __asm
+    {
+        mcr p15,0, i, c3, c0,  0
+    }
+}
+
+void mmu_enable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x01
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_icache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x1000
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_dcache()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x04
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_enable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        orr value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_disable_alignfault()
+{
+    register rt_uint32_t value;
+
+    __asm
+    {
+        mrc p15, 0, value, c1, c0, 0
+        bic value, value, #0x02
+        mcr p15, 0, value, c1, c0, 0
+    }
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+    __asm
+    {
+        mcr p15, 0, index, c7, c14, 2
+    }
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while(ptr < buffer + size)
+    {
+    	__asm
+    	{
+    		MCR p15, 0, ptr, c7, c14, 1
+    	}
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		__asm
+		{
+			MCR p15, 0, ptr, c7, c10, 1
+		}
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		__asm
+		{
+			MCR p15, 0, ptr, c7, c6, 1
+		}
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_tlb()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+    __asm
+    {
+        mcr p15, 0, value, c8, c7, 0
+    }
+}
+
+void mmu_invalidate_icache()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm
+    {
+        mcr p15, 0, value, c7, c5, 0
+    }
+}
+
+
+void mmu_invalidate_dcache_all()
+{
+    register rt_uint32_t value;
+
+    value = 0;
+
+    __asm
+    {
+        mcr p15, 0, value, c7, c6, 0
+    }
+}
+#elif defined(__GNUC__)
+void mmu_setttbase(register rt_uint32_t i)
+{
+	//register rt_uint32_t value;
+
+   /* Invalidates all TLBs.Domain access is selected as
+    * client by configuring domain access register,
+    * in that case access controlled by permission value
+    * set by page table entry
+    */
+#if 0
+	value = 0;
+	asm ("mcr p15, 0, %0, c8,c7, 0"::"r"(value));
+
+	value = 0x55555555;
+	asm ("mcr p15, 0, %0, c3,c0, 0"::"r"(value));
+	asm ("mcr p15, 0, %0, c2,c0, 0"::"r"(i));
+#endif
+
+	asm (
+    	"mrc p15,0,r0,c1,c0,0 \r\n"
+        "mov r1,#0x800000  \r\n"
+        "orr r0,r0,r1	 @ disable Subpage AP bits  \r\n"
+        "mcr p15,0,r0,c1,c0,0 @ write value back  \r\n"
+        "mov r0,#0x0  \r\n"
+        "mcr p15,0,r0,c2,c0,2 @ W  \r\n"
+    );
+    asm("mcr p15,0,%0,c2,c0,0"::"r"(i));
+}
+
+void mmu_set_domain(register rt_uint32_t i)
+{
+	asm ("mcr p15,0, %0, c3, c0,  0": :"r" (i));
+}
+
+void mmu_enable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= 0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~0x1;
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_icache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 12);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_dcache()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 2);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_enable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i |= (1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_disable_alignfault()
+{
+	register rt_uint32_t i;
+
+	/* read control register */
+	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
+
+	i &= ~(1 << 1);
+
+	/* write back to control register */
+	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i));
+}
+
+void mmu_clean_invalidated_cache_index(int index)
+{
+	asm ("mcr p15, 0, %0, c7, c14, 2": :"r" (index));
+}
+
+void mmu_clean_invalidated_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+    unsigned int ptr;
+
+    ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+    while(ptr < buffer + size)
+    {
+    	asm ("mcr p15, 0, %0, c7, c14, 1": :"r" (ptr));
+        ptr += CACHE_LINE_SIZE;
+    }
+}
+
+
+void mmu_clean_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		asm ("mcr p15, 0, %0, c7, c10, 1": :"r" (ptr));
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_dcache(rt_uint32_t buffer, rt_uint32_t size)
+{
+	unsigned int ptr;
+
+	ptr = buffer & ~(CACHE_LINE_SIZE - 1);
+
+	while (ptr < buffer + size)
+	{
+		asm ("mcr p15, 0, %0, c7, c6, 1": :"r" (ptr));
+		ptr += CACHE_LINE_SIZE;
+	}
+}
+
+void mmu_invalidate_tlb()
+{
+	asm ("mcr p15, 0, %0, c8, c7, 0": :"r" (0));
+}
+
+void mmu_invalidate_icache()
+{
+	asm ("mcr p15, 0, %0, c7, c5, 0": :"r" (0));
+}
+
+void mmu_invalidate_dcache_all()
+{
+    asm ("mcr p15, 0, %0, c7, c6, 0": :"r" (0));
+}
+#endif
+
+/* level1 page table */
+//static volatile unsigned int _page_table[4*1024] __attribute__((aligned(16*1024)));
+#define ARM1176_GCC_ALIGN(bits) __attribute__((aligned(1UL<<bits)))
+#define ARM1176_MMU_TTB_ALIGNMENT 14
+static volatile unsigned int _page_table[4096]
+    ARM1176_GCC_ALIGN(ARM1176_MMU_TTB_ALIGNMENT) __attribute__ ((section(".nocache_buffer"))) = { 0x000011E2UL };
+
+void mmu_setmtt(rt_uint32_t vaddrStart, rt_uint32_t vaddrEnd, rt_uint32_t paddrStart, rt_uint32_t attr)
+{
+    volatile rt_uint32_t *pTT;
+    volatile int i,nSec;
+    pTT=(rt_uint32_t *)_page_table+(vaddrStart>>20);
+    nSec=(vaddrEnd>>20)-(vaddrStart>>20);
+    for(i=0;i<=nSec;i++)
+    {
+		*pTT = attr |(((paddrStart>>20)+i)<<20);
+		pTT++;
+    }
+}
+
+
+void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb)
+{
+    int i;
+    int fcnt = 0;
+
+    rt_kprintf("page table@%p\n", ptb);
+    for (i = 0; i < 1024*4; i++)
+    {
+        rt_uint32_t pte1 = ptb[i];
+        if ((pte1 & 0x3) == 0)
+        {
+            rt_kprintf("%03x: ", i);
+            fcnt++;
+            if (fcnt == 16)
+            {
+                rt_kprintf("fault\n");
+                fcnt = 0;
+            }
+            continue;
+        }
+        if (fcnt != 0)
+        {
+            rt_kprintf("fault\n");
+            fcnt = 0;
+        }
+
+        rt_kprintf("%03x: %08x: ", i, pte1);
+        if ((pte1 & 0x3) == 0x3)
+        {
+            rt_kprintf("LPAE\n");
+        }
+        else if ((pte1 & 0x3) == 0x1)
+        {
+            rt_kprintf("pte,ns:%d,domain:%d\n",
+                       (pte1 >> 3) & 0x1, (pte1 >> 5) & 0xf);
+            /*
+             *rt_hw_cpu_dump_page_table_2nd((void*)((pte1 & 0xfffffc000)
+             *                               - 0x80000000 + 0xC0000000));
+             */
+        }
+        else if (pte1 & (1 << 18))
+        {
+            rt_kprintf("super section,ns:%d,ap:%x,xn:%d,texcb:%02x\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       ((pte1 >> 10) | (pte1 >> 2)) & 0x1f);
+        }
+        else
+        {
+            rt_kprintf("section,ns:%d,ap:%x,"
+                       "xn:%d,texcb:%02x,domain:%d\n",
+                       (pte1 >> 19) & 0x1,
+                       ((pte1 >> 13) | (pte1 >> 10))& 0xf,
+                       (pte1 >> 4) & 0x1,
+                       (((pte1 & (0x7 << 12)) >> 10) |
+                        ((pte1 &        0x0c) >>  2)) & 0x1f,
+                       (pte1 >> 5) & 0xf);
+        }
+    }
+}
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size)
+{
+	/* disable I/D cache */
+	mmu_disable_dcache();
+	mmu_disable_icache();
+	mmu_disable();
+	mmu_invalidate_tlb();
+
+	/* set page table */
+	for (; size > 0; size--)
+	{
+		mmu_setmtt(mdesc->vaddr_start, mdesc->vaddr_end,
+			mdesc->paddr_start, mdesc->attr);
+		mdesc++;
+	}
+
+	/* set MMU table address */
+	mmu_setttbase((rt_uint32_t)_page_table);
+
+    /* enables MMU */
+    mmu_enable();
+
+    /* enable Instruction Cache */
+    mmu_enable_icache();
+
+    /* enable Data Cache */
+    mmu_enable_dcache();
+
+    mmu_invalidate_icache();
+    mmu_invalidate_dcache_all();
+}
+
+
+
+

+ 73 - 0
bsp/gkipc/armv6/mmu.h

@@ -0,0 +1,73 @@
+/*
+ * File      : mmu.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef __MMU_H__
+#define __MMU_H__
+
+#include <rtthread.h>
+
+#define CACHE_LINE_SIZE	32
+
+#define DESC_SEC		(0x2|(1<<4))
+#define CB				(3<<2)  //cache_on, write_back
+#define CNB				(2<<2)  //cache_on, write_through
+#define NCB				(1<<2)  //cache_off,WR_BUF on
+#define NCNB			(0<<2)  //cache_off,WR_BUF off
+#define AP_RW			(3<<10) //supervisor=RW, user=RW
+#define AP_RO			(2<<10) //supervisor=RW, user=RO
+
+#define DOMAIN_FAULT	(0x0)
+#define DOMAIN_CHK		(0x1)
+#define DOMAIN_NOTCHK	(0x3)
+#define DOMAIN0			(0x0<<5)
+#define DOMAIN1			(0x1<<5)
+
+#define DOMAIN0_ATTR	(DOMAIN_CHK<<0)
+#define DOMAIN1_ATTR	(DOMAIN_FAULT<<2)
+
+#define RW_CB		(AP_RW|DOMAIN0|CB|DESC_SEC)		/* Read/Write, cache, write back */
+#define RW_CNB		(AP_RW|DOMAIN0|CNB|DESC_SEC)	/* Read/Write, cache, write through */
+#define RW_NCNB		(AP_RW|DOMAIN0|NCNB|DESC_SEC)	/* Read/Write without cache and write buffer */
+#define RW_FAULT	(AP_RW|DOMAIN1|NCNB|DESC_SEC)	/* Read/Write without cache and write buffer */
+
+#define ARM1176_1MB_NOCACHE_BUFFER      0x00000DE6  // non-cachable/bufferable
+#define ARM1176_1MB_CACHE_NOBUFFER      0x00000DEA  // cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER        0x00000DEE  // cachable/bufferable
+#define ARM1176_1MB_NOCACHE_NOBUFFER    0x00000DE2  // non-cachable/non-bufferable
+#define ARM1176_1MB_NORMAL_NOCACHE      0x00001DE2  // Normal memory, non-cachable/non-bufferable
+#define ARM1176_1MB_CACHE_BUFFER_RO     0x000011EE  // cachable/bufferable read-only
+#define ARM1176_1MB_NOCACHE_NOBUFFER_RO 0x000011E2  // non-cachable/non-bufferable read-only
+
+
+struct mem_desc {
+	rt_uint32_t vaddr_start;
+	rt_uint32_t vaddr_end;
+	rt_uint32_t paddr_start;
+	rt_uint32_t attr;
+};
+
+void rt_hw_mmu_init(struct mem_desc *mdesc, rt_uint32_t size);
+void rt_hw_cpu_dump_page_table(rt_uint32_t *ptb);
+
+#endif
+

+ 39 - 0
bsp/gkipc/armv6/reset.c

@@ -0,0 +1,39 @@
+/*
+ * File      : reset.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "gk7101.h"
+
+
+
+void machine_reset(void)
+{
+
+}
+
+void machine_shutdown(void)
+{
+}
+
+/*@}*/

+ 27 - 0
bsp/gkipc/armv6/rtos.h

@@ -0,0 +1,27 @@
+/*!
+********************************************************************************
+**
+** \file        ./GKOS2/inc/rtos_lib.h
+**
+** \brief       RTOS user interface
+**
+** This file contains all public API functions and definitions to use the
+** RTOS real time operating system within an application.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. Goke SEMICONDUCTOR
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+********************************************************************************
+*/
+#ifndef RTOS__H
+#define RTOS__H
+
+#include "rtos_lib.h"
+#include "rtos_memory.h"
+/*
+********************************************************************************
+** end of file
+********************************************************************************
+*/
+#endif /* RTOS__H */

+ 1450 - 0
bsp/gkipc/armv6/rtos_lib.c

@@ -0,0 +1,1450 @@
+#include <sys/time.h>
+#include <time.h>
+#include "rtos_lib.h"
+#include "gd_timer.h"
+#include "gm_debug.h"
+#include "rtthread.h"
+#include "shell.h"
+
+#ifdef RT_USING_FINSH
+#include "shell.h"
+#endif
+
+//#define CACHE_MEM_MANAGE
+#define CACHE_MEM_SIZE  0x200000//1152k
+#define CACHE_DSP_SIZE  0x330000//3168k
+
+#define CACHE_LINE_SIZE     32
+#define CACHE_LINE_MASK     ~(CACHE_LINE_SIZE - 1)
+
+static int cache_check_end = 0;
+static int cache_check_start = 1;
+//static int cache_check_fail_halt = 0;
+void RTOS_MMU_ChangeMapEntry(U32 vaddrStart, U32 vaddrEnd, U32 paddrStart, U32 attr);
+
+static inline void __delay(int loops);
+
+u32 cpu_cpsr;
+#define HZ      RT_TICK_PER_SECOND
+
+#define LPS_PREC 8
+
+#define jiffies raid6_jiffies()
+
+static inline void __delay(int loops)
+{
+    return;
+}
+
+static inline unsigned int raid6_jiffies(void)
+{
+    //struct timeval tv;
+    //gettimeofday(&tv, NULL);
+    //return tv.tv_sec*1000 + tv.tv_usec/1000;
+    return rt_tick_get()*1000;
+}
+
+static unsigned long  calibrate_delay_converge(void)
+{
+    /* First stage - slowly accelerate to find initial bounds */
+    unsigned long lpj, lpj_base, ticks, loopadd, loopadd_base, chop_limit;
+    int trials = 0, band = 0, trial_in_band = 0;
+
+    lpj = (1<<12);
+
+    /* wait for "start of" clock tick */
+    ticks = jiffies;
+    while (ticks == jiffies)
+        ; /* nothing */
+    /* Go .. */
+    ticks = jiffies;
+    do {
+        if (++trial_in_band == (1<<band)) {
+            ++band;
+            trial_in_band = 0;
+        }
+        __delay(lpj * band);
+        trials += band;
+    } while (ticks == jiffies);
+    /*
+     * We overshot, so retreat to a clear underestimate. Then estimate
+     * the largest likely undershoot. This defines our chop bounds.
+     */
+    trials -= band;
+    loopadd_base = lpj * band;
+    lpj_base = lpj * trials;
+
+recalibrate:
+    lpj = lpj_base;
+    loopadd = loopadd_base;
+
+    /*
+     * Do a binary approximation to get lpj set to
+     * equal one clock (up to LPS_PREC bits)
+     */
+    chop_limit = lpj >> LPS_PREC;
+    while (loopadd > chop_limit) {
+        lpj += loopadd;
+        ticks = jiffies;
+        while (ticks == jiffies)
+            ; /* nothing */
+        ticks = jiffies;
+        __delay(lpj);
+        if (jiffies != ticks)   /* longer than 1 tick */
+            lpj -= loopadd;
+        loopadd >>= 1;
+    }
+    /*
+     * If we incremented every single time possible, presume we've
+     * massively underestimated initially, and retry with a higher
+     * start, and larger range. (Only seen on x86_64, due to SMIs)
+     */
+    if (lpj + loopadd * 2 == lpj_base + loopadd_base * 2) {
+        lpj_base = lpj;
+        loopadd_base <<= 2;
+        goto recalibrate;
+    }
+
+    return lpj;
+}
+
+void RTOS_Jiffies()
+{
+    unsigned long lpj;
+    lpj = calibrate_delay_converge();
+    rt_kprintf("Calibrating delay loop... %lu.%02lu BogoMIPS (lpj=%lu)\n",
+            lpj/(500000/HZ),
+            (lpj/(5000/HZ)) % 100, lpj);
+}
+
+void gk7101_setting_pll()
+{
+    int i = 0;
+
+    *((volatile U32 *)0x70170000) = 0x01202e01;
+    *((volatile U32 *)0x70170004) = 0x00000000;
+    *((volatile U32 *)0x7017000C) = 0x0000000c;
+    *((volatile U32 *)0x70170014) = 0x01202401;
+    *((volatile U32 *)0x70170018) = 0x00000000;
+    *((volatile U32 *)0x7017001C) = 0x00000001;
+    *((volatile U32 *)0x70170024) = 0x02406301;
+    *((volatile U32 *)0x70170028) = 0x00000000;
+    *((volatile U32 *)0x70170030) = 0x00000000;
+    *((volatile U32 *)0x70170034) = 0x00000000;
+    *((volatile U32 *)0x70170038) = 0x00000001;
+    *((volatile U32 *)0x7017003C) = 0x00000008;
+    *((volatile U32 *)0x7017004C) = 0x00000001;
+    *((volatile U32 *)0x70170050) = 0x00000001;
+    *((volatile U32 *)0x70170054) = 0x01202001;
+    *((volatile U32 *)0x70170058) = 0x00c49ba5;
+    *((volatile U32 *)0x7017005C) = 0x00000008;
+    *((volatile U32 *)0x70170060) = 0x00000001;
+    *((volatile U32 *)0x70170068) = 0x00000002;
+    *((volatile U32 *)0x70170080) = 0x00206978;
+    *((volatile U32 *)0x70170084) = 0x00000020;
+    *((volatile U32 *)0x7017008C) = 0x0000000f;
+    *((volatile U32 *)0x7017009C) = 0x00000002;
+    *((volatile U32 *)0x701700A0) = 0x00000010;
+    *((volatile U32 *)0x701700BC) = 0x00000001;
+    *((volatile U32 *)0x701700E4) = 0x01203201;
+    *((volatile U32 *)0x701700E8) = 0x00000000;
+    *((volatile U32 *)0x701700EC) = 0x00000008;
+    *((volatile U32 *)0x70170100) = 0x00000030;
+    *((volatile U32 *)0x70170108) = 0x00000030;
+    *((volatile U32 *)0x70170118) = 0x00000002;
+    *((volatile U32 *)0x7017011C) = 0x00000030;
+    *((volatile U32 *)0x70170124) = 0x00000030;
+    *((volatile U32 *)0x70170130) = 0x00000030;
+    *((volatile U32 *)0x70170148) = 0x00000001;
+    *((volatile U32 *)0x70170198) = 0x00000000;
+    *((volatile U32 *)0x7017019C) = 0x00000000;
+    *((volatile U32 *)0x701701E0) = 0x00000000;
+    *((volatile U32 *)0x701701E4) = 0x00000000;
+    *((volatile U32 *)0x701701F4) = 0x00000002;
+    *((volatile U32 *)0x701701FC) = 0x00000021;
+    *((volatile U32 *)0x70170200) = 0x00000022;
+    *((volatile U32 *)0x70170214) = 0x00000022;
+#if 0
+    *((volatile U32 *)0x7017021C) = 0x00000000;
+    *((volatile U32 *)0x70170228) = 0x00000000;
+    *((volatile U32 *)0x7017022C) = 0x00000000;
+#endif
+
+    for(i=0; i<14; i++)
+    {
+        *((volatile U32 *)((U32)0x70170230 + i*4)) = 0x11111111;
+    }
+
+#if 0
+    *((volatile U32 *)0x70170270) = 0x00000000;
+#endif
+
+    *(volatile U32 *)(0x70009100+20*4) = (1<<8);
+    *(volatile U32 *)(0x70009200+7*4) = 20;
+
+    *(volatile U32 *)(0x70009100+22*4) = 9;
+
+}
+//-------------------------------------------------------
+
+#if 0
+rt_inline unsigned int rt_list_len(const rt_list_t *l)
+{
+    unsigned int len = 0;
+    const rt_list_t *p = l;
+    while (p->next != l)
+    {
+        p = p->next;
+        len ++;
+    }
+
+    return len;
+}
+#endif
+
+static void show_wait_queue(struct rt_list_node *list)
+{
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, tlist);
+        rt_kprintf("%s", thread->name);
+
+        if (node->next != list)
+            rt_kprintf("/");
+    }
+}
+
+void rtos_cache_inv_range(void *addr, unsigned int size)
+{
+    u32                 vstart;
+    u32                 vend;
+    u32                 addr_tmp;
+
+    vstart = (u32)addr & CACHE_LINE_MASK;
+    vend = ((u32)addr + size + CACHE_LINE_SIZE - 1) & CACHE_LINE_MASK;
+
+    if (cache_check_start && (vstart != (u32)addr)) {
+        return;
+    }
+    if (cache_check_end && (vend != ((u32)addr + size))) {
+        return;
+    }
+
+
+    for (addr_tmp = vstart; addr_tmp < vend; addr_tmp += CACHE_LINE_SIZE) {
+        __asm__ __volatile__ (
+            "mcr p15, 0, %0, c7, c6, 1" : : "r" (addr_tmp));
+    }
+    dsb();
+}
+
+void rtos_cache_clean_range(void *addr, unsigned int size)
+{
+
+
+    u32                 vstart;
+    u32                 vend;
+
+    u32                 addr_tmp;
+
+    vstart = (u32)addr & CACHE_LINE_MASK;
+    vend = ((u32)addr + size + CACHE_LINE_SIZE - 1) & CACHE_LINE_MASK;
+    if (cache_check_start && (vstart != (u32)addr)) {
+        return;
+    }
+    if (cache_check_end && (vend != ((u32)addr + size))) {
+        return;
+    }
+
+
+    for (addr_tmp = vstart; addr_tmp < vend; addr_tmp += CACHE_LINE_SIZE) {
+        __asm__ __volatile__ (
+            "mcr p15, 0, %0, c7, c10, 1" : : "r" (addr_tmp));
+    }
+
+    dsb();
+}
+
+
+
+
+
+U32 RTOS_EnterCriticalSection( void )
+{
+    #if 0
+    /*lint -save -e529 */
+    U32 old_flags = 0;
+    U32 new_flags = 0;
+
+    #if defined(_ARM) && !defined(__GNUC__) && !defined(__polyspace__)
+        __asm { mrs old_flags,cpsr }
+        __asm { orr new_flags,old_flags,#0xC0 }
+        __asm { msr cpsr_c,new_flags }
+    #endif
+
+    #if defined(_ARM) && defined(__GNUC__) && !defined(__polyspace__)
+        asm volatile( "mrs %0,cpsr"     : "=r"(old_flags) : "r"(new_flags) );
+        asm volatile( "orr %0,%1,#0xC0" : "=r"(new_flags) : "r"(old_flags) );
+        asm volatile( "msr cpsr_c,%0"   : : "r"(new_flags) );
+    #endif
+
+    #if defined(_ARC) && !defined(__polyspace__)
+        old_flags = _lr(0);
+        _flag(0);
+    #endif
+
+    return( old_flags );
+    #else
+    return (U32)rt_hw_interrupt_disable();
+    #endif
+    /*lint -restore */
+}
+
+void RTOS_LeaveCriticalSection( U32 cpuStatus )
+{
+    #if 0
+    /*lint -save -e715 */
+
+    #if defined(_ARM) && !defined(__GNUC__) && !defined(__polyspace__)
+        __asm { msr cpsr_c,cpuStatus }
+    #endif
+
+    #if defined(_ARM) && defined(__GNUC__) && !defined(__polyspace__)
+        asm volatile ( "msr cpsr_c,%0" : : "r"(cpuStatus) );
+    #endif
+
+    #if defined(_ARC) && !defined(__polyspace__)
+        cpuStatus &= 0x0C000000;
+        _flag( cpuStatus >> 25 );
+    #endif
+    #else
+    rt_hw_interrupt_enable(cpuStatus);
+    #endif
+    /*lint -restore */
+}
+
+
+
+
+void RTOS_Halt( void )
+{
+    RTOS_EnterCriticalSection();
+}
+
+
+
+//-------------------------------------------------------------
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes )
+{
+    if( ( mem == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+#if 0
+    return rt_memset(mem,value,bytes);
+#else// use libc 's memset to improve performance.
+    return memset(mem,value,bytes);
+#endif
+}
+
+RTOS_Memory RTOS_Malloc( RTOS_Size bytes)
+{
+    return rt_malloc(bytes);
+}
+
+RTOS_Memory RTOS_Realloc( RTOS_Memory addr, RTOS_Size bytes )
+{
+    return rt_realloc(addr, bytes);
+}
+
+char * RTOS_ThreadGetSelfName(void);
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared )
+{
+    //if (bytes >= 0x10000)
+    //    printf("RTOS_MemoryAllocate: %d(%s)\n",bytes, RTOS_ThreadGetSelfName());
+    return rt_malloc(bytes);
+}
+
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory )
+{
+    if(memory) rt_free(memory);
+    return 0;
+}
+
+RTOS_Memory RTOS_SysMemoryAllocate( RTOS_Size bytes, RTOS_Flag shared )
+{
+#ifndef CACHE_MEM_MANAGE
+    return (RTOS_Memory)rt_malloc(bytes);
+#else
+    return (RTOS_Memory)rt_dspmem_malloc(bytes);
+#endif
+}
+
+RTOS_Status RTOS_SysMemoryRelease( RTOS_Memory memory )
+{
+    if(memory)
+#ifndef CACHE_MEM_MANAGE
+     rt_free(memory);
+#else
+    rt_dspmem_free(memory);
+#endif
+    return 0;
+}
+
+RTOS_Memory RTOS_KernelMemoryAllocate( RTOS_Size bytes)
+{
+    return (RTOS_Memory)RT_KERNEL_MALLOC(bytes);
+}
+
+RTOS_Status RTOS_KernelMemoryRelease( RTOS_Memory memory )
+{
+    if(memory)
+        RT_KERNEL_FREE(memory);
+    return 0;
+}
+
+
+void RTOS_GetMemInfo( RTOS_Size *Cache_memory, RTOS_Size *Uncache_memory)
+{
+    rt_uint32_t total,used,max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    *Cache_memory = total;
+    *Uncache_memory = 0;
+
+    #ifdef  CACHE_MEM_MANAGE
+    rt_cache_memory_info(&total,&used,&max_used);
+    *Uncache_memory = total;
+    #endif
+}
+
+
+
+void RTOS_HeapMemoryReport( void )
+{
+    rt_uint32_t total,used,max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf("Heap Memory Info [cache memory]\n");
+    rt_kprintf("total memory:             %d KBytes,%d Btyes\n", total/1024,total);
+    rt_kprintf("used memory :             %d KBytes,%d Btyes\n", used/1024,used);
+    rt_kprintf("maximum allocated memory: %d KBytes,%d Btyes\n", max_used/1024,max_used);
+}
+
+void RTOS_SysMemoryReport( void )
+{
+#ifdef  CACHE_MEM_MANAGE
+    rt_uint32_t total,used,max_used;
+
+    rt_cache_memory_info(&total,&used,&max_used);
+    rt_kprintf("Sys  Memory Info [cache memory]\n");
+    rt_kprintf("total memory:             %d KBytes\n", total/1024);
+    rt_kprintf("used memory :             %d KBytes\n", used/1024);
+    rt_kprintf("maximum allocated memory: %d KBytes\n", max_used/1024);
+
+    rt_dspmem_memory_info(&total,&used,&max_used);
+    rt_kprintf("Drv  Memory Info [uncache memory]\n");
+    rt_kprintf("total memory:             %d KBytes\n", total/1024);
+    rt_kprintf("used memory :             %d KBytes\n", used/1024);
+    rt_kprintf("maximum allocated memory: %d KBytes\n", max_used/1024);
+
+#endif
+}
+
+RTOS_Memory RTOS_MemoryCopy( RTOS_Memory dst, RTOS_Memory src, RTOS_Size bytes )
+{
+#if 0
+    U8*       dstArray = (U8*)dst;
+    U8*       srcArray = (U8*)src;
+    RTOS_Size index;
+
+    if( ( dst == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+
+    for( index=0; index < bytes; index++ )
+        dstArray[index] = srcArray[index];
+
+    return( dst );
+#else// use libc 's memcpy to improve performance.
+    if( ( dst == (RTOS_Memory)0 ) || ( bytes == 0 ) )
+        return( (RTOS_Memory)0 );
+    memcpy(dst, src, bytes);
+    return( dst );
+#endif
+}
+
+//-------------------------------------------------------------
+
+U32 RTOS_SetThreadName( RTOS_ThreadT threadHandle, const char* optName)
+{
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    if(threadHandle)
+    {
+        rt_strncpy(((rt_thread_t)threadHandle)->name, optName, RT_NAME_MAX);
+    }
+    rt_hw_interrupt_enable(level);
+
+    return 0;
+}
+
+U32 RTOS_ThreadSetName( RTOS_ThreadT threadHandle, const char* optName)
+{
+    rt_base_t level;
+
+    level = rt_hw_interrupt_disable();
+    if(threadHandle)
+    {
+        rt_strncpy(((rt_thread_t)threadHandle)->name, optName, RT_NAME_MAX);
+    }
+    rt_hw_interrupt_enable(level);
+
+    return 0;
+}
+char * RTOS_ThreadGetSelfName(void)
+{
+    return rt_thread_self()->name;
+}
+
+// thread-safe errno related api functions.
+void RTOS_SetErrno(const int err)
+{
+#if 0
+    rt_base_t level;
+    level = rt_hw_interrupt_disable();
+
+    rt_thread_t self = rt_thread_self();
+    self->thr_internal_errno = err;//FIXME(heyong): error is used to errno.
+
+    rt_hw_interrupt_enable(level);
+    //rt_kprintf("RTOS_SetErrno %d\n", err);
+#endif
+}
+int RTOS_GetErrno()
+{
+    int err;
+#if 0
+    rt_base_t level;
+    level = rt_hw_interrupt_disable();
+
+    rt_thread_t self = rt_thread_self();
+    err = (int)self->thr_internal_errno;//FIXME(heyong): error is used to errno.
+
+    rt_hw_interrupt_enable(level);
+    //rt_kprintf("RTOS_GetErrno %d\n", err);
+#endif
+    return err;
+}
+
+RTOS_ThreadT RTOS_CreateThread(
+        U32* stackBuffer, U32 stackSize, U32 priority,
+        RTOS_ThreadFunctionT function, void* optArg, void* optData,
+        const char* optName )
+{
+    rt_thread_t tid;
+
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+
+    tid = rt_thread_create((optName == NULL)?"thread":optName,
+                    function, optArg,
+                    stackSize, priority, THREAD_TIMESLICE);
+    if (tid != RT_NULL)
+    {
+        rt_thread_startup(tid);
+    }
+
+    return (RTOS_ThreadT)tid;
+}
+
+U32 RTOS_DestroyThread( RTOS_ThreadT threadHandle )
+{
+    rt_err_t ret = 0;
+
+    rt_enter_critical();
+    ret = rt_thread_delete((rt_thread_t)threadHandle);
+    rt_exit_critical();
+
+    if (RT_EOK == ret)
+    {
+        ret = 1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    return ret;
+}
+
+U32 RTOS_ThreadDestroy( RTOS_ThreadT threadHandle )
+{
+    rt_err_t ret = 0;
+
+    rt_enter_critical();
+    ret = rt_thread_delete((rt_thread_t)threadHandle);
+    rt_exit_critical();
+
+    if (RT_EOK == ret)
+    {
+        ret = 1;
+    }
+    else
+    {
+        ret = 0;
+    }
+
+    return ret;
+}
+
+U32 RTOS_GetThreadPriority(RTOS_ThreadT threadHandle)
+{
+    rt_thread_t tid = (rt_thread_t)threadHandle;
+    int priority = tid->current_priority;
+
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+    return priority;
+}
+
+
+void gkosFinishThread( void )
+{
+    //rt_thread_t t = rt_thread_self();
+
+    //rt_thread_detach(t);
+}
+
+
+void RTOS_LockScheduler( void )
+{
+    rt_enter_critical();
+}
+
+void RTOS_UnlockScheduler( void )
+{
+    rt_exit_critical();
+}
+
+void RTOS_SchedulerLock( void )
+{
+    rt_enter_critical();
+}
+
+void RTOS_SchedulerUnlock( void )
+{
+    rt_exit_critical();
+}
+
+U32 RTOS_SleepThread( U32 msecs )
+{
+    return  rt_thread_delay( msecs )  ;
+}
+
+U32 msleep( U32 msecs )
+{
+    return  rt_thread_delay( msecs )  ;
+}
+
+
+U32 RTOS_SuspendThread( RTOS_ThreadT threadHandle )
+{
+    return rt_thread_suspend((rt_thread_t)threadHandle);
+}
+
+U32 RTOS_WakeupThread( RTOS_ThreadT threadHandle )
+{
+    return rt_thread_resume( (rt_thread_t)threadHandle );
+}
+
+void thread_statistics()
+{
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+    rt_uint8_t *ptr;
+
+    rt_base_t level;
+
+    struct rt_object_information *information;
+
+    information = rt_object_get_information(RT_Object_Class_Thread);
+    RT_ASSERT(information != RT_NULL);
+
+    struct rt_list_node *list = &(information->object_list);
+
+    level = rt_hw_interrupt_disable();
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+        //if(thread) thread->total_tick = 0;
+    }
+
+    rt_hw_interrupt_enable(level);
+
+    rt_thread_delay(5000);
+
+    //not close interrupt to avoid the venc error because the print time is too long.
+    //level = rt_hw_interrupt_disable();
+    rt_kprintf("          thread                 pri  status  tick   cpu%%         sp    stack addr stack size  max used  left tick\n");
+    rt_kprintf("-------------------------------- --- ------- ------ -------    ---------- ---------- ---------- ---------- ---------- \n");
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+#if 0
+        rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
+#else
+        int priority = thread->current_priority;
+        if (priority < RTOS_ThreadPriorityHighest)
+        {
+            priority = RTOS_ThreadPriorityHighest - priority;
+        }
+        else
+        {
+            priority = 1;
+        }
+        rt_kprintf("%-32.*s %3d", RT_NAME_MAX, thread->name, priority);
+#endif
+        if (thread->stat == RT_THREAD_READY)        rt_kprintf("   ready");
+        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
+        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf("    init");
+        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf("   close");
+
+        ptr = (rt_uint8_t*)thread->stack_addr;
+        while (*ptr == '#')ptr ++;
+#if 0
+        rt_kprintf(" %5d   %5.2f%%    0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+            thread->total_tick,
+            ((double)thread->total_tick/50)>=100.00?99.9:((double)thread->total_tick/50),
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
+            thread->remaining_tick);
+#endif
+
+        rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
+            thread->remaining_tick);
+    }
+    //rt_hw_interrupt_enable(level);
+}
+
+void RTOS_ThreadDisplayStatistics( void )
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf("\n         memory info       size \n");
+    rt_kprintf("--------------------------------- -------\n");
+    rt_kprintf("total heap memory :               %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  heap memory :               %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated heap memory:    %d(%dKB)\n\n", max_used, max_used/1024);
+#ifdef CACHE_MEM_MANAGE
+    rt_cache_memory_info(&total,&used,&max_used);
+    rt_kprintf("total sys  memory :             %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  sys  memory :             %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated sys memory:   %d(%dKB)\n", max_used, max_used/1024);
+
+    rt_dspmem_memory_info(&total,&used,&max_used);
+    rt_kprintf("total drv  memory :             %d(%dKB)\n", total, total/1024);
+    rt_kprintf("used  drv  memory :             %d(%dKB)\n", used, used/1024);
+    rt_kprintf("maximum allocated drv memory:   %d(%dKB)\n", max_used, max_used/1024);
+#endif
+
+    thread_statistics();
+
+    return ;
+}
+
+U32 RTOS_GetFreeHeapSize()
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+
+    rt_memory_info(&total,&used,&max_used);
+
+    return (total-used);
+}
+
+RTOS_Time RTOS_KernelTimerGetPeriod(void)
+{
+    return (1000 / RT_TICK_PER_SECOND);
+}
+
+//-------------------------sem--------------------------
+RTOS_SemaphoreT RTOS_CreateSemaphore( U32 initCount )
+{
+    return (RTOS_SemaphoreT)rt_sem_create("sem", initCount, RT_IPC_FLAG_PRIO);
+}
+
+U32 RTOS_WaitSemaphore(RTOS_SemaphoreT semaphoreHandle, U32 suspend)
+{
+    if(suspend)
+        return RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, RTOS_SUSPEND);
+    else
+        return RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, RTOS_NO_SUSPEND);
+}
+
+
+U32 RTOS_GetSemaphore( RTOS_SemaphoreT semaphoreHandle,
+                           U32 msecsTimeout )
+{
+    return rt_sem_take((rt_sem_t)semaphoreHandle, msecsTimeout);
+}
+
+U32 RTOS_SetSemaphore( RTOS_SemaphoreT semaphoreHandle,
+                            U32 msecsTimeout )
+{
+    return rt_sem_release((rt_sem_t)semaphoreHandle);
+}
+
+RTOS_Status RTOS_SemaphoreDestroy( RTOS_Semaphore semaphoreHandle )
+{
+    return rt_sem_delete((rt_sem_t)semaphoreHandle);
+}
+
+RTOS_Status RTOS_DestroySemaphore( RTOS_Semaphore semaphoreHandle )
+{
+    return rt_sem_delete((rt_sem_t)semaphoreHandle);
+}
+
+S32 RTOS_SemaphoreQuery( RTOS_Semaphore semaphoreHandle )
+{
+    S32 countPtr = 0;
+    rt_ubase_t level;
+
+    level = rt_hw_interrupt_disable();
+
+    countPtr = ((rt_sem_t)semaphoreHandle)->value;
+
+    rt_hw_interrupt_enable(level);
+
+    return (S32)countPtr;
+}
+
+//-------------------------timer-------------------------
+void GKOS_KernelTimerSetHook(RTOS_HookFunction function)
+{
+    if(gkosHookData)
+    {
+        if(gkosHookData->timerFunctionCount < (GKOS_TIMER_HOOK_TABLE_SIZE - 1))
+        {
+            gkosHookData->timerFunctionArray[gkosHookData->timerFunctionCount] = function;
+            gkosHookData->timerFunctionCount ++;
+        }
+    }
+}
+
+
+void RTOS_KernelTimerSetHook(RTOS_HookFunction function)
+{
+    GKOS_KernelTimerSetHook(function);
+}
+
+//-------------------------mail queue-------------------------
+#if 0
+RTOS_MailqueueT RTOS_MailqueueCreate( U32 queueElements)
+{
+    struct rt_mailbox *mq;
+
+    mq = rt_mb_create("mqt", queueElements, RT_IPC_FLAG_FIFO);
+
+    return (RTOS_MailqueueT)mq;
+}
+#endif
+
+RTOS_MailqueueT RTOS_CreateMailqueue( U32 queueElements, U32 elementBytes )
+{
+    struct rt_mailbox *mq;
+
+    mq = rt_mb_create("mqt", queueElements, RT_IPC_FLAG_FIFO);
+
+    return (RTOS_MailqueueT)mq;
+}
+
+RTOS_Status RTOS_MailqueueSend(RTOS_Mailqueue mailqueue, RTOS_Message data)
+{
+    //rt_kprintf("mail send...0x%x\n", data);
+    return rt_mb_send((rt_mailbox_t)mailqueue, (rt_uint32_t)data);
+}
+
+RTOS_Status RTOS_MailqueueSendTimeout(RTOS_Mailqueue mailqueue, RTOS_Message data, RTOS_Time timeout)
+{
+    //rt_kprintf("mail send...0x%x\n", data);
+    return rt_mb_send_wait((rt_mailbox_t)mailqueue, (rt_uint32_t)data, timeout);
+}
+
+RTOS_Message RTOS_MailqueueWait(RTOS_Mailqueue mailqueue, RTOS_Flag suspend)
+{
+    int ret;
+    U32 timeout;
+    U8* messagePtr;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    ret = rt_mb_recv((rt_mailbox_t)mailqueue, (void*)(&messagePtr), timeout);
+    //rt_kprintf("mail recv [0x%x]...0x%x\n", (U32)timeout, messagePtr);
+
+    if(ret != 0)
+        return NULL;
+
+    return (RTOS_Message)messagePtr;
+}
+
+RTOS_Message RTOS_MailqueueWaitTimeout( RTOS_Mailqueue mailqueue, RTOS_Time timeout )
+{
+    U8* messagePtr;
+    int ret;
+
+    ret = rt_mb_recv((rt_mailbox_t)mailqueue, (void*)(&messagePtr), timeout);
+    //rt_kprintf("mail recv [0x%x]...0x%x\n", (U32)timeout, messagePtr);
+
+    if(ret != 0)
+        return NULL;
+    return (RTOS_Message)messagePtr;
+}
+
+U32 RTOS_MailqueueDestroy( RTOS_MailqueueT mailqueuePtr )
+{
+    rt_mb_delete((rt_mailbox_t)mailqueuePtr);
+
+    return 0;
+}
+
+U32 RTOS_DestroyMailqueue( RTOS_MailqueueT mailqueuePtr )
+{
+    rt_mb_delete((rt_mailbox_t)mailqueuePtr);
+
+    return 0;
+}
+
+U32 RTOS_GetTimerStamp()
+{
+    return rt_tick_get();
+}
+
+/*
+*******************************************************************************
+**
+** Create a new mutex and initializes it with the given value.
+**
+*******************************************************************************
+*/
+RTOS_MutexT RTOS_MutexCreate( void )
+{
+    return( (RTOS_MutexT) rt_mutex_create("mutex", RT_IPC_FLAG_FIFO) );
+}
+
+/*
+*******************************************************************************
+**
+** Destroy a given mutex.
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexDestroy( RTOS_MutexT mutex )
+{
+
+    return rt_mutex_delete( (rt_mutex_t) mutex );
+}
+
+/*
+*******************************************************************************
+**
+** Query (read) the current value from a given mutex.
+**
+*******************************************************************************
+*/
+S32 RTOS_MutexQuery( RTOS_MutexT mutex )
+{
+
+    S32 countPtr = 0;
+    rt_ubase_t level;
+
+    level = rt_hw_interrupt_disable();
+
+    countPtr = ((rt_mutex_t)mutex)->value;
+
+    rt_hw_interrupt_enable(level);
+
+    return countPtr;
+}
+
+/*
+*******************************************************************************
+**
+** Wait and lock a given mutex
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexLock( RTOS_MutexT mutex, RTOS_Flag suspend )
+{
+    U32 timeout;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    return rt_mutex_take( (rt_mutex_t) mutex, timeout );
+
+}
+
+U32 RTOS_MutexLockTimeout( RTOS_MutexT mutex, U32 timeout )
+{
+
+    return rt_mutex_take( (rt_mutex_t) mutex, timeout );
+
+}
+
+/*
+*******************************************************************************
+**
+** Unlock an occupied mutex
+**
+*******************************************************************************
+*/
+U32 RTOS_MutexUnlock( RTOS_MutexT mutex )
+{
+    return rt_mutex_release( (rt_mutex_t) mutex );
+}
+
+
+//--------------------------------------------------------
+RTOS_ThreadT RTOS_ThreadSelf( void )
+{
+    return( (RTOS_ThreadT)rt_thread_self() );
+}
+
+
+//-------------------------------------------------------
+
+extern unsigned char __heap_end__[];
+gkosHookDataT  HookData;
+
+void RTOS_HwTickInit(void)
+{
+
+    GD_HANDLE   timerHandle;
+    GBOOL       timerFlag;
+    GERR        result;
+
+    GD_INT_DisableAllInterrupts();
+    // only use the os's timers
+    // RTOS_TIMERTICK_IRQ must use the GD_INT_LOW_PRIORITY mode
+    GD_INT_SetVector( GD_INT_TIMER1_IRQ, NULL );
+    result = GD_TIMER_SoftTimerOpen( &timerHandle );
+
+    if( result == GD_OK )
+    {
+        // modify the hard timer to Timer Tick
+        result = GD_TIMER_SoftTimerSet( &timerHandle, 1, &timerFlag, NULL );
+        GD_INT_SetVector( GD_INT_TIMER1_IRQ, rt_tick_increase );
+    }
+
+
+    int bytes = sizeof(gkosHookDataT);
+    gkosHookData = &HookData;
+    memset( gkosHookData, 0, bytes );
+
+}
+
+extern u32 ARM1176_MMU_ttb0[4096];
+
+
+U32 RTOS_InitKernel(U32 Heap_size)
+{
+    u32 os_end_address=0;
+    /* disable interrupt first */
+    rt_hw_interrupt_disable();
+    /* enable cpu cache */
+    //rt_hw_cpu_icache_disable();
+    //mmu_invalidate_icache();
+    //rt_hw_cpu_icache_enable();
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+
+    /* initialize board */
+    //rt_hw_board_init();
+
+    /* show version */
+    //rt_show_version();
+
+    /* initialize tick */
+    //rt_system_tick_init();
+    RTOS_HwTickInit();
+    //rt_kprintf("set tick\n");
+
+    /* initialize kernel object */
+    rt_system_object_init();
+
+    /* initialize timer system */
+    rt_system_timer_init();
+
+    /* initialize heap memory system */
+    os_end_address= (u32)__heap_end__+Heap_size;
+
+#ifdef  CACHE_MEM_MANAGE
+    rt_system_heap_init((void*)__heap_end__, (void*)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE));
+
+    rt_system_cache_init((void*)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE),
+                          (void*)(os_end_address-CACHE_DSP_SIZE));
+    //cache-buffer for system
+    #if 0
+    RTOS_MMU_ChangeMapEntry((U32)(os_end_address-CACHE_MEM_SIZE-CACHE_DSP_SIZE),(U32)os_end_address-CACHE_DSP_SIZE,
+                            (U32)(os_end_address-CACHE_MEM_SIZE), 0x00000DE2);
+    #endif
+
+    rt_system_dspmem_init((void*)(os_end_address-CACHE_DSP_SIZE), (void*)(os_end_address));
+    //nocache nobuffer
+    RTOS_MMU_ChangeMapEntry((U32)(os_end_address-CACHE_DSP_SIZE), (U32)os_end_address,
+                            (U32)(os_end_address-CACHE_DSP_SIZE), 0x00000DE2);
+
+        /* print mmu table */
+    //rt_hw_cpu_dump_page_table((rt_uint32_t*)ARM1176_MMU_ttb0);
+
+#else
+    rt_system_heap_init((void*)__heap_end__, (void*)os_end_address);
+#endif
+
+
+
+#ifdef RT_USING_MODULE
+    /* initialize module system*/
+    rt_system_module_init();
+#endif
+
+    /* initialize scheduler system */
+    rt_system_scheduler_init();
+
+    return 0;
+}
+
+void RTOS_StartMultitasking( void )
+{
+    #ifdef RT_USING_FINSH
+    /* initialize finsh */
+    finsh_system_init();
+#ifdef RT_USING_DEVICE
+    finsh_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif
+#endif
+
+    /* initialize system timer thread */
+    rt_system_timer_thread_init();
+
+    /* initialize idle thread */
+    rt_thread_idle_init();
+
+    rt_kprintf("start scheduler\n");
+    /* start scheduler */
+
+    rt_system_scheduler_start();
+
+    /* never reach here */
+    return ;
+}
+
+
+U32 RTOS_GetMailqueue( RTOS_MailqueueT mailqueueHandle,
+                           void* resultBuffer, U32 msecsTimeout )
+{
+    return rt_mb_recv((rt_mailbox_t)mailqueueHandle,(rt_uint32_t*)resultBuffer,
+                        (rt_uint32_t)msecsTimeout);
+}
+
+U32 RTOS_SetMailqueue( RTOS_MailqueueT mailqueueHandle,
+                           void* messagePtr, U32 toFront,
+                           U32 msecsTimeout )
+{
+    return rt_mb_send_wait((rt_mailbox_t)mailqueueHandle,
+                            (rt_uint32_t)messagePtr, (rt_uint32_t)msecsTimeout);
+}
+
+
+/*Dummy func of os*/
+
+//-----------------------------cond------------------------------
+RTOS_CondT RTOS_CondCreate( void )
+{
+    rt_event_t evt;
+
+    evt = rt_event_create("evt", 0);
+
+    /* detach the object from system object container */
+    rt_object_detach(&(evt->parent.parent));
+
+    return (RTOS_CondT) evt;
+}
+
+RTOS_Status RTOS_CondDestroy( RTOS_CondT cond )
+{
+    rt_err_t result;
+    if (cond == RT_NULL)
+        return -2;
+
+    result = rt_event_delete((rt_event_t)cond);
+    if (result != RT_EOK)
+        return -3;
+
+    return( 0 );
+}
+
+int _cond_timedwait(RTOS_CondT  cond, RTOS_MutexT mutex, U32 timeout)
+{
+    int result;
+    rt_uint32_t recved = 0XFF;
+    if (!cond || !mutex)
+        return -1;
+
+    if(RTOS_MutexUnlock(mutex)!=0) return -2;
+
+    result = rt_event_recv((rt_event_t)cond, 0x01,RT_EVENT_FLAG_AND|RT_EVENT_FLAG_CLEAR,timeout,&recved);
+    if(result == -RT_ERROR && recved == 0XFF) // for boardcase event
+    {
+        result = RT_EOK;
+    }
+    /* lock mutex again */
+    RTOS_MutexLock(mutex, 1);
+
+    return result;
+}
+
+
+RTOS_Status RTOS_CondWait( RTOS_CondT cond, RTOS_MutexT mutex, RTOS_Flag suspend )
+{
+    S32 value = 0;
+    U32 timeout;
+
+    if( suspend )
+        timeout = RTOS_SUSPEND;
+    else
+        timeout = RTOS_NO_SUSPEND;
+
+    value = _cond_timedwait( (RTOS_CondT) cond, (RTOS_MutexT) mutex, timeout );
+    if( value != RT_EOK )
+        return( -1 );
+
+    return( value );
+}
+
+RTOS_Status RTOS_CondWaitTimeout( RTOS_CondT cond, RTOS_MutexT mutex, U32 timeout )
+{
+    S32 value = 0;
+
+    value = _cond_timedwait( (RTOS_CondT) cond, (RTOS_MutexT) mutex, timeout );
+    if( value != RT_EOK )
+        return( -1 );
+
+    return( value );
+}
+
+
+RTOS_Status RTOS_CondSignal( RTOS_CondT cond )
+{
+    RTOS_Status result;
+
+    result = rt_event_send((rt_event_t)cond,0x01);
+    if (result != RT_EOK)
+        return -1;
+
+    return 0;
+}
+
+RTOS_Status RTOS_CondBroadcast( RTOS_CondT cond )
+{
+
+    rt_event_control((rt_event_t)cond,RT_IPC_CMD_RESET,0);
+
+    return 0;
+}
+
+U32 RTOS_OsType(void)
+{
+    return RTOS_RTTHREAD;
+}
+
+
+void RTOS_MMU_ChangeMapEntry(U32 vaddrStart, U32 vaddrEnd, U32 paddrStart, U32 attr)
+{
+    volatile U32 *pTT;
+    volatile int i,nSec;
+
+    extern U32 ARM1176_MMU_ttb0[];
+    extern U32 ARM1176_MMU_ttb1[];
+
+    U32*   table_ptr  = (U32*)ARM1176_MMU_ttb0;
+    //printf("mmu table: 0x%x \n", (U32)ARM1176_MMU_ttb0);
+
+    pTT  = (U32 *)table_ptr + (vaddrStart>>20);
+    nSec = (vaddrEnd>>20) - (vaddrStart>>20);
+    //printf("change table: 0x%x -- %d\n", (U32)pTT, nSec);
+
+    for(i=0;i<=nSec;i++)
+    {
+        *pTT = attr |(((paddrStart>>20)+i)<<20);
+        pTT++;
+    }
+
+    table_ptr  = (U32*)ARM1176_MMU_ttb1;
+    //printf("mmu table: 0x%x \n", (U32)ARM1176_MMU_ttb1);
+
+    pTT  = (U32 *)table_ptr + (vaddrStart>>20);
+    nSec = (vaddrEnd>>20) - (vaddrStart>>20);
+    //printf("change table: 0x%x -- %d\n", (U32)pTT, nSec);
+
+    for(i=0;i<=nSec;i++)
+    {
+        *pTT = attr |(((paddrStart>>20)+i)<<20);
+        pTT++;
+    }
+
+}
+
+int RTOS_thread_yield(void)
+{
+    rt_thread_yield();
+
+    return 0;
+}
+
+unsigned int RTOS_jiffies(void)
+{
+    return jiffies;
+}
+
+RTOS_TimerT RTOS_CreateTimer(U32 isContinouos, RTOS_SemaphoreT fireSemaphore, RTOS_HookFunctionT callbackFunction)
+{
+    //U8 name[32];
+
+    //sprintf(name, "timer %X", (U32)callbackFunction);
+    if(isContinouos)
+    {
+        return (RTOS_TimerT)rt_timer_create("timer", callbackFunction, NULL, 0, RT_TIMER_FLAG_PERIODIC);
+    }
+    else
+    {
+        return (RTOS_TimerT)rt_timer_create("timer", callbackFunction, NULL, 0, RT_TIMER_FLAG_ONE_SHOT);
+    }
+}
+
+RTOS_TimerT RTOS_CreateTimerEx(const char *name, U8 flag, void *parameter, RTOS_TimerFunctionT callbackFunction)
+{
+    U8 timer_flag = 0;
+
+    if(flag & RTOS_TIMER_FLAG_PERIODIC)
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_PERIODIC;
+    }
+    else
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_ONE_SHOT;
+    }
+
+    if(flag & RTOS_TIMER_FLAG_SOFT_TIMER)
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_SOFT_TIMER;
+    }
+    else
+    {
+        timer_flag = timer_flag | RT_TIMER_FLAG_SOFT_TIMER;
+    }
+
+    return (RTOS_TimerT)rt_timer_create(name, callbackFunction, parameter, 0, timer_flag);
+}
+
+
+U32 RTOS_DestroyTimer(RTOS_TimerT timerHandle)
+{
+    return rt_timer_delete((rt_timer_t)timerHandle);
+}
+U32 RTOS_StartTimer(RTOS_TimerT timerHandle, U32 fireInterval)
+{
+    rt_timer_t handler = (rt_timer_t)timerHandle;
+
+    handler->init_tick = fireInterval;
+    return rt_timer_start((rt_timer_t)timerHandle);
+}
+
+U32 RTOS_StopTimer(RTOS_TimerT timerHandle)
+{
+    return rt_timer_stop((rt_timer_t)timerHandle);
+}
+
+U32 RTOS_ControlTimer(RTOS_TimerT timerHandle, U32 delay_time)
+{
+    return rt_timer_control((rt_timer_t)timerHandle, RT_TIMER_CTRL_SET_TIME, &delay_time);
+}
+
+U32 RTOS_GetTimerStatus(RTOS_TimerT timerHandle)
+{
+    rt_timer_t t;
+
+    t = (rt_timer_t)timerHandle;
+    if(t->parent.flag & RT_TIMER_FLAG_ACTIVATED)
+    {
+        return RTOS_TIMER_FLAG_ACTIVATED;
+    }
+    else
+    {
+        return RTOS_TIMER_FLAG_DEACTIVATED;
+    }
+}
+
+void *RTOS_timer_get_context(RTOS_TimerT timerHandle)
+{
+    rt_timer_t t;
+
+    t = (rt_timer_t)timerHandle;
+
+    return t->parameter;
+}
+
+int RTOS_Thead_Switch_Priority(int priority)
+{
+    if (priority < RTOS_ThreadPriorityHighest)
+    {
+        priority = RTOS_ThreadPriorityHighest - priority;
+    }
+    else
+    {
+        priority = 1;
+    }
+    return priority;
+}
+
+void usleep(int micro_sec)
+{
+    int ms = micro_sec/1000;
+    rt_thread_delay(ms);
+}
+
+void sleep(int sec)
+{
+    rt_thread_delay(sec*1000);
+}

+ 236 - 0
bsp/gkipc/armv6/rtos_lib.h

@@ -0,0 +1,236 @@
+#ifndef RTOS_LIB_H
+#define RTOS_LIB_H
+#include <limits.h>
+#include <string.h>
+#include "rthw.h"
+#include "rtthread.h"
+
+#include "gtypes.h"    /* global type definitions */
+#include "gd_int.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void(*RTOS_ThreadFunctionT)(void*);
+typedef void(*RTOS_HookFunctionT)(void*);
+typedef void (*RTOS_TimerFunctionT)(void *);
+typedef void* RTOS_ThreadT;
+typedef void* RTOS_EventT;
+typedef void* RTOS_SemaphoreT;
+typedef void* RTOS_MailboxT;
+typedef void* RTOS_MailqueueT;
+typedef void* RTOS_MutexT;
+typedef void* RTOS_TimerT;
+typedef void* RTOS_CondT;
+
+typedef U32   RTOS_SYS_SemaphoreT;
+typedef void* RTOS_SYS_MailqueueT;
+
+//typedef struct rt_thread *RTOS_ThreadT;
+//typedef struct rt_semaphore * RTOS_SemaphoreT;
+//typedef struct rt_messagequeue *RTOS_MailqueueT;
+//typedef struct rt_mailbox *RTOS_MailqueueT;
+//typedef struct rt_mutex *RTOS_MutexT;
+
+/*
+********************************************************************************
+********************************************************************************
+**
+** macros to define various suspend modes
+**
+********************************************************************************
+********************************************************************************
+*/
+#define RTOS_OK                     (RTOS_Status)0   //!< The OK status
+#define RTOS_FAILURE                (RTOS_Status)-1  //!< The general FAILURE status
+
+
+#define RTOS_NO_SUSPEND                0x00000000UL //!< do not suspend, return immediately
+#define RTOS_SUSPEND                   0xFFFFFFFFUL //!< suspend forever, wait for valid event without timeout
+
+#define RTOS_MAX_MAILQUEUE_ENTRIES     4096
+#define RTOS_MSG_IS_POINTER 0xFFFFFFFFUL //!< the message to transport is a generic pointer only
+
+typedef GBOOL                    RTOS_Flag;             //!< the boolean flag type
+typedef S32                      RTOS_Status;           //!< the result status type
+typedef S32                      RTOS_Size;             //!< the generic size type
+typedef U32                      RTOS_Time;             //!< the generic time type
+typedef RTOS_TimerT              RTOS_Timer;            //!< the generic time type
+typedef RTOS_ThreadT             RTOS_Thread;           //!< the thread identifier type
+typedef S32                      RTOS_Priority;         //!< the generic priority type
+typedef RTOS_SemaphoreT          RTOS_Semaphore;        //!< the semaphore identifier type
+typedef RTOS_MutexT              RTOS_Mutex;            //!< the mutex semaphore identifier type
+typedef RTOS_MailboxT            RTOS_Mailbox;          //!< the mailbox identifier type
+typedef RTOS_MailqueueT          RTOS_Mailqueue;        //!< the mailqueue identifier type
+typedef void*                    RTOS_Message;          //!< the generic message identifier type
+typedef void*                    RTOS_Memory;           //!< the generic memory pointer type
+typedef U32                      RTOS_Segment;          //!< the memory heap segment type
+typedef RTOS_ThreadFunctionT     RTOS_ThreadFunction;   //!< the thread function definition type
+typedef RTOS_HookFunctionT       RTOS_HookFunction;     //!< the hook function definition type
+typedef RTOS_ThreadT             RTOS_ThreadData;       //!< the optional thread data structure
+typedef RTOS_CondT               RTOS_Cond;             //!< the cond semaphore identifier type
+
+
+#define GKOS_TIMER_HOOK_TABLE_SIZE   8    //!< number of timer-tick hook function entries
+#define GKOS_SWITCH_HOOK_TABLE_SIZE  4    //!< number of context-switch hook function entries
+
+#define RTOS_ThreadPriorityHighest (RTOS_Priority)127 //!< The highest possible priority
+#define RTOS_ThreadPriorityLowest  (RTOS_Priority)1   //!< The lowest possible priority
+
+/*
+********************************************************************************
+********************************************************************************
+**
+** rtos type, gkos:0, rtthread:1
+**
+********************************************************************************
+********************************************************************************
+*/
+#define RTOS_GKOS                   0
+#define RTOS_RTTHREAD               1
+
+#define RTOS_TIMER_FLAG_DEACTIVATED       0x0             /**< timer is deactive */
+#define RTOS_TIMER_FLAG_ACTIVATED         0x1             /**< timer is active */
+#define RTOS_TIMER_FLAG_ONE_SHOT          0x0             /**< one shot timer */
+#define RTOS_TIMER_FLAG_PERIODIC          0x2             /**< periodic timer */
+
+#define RTOS_TIMER_FLAG_HARD_TIMER        0x0             /**< hard timer,the timer's callback function will be called in tick isr. */
+#define RTOS_TIMER_FLAG_SOFT_TIMER        0x4             /**< soft timer,the timer's callback function will be called in timer thread. */
+
+#define RTOS_TIMER_CTRL_SET_TIME          0x0             /**< set timer control command */
+#define RTOS_TIMER_CTRL_GET_TIME          0x1             /**< get timer control command */
+#define RTOS_TIMER_CTRL_SET_ONESHOT       0x2             /**< change timer to one shot */
+#define RTOS_TIMER_CTRL_SET_PERIODIC      0x3             /**< change timer to periodic */
+
+typedef struct
+{
+    RTOS_HookFunctionT timerFunctionArray[GKOS_TIMER_HOOK_TABLE_SIZE];
+    U32                timerFunctionCount;
+    RTOS_HookFunctionT switchFunctionArray[GKOS_SWITCH_HOOK_TABLE_SIZE];
+    U32                switchFunctionCount;
+}gkosHookDataT;
+
+gkosHookDataT*      gkosHookData;
+
+
+#define THREAD_TIMESLICE       10
+
+#define RTOS_ThreadCreate(function,arg,priority,stackBuffer,stackSize)  \
+        RTOS_CreateThread(stackBuffer, stackSize, priority, function, arg, 0, 0)
+U32 RTOS_DestroyThread( RTOS_ThreadT threadHandle );
+
+#define RTOS_ThreadSleep(msecs)    rt_thread_delay(msecs)
+
+
+
+U32 RTOS_ThreadSetName( RTOS_ThreadT threadHandle, const char* optName);
+U32 RTOS_SetThreadName( RTOS_ThreadT threadHandle, const char* optName);
+char * RTOS_ThreadGetName();
+
+
+
+
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory );
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared );
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes );
+RTOS_Memory RTOS_MemoryCopy( RTOS_Memory dst, RTOS_Memory src, RTOS_Size bytes );
+
+RTOS_Memory RTOS_KernelMemoryAllocate( RTOS_Size bytes);
+RTOS_Status RTOS_KernelMemoryRelease( RTOS_Memory memory );
+
+#define RTOS_ATOM_PRINTF(format, ...)   do {\
+        U32 pval = 0;\
+        RTOS_EnterCritical(pval);\
+        printf("\033[0;31m[@%s.%d]->"format"\033[0;0m\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);\
+        RTOS_LeaveCritical(pval);\
+    }while(0)
+
+#define RTOS_ASSERT(EX)                                                         \
+    if (!(EX))                                                                    \
+    {                                                                             \
+        volatile char dummy = 0;                                                  \
+        U32 pval = 0;\
+        RTOS_EnterCritical(pval);\
+        printf("(%s) assert failed at %s:%d thread name:%s\n", #EX, __FUNCTION__, __LINE__, RTOS_ThreadGetSelfName());\
+        while (dummy == 0);                                                       \
+    }
+
+//U32 GKOS_EnterCriticalSection( void );
+//void GKOS_LeaveCriticalSection( U32 cpuStatus );
+
+void RTOS_LockScheduler( void );
+void RTOS_UnlockScheduler( void );
+
+void gkosFinishThread( void );
+
+U32 RTOS_SleepThread( U32 msecs );
+
+
+RTOS_SemaphoreT RTOS_CreateSemaphore( U32 initCount );
+U32 RTOS_GetSemaphore( RTOS_SemaphoreT semaphoreHandle, U32 msecsTimeout );
+U32 RTOS_SetSemaphore( RTOS_SemaphoreT semaphoreHandle, U32 msecsTimeout );
+S32 RTOS_SemaphoreQuery( RTOS_Semaphore semaphoreHandle );
+RTOS_Status RTOS_SemaphoreDestroy( RTOS_Semaphore semaphoreHandle );
+
+#define RTOS_SemaphoreWait(semaphoreHandle, suspend)		RTOS_WaitSemaphore(semaphoreHandle, suspend)
+#define RTOS_SemaphoreWaitTimeout(semaphoreHandle, timeout) RTOS_GetSemaphore((RTOS_Semaphore)semaphoreHandle, timeout)
+#define RTOS_SemaphoreCreate(initCount)                     RTOS_CreateSemaphore(initCount)
+#define RTOS_SemaphoreRelease(semaphoreHandle)              RTOS_SetSemaphore((RTOS_Semaphore)semaphoreHandle,RTOS_SUSPEND)
+
+
+void RTOS_HwTickInit(void);
+
+
+void RTOS_KernelTimerSetHook(RTOS_HookFunction function);
+
+
+RTOS_MailqueueT RTOS_CreateMailqueue( U32 queueElements, U32 elementBytes );
+#define RTOS_MailqueueCreate(elements)      RTOS_CreateMailqueue(elements, RTOS_MSG_IS_POINTER)
+
+
+#define RTOS_EnterCritical(cpusr)   {cpusr=rt_hw_interrupt_disable();}
+#define RTOS_LeaveCritical(cpusr)   {rt_hw_interrupt_enable(cpusr);}
+
+extern U32 cpu_cpsr;
+
+#define RTOS_EnterCriticalEx()   cpu_cpsr = RTOS_EnterCriticalSection()
+#define RTOS_LeaveCriticalEx()   RTOS_LeaveCriticalSection(cpu_cpsr)
+
+#define RTOS_ThreadSuspend(threadHandle)                                RTOS_SuspendThread(threadHandle)
+#define RTOS_ThreadWakeup(threadHandle)                                 RTOS_WakeupThread(threadHandle)
+
+RTOS_Status RTOS_MailqueueSend(RTOS_Mailqueue mailqueue, RTOS_Message data);
+
+#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
+                                    : : "r" (0) : "memory")
+#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
+                                    : : "r" (0) : "memory")
+#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
+                                    : : "r" (0) : "memory")
+
+void 	rtos_cache_inv_range(void *addr, unsigned int size);
+void 	rtos_cache_clean_range(void *addr, unsigned int size);
+
+
+U32 RTOS_Initialize(U32 Heap_size);
+
+#define RTOS_Initialize             RTOS_InitKernel
+
+#define RTOS_GetIdentity            RTOS_GetIdentity
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*
+********************************************************************************
+** end of file
+********************************************************************************
+*/
+#endif /* RTOS_LIB_H */
+
+
+

+ 130 - 0
bsp/gkipc/armv6/rtos_memory.h

@@ -0,0 +1,130 @@
+/*!
+*******************************************************************************
+**
+** \file        rtos_memory.h
+**
+** \version     1.0
+**
+** \date        March 20, 2003
+**
+** \author      Wolfgang Larisch
+**
+** \brief       A generic OS adaptation layer library
+**
+** This header file defines RTOS internal functions which are implemented
+** either in the uC/OS or the Nucleus port (maybe others OSes will follow in
+** the future).
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+** (C) Copyright 2002 - 2007 by Goke Microelectronics China
+**
+*******************************************************************************
+*/
+#ifndef RTOS_MEMORY_H
+#define RTOS_MEMORY_H
+#include "gtypes.h"
+#include "rtos_lib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+*******************************************************************************
+**
+** \brief Allocate a bunch of memory from the system heap
+**
+** This function allocates the given size of memory from the available
+** OS controlled SDRAM heap space.
+**
+** \param  size   size of memory in bytes to allocate.
+** \param  shared a boolean value which decides whether to allocate a
+**                memory block as shared (GTRUE) or as private (GFALSE)
+**                memory. Private memory can only be de-allocated by
+**                the thread that has allocated the memory, shared
+**                memory can be de-allocated by any thread.
+**
+** \return memory a pointer to the start address of the allocated memory
+**                block, or \b NULL if the required size of memory was not
+**                available.
+**
+** \sa     rtos_types
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_SysMemoryAllocate( RTOS_Size size, RTOS_Flag shared );
+
+/*!
+*******************************************************************************
+**
+** \brief Release (de-allocate) a bunch of system heap memory
+**
+** This function de-allocates a previoulsy allocated bunch of memory.
+**
+** \param  memory a pointer to the start of the memory block  to release.
+**
+** \return status the result status, either \b RTOS_OK,
+**                \b RTOS_MEMORY_FAILURE if the given memory pointer does not
+**                point to dynamic allocated memory  or \b RTOS_THREAD_FAILURE
+**                if the allocated memory space is owned by a different
+**                thread.
+**
+** \sa     rtos_types
+** \sa     rtos_status
+**
+*******************************************************************************
+*/
+RTOS_Status RTOS_SysMemoryRelease( RTOS_Memory memory );
+
+/*
+*******************************************************************************
+**
+** This function allocates the given size of memory from the available
+** OS controlled user heap.
+** For better performace, we control all the available OS handled RAM by
+** segments of a min. size of RTOS_HeapMinAllocSize bytes.
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_MemoryAllocate( RTOS_Size bytes, RTOS_Flag shared );
+
+RTOS_Memory RTOS_Malloc( RTOS_Size bytes);
+
+RTOS_Memory RTOS_Realloc( RTOS_Memory addr, RTOS_Size bytes );
+
+/*
+*******************************************************************************
+**
+** This function de-allocates a previoulsy allocated bunch of memory
+** within the user heap.
+**
+*******************************************************************************
+*/
+RTOS_Status RTOS_MemoryRelease( RTOS_Memory memory );
+
+/*
+*******************************************************************************
+**
+** This function sets the given amount of bytes in the given source address
+** the the specified byte value.
+**
+*******************************************************************************
+*/
+RTOS_Memory RTOS_MemorySet( RTOS_Memory mem, U8 value, RTOS_Size bytes );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+*******************************************************************************
+**
+** end
+**
+*******************************************************************************
+*/
+#endif /* RTOS_MEMORY_H */

+ 77 - 0
bsp/gkipc/armv6/stack.c

@@ -0,0 +1,77 @@
+/*
+ * File      : stack.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtthread.h>
+
+/*****************************/
+/* CPU Mode                  */
+/*****************************/
+#define USERMODE		0x10
+#define FIQMODE			0x11
+#define IRQMODE			0x12
+#define SVCMODE			0x13
+#define ABORTMODE		0x17
+#define UNDEFMODE		0x1b
+#define MODEMASK		0x1f
+#define NOINT			0xc0
+
+/**
+ * This function will initialize thread stack
+ *
+ * @param tentry the entry of thread
+ * @param parameter the parameter of entry 
+ * @param stack_addr the beginning stack address
+ * @param texit the function will be called when thread exit
+ *
+ * @return stack address
+ */
+rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
+	rt_uint8_t *stack_addr, void *texit)
+{
+	rt_uint32_t *stk;
+
+    stack_addr += sizeof(rt_uint32_t);
+    stack_addr  = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
+    stk      = (rt_uint32_t *)stack_addr;
+
+    *(--stk) = (rt_uint32_t)tentry;         /* entry point */
+    *(--stk) = (rt_uint32_t)texit;          /* lr */
+    *(--stk) = 0xdeadbeef;                  /* r12 */
+    *(--stk) = 0xdeadbeef;                  /* r11 */
+    *(--stk) = 0xdeadbeef;                  /* r10 */
+    *(--stk) = 0xdeadbeef;                  /* r9 */
+    *(--stk) = 0xdeadbeef;                  /* r8 */
+    *(--stk) = 0xdeadbeef;                  /* r7 */
+    *(--stk) = 0xdeadbeef;                  /* r6 */
+    *(--stk) = 0xdeadbeef;                  /* r5 */
+    *(--stk) = 0xdeadbeef;                  /* r4 */
+    *(--stk) = 0xdeadbeef;                  /* r3 */
+    *(--stk) = 0xdeadbeef;                  /* r2 */
+    *(--stk) = 0xdeadbeef;                  /* r1 */
+    *(--stk) = (rt_uint32_t)parameter;      /* r0 : argument */
+	*(--stk) = SVCMODE;						/* cpsr */
+	*(--stk) = SVCMODE;						/* spsr */
+
+	/* return task's current stack address */
+	return (rt_uint8_t *)stk;
+}
+

+ 481 - 0
bsp/gkipc/armv6/start_gcc.s

@@ -0,0 +1,481 @@
+/*
+ * File      : start.S
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date                 Author          Notes
+ * 2016/3/9 16:27:48    louis           first version
+ */
+
+#define CONFIG_STACKSIZE    512
+#define S_FRAME_SIZE        72
+
+#define S_OLD_R0            68
+#define S_PSR               64
+#define S_PC                60
+#define S_LR                56
+#define S_SP                52
+
+#define S_IP                48
+#define S_FP                44
+#define S_R10               40
+#define S_R9                36
+#define S_R8                32
+#define S_R7                28
+#define S_R6                24
+#define S_R5                20
+#define S_R4                16
+#define S_R3                12
+#define S_R2                8
+#define S_R1                4
+#define S_R0                0
+
+.equ    USERMODE,           0x10
+.equ    FIQMODE,            0x11
+.equ    IRQMODE,            0x12
+.equ    SVCMODE,            0x13
+.equ    ABORTMODE,          0x17
+.equ    UNDEFMODE,          0x1b
+.equ    MODEMASK,           0x1f
+.equ    NOINT,              0xc0
+
+
+
+
+    .text
+    .section ".ARM1176START"
+    .code 32
+
+
+@*******************************************************************************
+@** Common cpu modes
+@*******************************************************************************
+
+    .equ ARM1176_MODE_USR,   0x10  @ CPSR_c xxx10000
+    .equ ARM1176_MODE_FIQ,   0x11  @ CPSR_c xxx10001
+    .equ ARM1176_MODE_IRQ,   0x12  @ CPSR_c xxx10010
+    .equ ARM1176_MODE_SVC,   0x13  @ CPSR_c xxx10011
+    .equ ARM1176_MODE_ABT,   0x17  @ CPSR_c xxx10111
+    .equ ARM1176_MODE_UND,   0x1B  @ CPSR_c xxx11011
+    .equ ARM1176_MODE_SYS,   0x1F  @ CPSR_c xxx11111
+    .equ ARM1176_CPSR_I_BIT, 0x80  @ CPSR_c 100xxxxx
+    .equ ARM1176_CPSR_F_BIT, 0x40  @ CPSR_c 010xxxxx
+    .equ ARM1176_CPSR_T_BIT, 0x20  @ CPSR_c 001xxxxx
+
+
+
+.globl _start
+.globl  ARM1176_Start
+_start:
+ARM1176_Start:
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    ldr r0, =Reset          ;@load translation table base address
+    mcr p15,0,r0,c12,c0,0   ;@write translation table base address req
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+    nop
+Reset:
+    ldr pc, =reset
+    ldr pc, =vector_undef
+    ldr pc, =vector_swi
+    ldr pc, =vector_pabt
+    ldr pc, =vector_dabt
+    ldr pc, =vector_resv
+    ldr pc, =vector_irq
+    ldr pc, =vector_fiq
+    nop
+    nop
+
+
+.balignl    16,0xdeadbeef
+
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ * relocate armboot to ram
+ * setup stack
+ * jump to second stage
+ *
+ *************************************************************************
+ */
+
+
+/*
+ * rtthread bss start and end which are defined in linker script
+ */
+
+
+.extern __stack_start__
+
+
+
+.equ Mode_USR,        0x10
+.equ Mode_FIQ,        0x11
+.equ Mode_IRQ,        0x12
+.equ Mode_SVC,        0x13
+.equ Mode_ABT,        0x17
+.equ Mode_UND,        0x1B
+.equ Mode_SYS,        0x1F
+
+.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
+.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
+
+.equ UND_Stack_Size,  0x00000200
+.equ SVC_Stack_Size,  0x00000200
+.equ ABT_Stack_Size,  0x00000000
+.equ FIQ_Stack_Size,  0x00000000
+.equ IRQ_Stack_Size,  0x00000200
+.equ USR_Stack_Size,  0x00000200
+
+#define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                 FIQ_Stack_Size + IRQ_Stack_Size)
+
+.globl stack_top
+stack_top:
+    .word __stack_start__
+
+
+
+    .extern ARM1176_TcmInitialise
+    .extern ARM1176_MmuInitialise
+    .extern GH_VIC_set_EdgeClr
+    .extern entry
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table
+ *
+ *************************************************************************
+ */
+
+/* ----------------------------------entry------------------------------*/
+reset:
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    @/* First read in some misc registers */
+    mrc p15, 0, r0, c0, c0, 0     @/* Read ID value {A5S=0x41 1 7 b36 5}*/
+    mrc p15, 0, r1, c0, c0, 1     @/* Read cache type {0x1d152152}*/
+    mrc p15, 0, r2, c0, c0, 2     @/* Read TCM status {0x10001}*/
+
+#ifdef GK7102C    
+    @mrc    p15, 0, r0, c15,c14,0  @ read CP15 register c15 into r0
+    @orr    r0,  r0,#0x80000000    @ system bit enabled
+    @bic    r0,  r0,#0x00000077    @
+    @orr    r0,  r0,#0x00000055    @ specifies 16KB data cache
+    @mcr    p15, 0, r0, c15,c14,0  @ wraite CP15 register c15 into r0
+
+    mrc     p15, 0, r0, c1, c0, 1  @read CP15 register c1 into r0
+    orr     r0,  r0,#0x00000040    @CZ bit enabled
+    mcr     p15, 0, r0, c1, c0, 1  @read CP15 register c1 into r0
+#endif
+    
+    @/* Turn on instrucion cache and disable MMU */
+    mrc p15, 0, r0, c1, c0, 0     @/* Read control register {0x5327d}*/
+    @bic r0, r0, #0x1000          @ Turn off bit 12 - I-cache
+    orr    r0, r0, #0x1000        @ Turn on bit 12 - I-cache
+    @bic r0, r0, #0x0004          @ Turn off bit 03 - D-cache
+    orr    r0, r0, #0x0004        @ Turn on bit 03 - D-cache
+    bic r0, r0, #0x2000           @ Turn off bit 13 - HV
+    bic r0, r0, #0x0001           @ Turn off bit 1 - MMU
+
+    @orr    r0, r0, #0x2    @ Turn on bit 1 - Alignment fault
+    bic r0, r0, #0x400000   @ Turn off bit 22 - Unainged support
+
+    @bic    r0, r0, #0x2        @ Turn off bit 1 - Alignment fault
+    @orr    r0, r0, #0x400000   @ Turn on bit 22 - Unainged support
+
+    mcr p15, 0, r0, c1, c0, 0   @/* Write control register */
+
+    mov r0, #0x1
+    mcr p15, 0, r0, c3, c0, 0   @/* Write domain access control reg */
+
+
+    @bl switch_core_freq    @/* Change PLL for core if necessary */
+    @bl memsetup5       @/* Initialize Memory */
+
+
+    @/* -------------------------------------------------- */
+    @/* Redirect peripheral port 0x60000000 - 0x7fffffff   */
+    @/* -------------------------------------------------- */
+    .if CPU_USE_GK710XS==1
+    mov r0, #0x80000000
+    orr r0, r0, #0x00000015 @0x14=512M
+    .else
+    mov r0, #0x60000000
+    orr r0, r0, #0x00000014 @0x14=512M
+    .endif
+    mcr p15, 0, r0, c15, c2, 4
+
+    @ clear the irq or fiq first
+    mov r0,#0x0
+    mov r1,#0xFFFFFFFF
+    bl GH_VIC_set_EdgeClr
+    mov r0,#0x1
+    mov r1,#0xFFFFFFFF
+    bl GH_VIC_set_EdgeClr
+
+    nop
+
+    @ bl ARM1176_TcmInitialise
+    msr cpsr_c,#(ARM1176_MODE_SYS | ARM1176_CPSR_I_BIT | ARM1176_CPSR_F_BIT)    @disable irq/fiq first
+    .if ARM1176_USE_VFP == 1
+    bl ARM1176_VfpInitialise
+    bl ARM1176_VfpSetFastmode
+    .endif
+    bl ARM1176_Invalid_Cache
+
+    /* setup stack */
+    ldr     r0, =stack_top
+    ldr     r0, [r0]
+
+    @  Enter Undefined Instruction Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_UND|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #UND_Stack_Size
+
+    @  Enter Abort Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_ABT|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #ABT_Stack_Size
+
+    @  Enter FIQ Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_FIQ|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #FIQ_Stack_Size
+
+    @  Enter IRQ Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #IRQ_Stack_Size
+
+    @  Enter Supervisor Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #SVC_Stack_Size
+
+    @  Enter User Mode and set its Stack Pointer
+    mov     sp, r0
+    sub     sl, sp, #USR_Stack_Size
+
+    /* clear .bss */
+    mov     r0,#0                   /* get a zero                       */
+    ldr     r1,=__bss_start__         /* bss start                      */
+    ldr     r2,=__bss_end__           /* bss end                            */
+
+bss_loop:
+    cmp     r1,r2                   /* check if data to clear           */
+    strlo   r0,[r1],#4              /* clear 4 bytes                    */
+    blo     bss_loop                /* loop until done                  */
+
+    /* call C++ constructors of global objects                          */
+    ldr     r0, =__ctors_start__
+    ldr     r1, =__ctors_end__
+
+ctor_loop:
+    cmp     r0, r1
+    beq     ctor_end
+    ldr     r2, [r0], #4
+    stmfd   sp!, {r0-r1}
+    mov     lr, pc
+    bx      r2
+    ldmfd   sp!, {r0-r1}
+    b       ctor_loop
+
+ctor_end:
+
+
+    @ need nocache buffer
+    bl ARM1176_MmuInitialise
+
+    /* start RT-Thread Kernel       */
+    ldr     pc, =entry
+
+    .global ARM1176_Invalid_Cache
+    .func   ARM1176_Invalid_Cache
+
+ARM1176_Invalid_Cache:
+    stmfd sp!,{r0-r12,lr}
+    mov r11,lr
+
+    mov r0,#0x0        @Set [31:30]
+    mov r1,#0x3
+loop1:
+    mov r2,#0x0
+    mov r3,#0x80
+
+loop2:
+    mov r4,r0,LSL #30
+    mov r5,r2,LSL #5        @Index [S+4:5] S=8 32K
+    add r4,r4,r5
+    mcr    p15, 0, r4, c7, c5, 2
+    add r2,r2,#0x1
+    cmp r2,r3
+    bne loop2
+
+    add r0,r0,#1
+    cmp r0,r1
+    bne loop1
+
+    mov lr,r11            @ restore link register
+    ldmfd sp!,{r0-r12,lr}
+    bx lr                 @ branch back to caller
+
+    .size ARM1176_Invalid_Cache, . - ARM1176_Invalid_Cache
+    .endfunc
+
+
+.global cpu_reset
+cpu_reset:
+    mov pc, lr
+
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+
+/* exception handlers               */
+    .align  5
+vector_undef:
+    sub     sp, sp, #S_FRAME_SIZE
+    stmia   sp, {r0 - r12}          /* Calling r0-r12                   */
+    add     r8, sp, #S_PC
+    stmdb   r8, {sp, lr}^           /* Calling SP, LR                   */
+    str     lr, [r8, #0]            /* Save calling PC                  */
+    mrs     r6, spsr
+    str     r6, [r8, #4]            /* Save CPSR                        */
+    str     r0, [r8, #8]            /* Save OLD_R0                      */
+    mov     r0, sp
+
+    bl      rt_hw_trap_udef
+
+    .align  5
+vector_swi:
+    bl      rt_hw_trap_swi
+
+    .align  5
+vector_pabt:
+    bl      rt_hw_trap_pabt
+
+    .align  5
+vector_dabt:
+    sub     sp, sp, #S_FRAME_SIZE
+    stmia   sp, {r0 - r12}          /* Calling r0-r12                   */
+    add     r8, sp, #S_PC
+    stmdb   r8, {sp, lr}^           /* Calling SP, LR                   */
+    str     lr, [r8, #0]            /* Save calling PC                  */
+    mrs     r6, spsr
+    str     r6, [r8, #4]            /* Save CPSR                        */
+    str     r0, [r8, #8]            /* Save OLD_R0                      */
+    mov     r0, sp
+
+    bl      rt_hw_trap_dabt
+
+    .align  5
+vector_resv:
+    bl      rt_hw_trap_resv
+
+    .align  5
+.globl      rt_interrupt_enter
+.globl      rt_interrupt_leave
+.globl      rt_thread_switch_interrupt_flag
+.globl      rt_interrupt_from_thread
+.globl      rt_interrupt_to_thread
+vector_irq:
+    stmfd   sp!, {r0-r12,lr}
+    bl      rt_interrupt_enter
+    bl      rt_hw_trap_irq
+    bl      rt_interrupt_leave
+
+    /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
+    ldr     r0, =rt_thread_switch_interrupt_flag
+    ldr     r1, [r0]
+    cmp     r1, #1
+    beq     _interrupt_thread_switch
+
+    ldmfd   sp!, {r0-r12,lr}
+    subs    pc, lr, #4
+
+    .align  5
+vector_fiq:
+    stmfd   sp!,{r0-r7,lr}
+    bl      rt_hw_trap_fiq
+    ldmfd   sp!,{r0-r7,lr}
+    subs    pc,lr,#4
+
+_interrupt_thread_switch:
+    mov     r1,  #0                 /* clear rt_thread_switch_interrupt_flag*/
+    str     r1,  [r0]
+
+    ldmfd   sp!, {r0-r12,lr}        /* reload saved registers           */
+    stmfd   sp!, {r0-r3}            /* save r0-r3                       */
+    mov     r1,  sp
+    add     sp,  sp, #16            /* restore sp                       */
+    sub     r2,  lr, #4             /* save old task's pc to r2         */
+
+    mrs     r3,  spsr               /* disable interrupt                */
+    orr     r0,  r3, #NOINT
+    msr     spsr_c, r0
+
+    ldr     r0,  =.+8               /* switch to interrupted task's stack*/
+    movs    pc,  r0
+
+    stmfd   sp!, {r2}               /* push old task's pc               */
+    stmfd   sp!, {r4-r12,lr}        /* push old task's lr,r12-r4        */
+    mov     r4,  r1                 /* Special optimised code below     */
+    mov     r5,  r3
+    ldmfd   r4!, {r0-r3}
+    stmfd   sp!, {r0-r3}            /* push old task's r3-r0            */
+    stmfd   sp!, {r5}               /* push old task's psr              */
+    mrs     r4,  spsr
+    stmfd   sp!, {r4}               /* push old task's spsr             */
+
+    ldr     r4,  =rt_interrupt_from_thread
+    ldr     r5,  [r4]
+    str     sp,  [r5]               /* store sp in preempted tasks's TCB*/
+
+    ldr r6,  =rt_interrupt_to_thread
+    ldr r6,  [r6]
+    ldr sp,  [r6]                   /* get new task's stack pointer     */
+
+    ldmfd   sp!, {r4}               /* pop new task's spsr              */
+    msr     SPSR_cxsf, r4
+    ldmfd   sp!, {r4}               /* pop new task's psr               */
+    msr     CPSR_cxsf, r4
+
+    ldmfd   sp!, {r0-r12,lr,pc}     /* pop new task's r0-r12,lr & pc    */
+
+
+
+@*******************************************************************************
+@** End of file
+@*******************************************************************************
+

+ 56 - 0
bsp/gkipc/armv6/system_clock.c

@@ -0,0 +1,56 @@
+/*
+ * File      : clock.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include "gk7101.h"
+#include "board.h"
+
+/**
+ * @brief System Clock Configuration
+ */
+void rt_hw_clock_init(void)
+{
+
+}
+
+void rt_hw_us_delay(rt_uint32_t us)
+{
+    rt_uint32_t     start_time = 0;
+    rt_uint32_t     end_time = 0;
+    int     time_difference  = 0;
+
+    start_time = gkosGetTicks();
+    do
+    {
+        end_time = gkosGetTicks();
+        time_difference = (rt_uint32_t)(end_time - start_time);
+        /* check overflow */
+        if(start_time > end_time)
+        {
+            time_difference = ((time_difference < 0L) ? -time_difference : time_difference); /* C-LIB code for labs() */
+        }
+    }while(time_difference < (us/1000));
+
+}
+
+

+ 250 - 0
bsp/gkipc/armv6/trap.c

@@ -0,0 +1,250 @@
+/*
+ * File      : trap.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Development Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "gk7101.h"
+#include <gtypes.h>
+#include <gd_int.h>
+#include "rtos_lib.h"
+
+
+extern struct rt_thread *rt_current_thread;
+#ifdef RT_USING_FINSH
+extern long list_thread(void);
+#endif
+
+/**
+ * this function will show registers of CPU
+ *
+ * @param regs the registers point
+ */
+
+/* FIXME(Heyong): add for print the system infos when sys abort */
+static void _rtt_statistics()
+{
+    rt_uint32_t total;
+    rt_uint32_t used;
+    rt_uint32_t max_used;
+    struct rt_thread *thread;
+    struct rt_list_node *node;
+    rt_uint8_t *ptr;
+
+    rt_base_t level;
+    struct rt_object_information *information;
+
+    information = rt_object_get_information(RT_Object_Class_Thread);
+    RT_ASSERT(information != RT_NULL);
+
+    struct rt_list_node *list = &(information->object_list);
+
+    level = rt_hw_interrupt_disable();
+
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+        //if(thread) thread->total_tick = 0;
+    }
+
+    rt_hw_interrupt_enable(level);
+    rt_memory_info(&total,&used,&max_used);
+    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+    rt_kprintf("\n         memory info       size \n");
+    rt_kprintf("------------------------- ------\n");
+    rt_kprintf("total memory:             (%dKB)\n",  total/1024);
+    rt_kprintf("used memory :             (%dKB)\n",  used/1024);
+    rt_kprintf("maximum allocated memory: (%dKB)\n\n",  max_used/1024);
+
+    rt_kprintf("          thread                 pri  status     sp     stack addr stack size  max used \n");
+    rt_kprintf("-------------------------------- --- ------- ---------- ---------- ---------- ---------- \n");
+    for (node = list->next; node != list; node = node->next)
+    {
+        thread = rt_list_entry(node, struct rt_thread, list);
+#if 0
+        rt_kprintf("%-32.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
+#else
+        int priority = thread->current_priority;
+        rt_kprintf("%-32.*s %03d", RT_NAME_MAX, thread->name, priority);
+#endif
+        if (thread->stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
+        else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
+        else if (thread->stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
+        else if (thread->stat == RT_THREAD_CLOSE)   rt_kprintf(" close  ");
+
+        ptr = (rt_uint8_t*)thread->stack_addr;
+        while (*ptr == '#')ptr++;
+
+        rt_kprintf("  0x%08x 0x%08x 0x%08x 0x%08x  \n",
+            thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
+            thread->stack_addr,
+            thread->stack_size,
+            thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr)
+           );
+    }
+    rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+}
+
+// FIXME(heyong): add for debug when sys abort.
+int g_eth_input = 0;
+int g_eth_output = 0;
+int g_wifi_input = 0;
+int g_wifi_output = 0;
+void rt_hw_show_register (struct rt_hw_register *regs)
+{
+	rt_kprintf("Execption:\n");
+	rt_kprintf("r00:0x%08x r01:0x%08x r02:0x%08x r03:0x%08x\n", regs->r0, regs->r1, regs->r2, regs->r3);
+	rt_kprintf("r04:0x%08x r05:0x%08x r06:0x%08x r07:0x%08x\n", regs->r4, regs->r5, regs->r6, regs->r7);
+	rt_kprintf("r08:0x%08x r09:0x%08x r10:0x%08x\n", regs->r8, regs->r9, regs->r10);
+	rt_kprintf("fp :0x%08x ip :0x%08x\n", regs->fp, regs->ip);
+	rt_kprintf("sp :0x%08x lr :0x%08x pc :0x%08x\n", regs->sp, regs->lr, regs->pc);
+	rt_kprintf("cpsr:0x%08x\n", regs->cpsr);
+	rt_kprintf("eth info : in = %d out = %d\n", g_eth_input, g_eth_output);
+	rt_kprintf("wifi info: in = %d out = %d\n", g_wifi_input, g_wifi_output);
+	_rtt_statistics();
+}
+
+/**
+ * When ARM7TDMI comes across an instruction which it cannot handle,
+ * it takes the undefined instruction trap.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_udef(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("undefined instruction\n");
+	rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * The software interrupt instruction (SWI) is used for entering
+ * Supervisor mode, usually to request a particular supervisor
+ * function.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_swi(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("software interrupt\n");
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_register *regs)
+{
+	rt_hw_show_register(regs);
+
+	rt_kprintf("prefetch abort\n");
+	rt_kprintf("thread - %s stack:\n", rt_current_thread->name);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * An abort indicates that the current memory access cannot be completed,
+ * which occurs during a data access.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_dabt(struct rt_hw_register *regs)
+{
+
+	rt_kprintf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
+	rt_kprintf("data abort\n");
+	rt_kprintf("thread - [%s] stack:\n", rt_current_thread->name);
+
+	rt_hw_show_register(regs);
+
+#ifdef RT_USING_FINSH
+	list_thread();
+#endif
+	rt_hw_cpu_shutdown();
+}
+
+/**
+ * Normally, system will never reach here
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_resv(struct rt_hw_register *regs)
+{
+	rt_kprintf("not used\n");
+	rt_hw_show_register(regs);
+	rt_hw_cpu_shutdown();
+}
+
+extern struct rt_irq_desc irq_desc[];
+
+void rt_hw_trap_irq()
+{
+    int index;
+	//rt_kprintf("irq interrupt request\n");
+    GD_IRQ_ISR();
+
+	if(gkosHookData)
+	{
+	    for( index=0; index < gkosHookData->timerFunctionCount; index++ )
+	    {
+	        if( gkosHookData->timerFunctionArray[index] )
+	        {
+	            (*gkosHookData->timerFunctionArray[index])(NULL);
+	        }
+	    }
+	}
+}
+
+void rt_hw_trap_fiq()
+{
+	//rt_kprintf("fast interrupt request\n");
+	GD_FIQ_ISR();
+	//rt_tick_increase();
+}
+
+/*@}*/

+ 24 - 0
bsp/gkipc/drivers/SConscript

@@ -0,0 +1,24 @@
+from building import *
+Import('rtconfig')
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+path = [cwd + '/..']
+
+if GetDepend('SOC_GK7101') or GetDepend('SOC_GK7102'):
+    path += [cwd + '/../libraries/drv/710X/gh/inc', cwd + '/../libraries/drv/710X/gd/inc']
+elif GetDepend('SOC_GK7101S') or GetDepend('SOC_GK7102S'):
+    path += [cwd + '/../libraries/drv/710XS/gh/inc', cwd + '/../libraries/drv/710XS/gd/inc']
+elif GetDepend('SOC_GK7102C'):
+    path += [cwd + '/../libraries/drv/7102C/gh/inc', cwd + '/../libraries/drv/7102C/gd/inc']
+	
+path += [cwd + '/../../../components/drivers/include/drivers']
+path += [cwd + '/../libraries/adi/inc']
+path += [cwd + '/../platform/board']
+path += [cwd + '/../platform']
+
+libcwd = str(Dir('#'))
+
+group = DefineGroup('drivers', src, depend = [''], CPPPATH = path)
+
+Return('group')

+ 131 - 0
bsp/gkipc/drivers/board.c

@@ -0,0 +1,131 @@
+#include <rtthread.h>
+#include <rthw.h>
+
+#include "gd_int.h"
+#include "gd_gpio.h"
+#include "gd_timer.h"
+#include "drv_uart.h"
+#include "gpio_cfg.h"
+#include "board.h"
+#include "drv_flash.h"
+#include "gh_debug_rct.h"
+
+#ifdef RT_USING_I2C
+#include "drv_i2c.h"
+#endif
+
+#ifdef RT_USING_SPI
+#include "drv_ssi.h"
+#endif
+
+#ifdef RT_USING_WDT
+#include "drv_wdt.h"
+#endif
+
+#ifdef RT_USING_GK_DMA
+#include "drv_dma.h"
+#endif
+
+#ifdef RT_USING_ADC
+#include "drv_adc.h"
+#endif
+
+#ifdef RT_USING_PWM
+#include "drv_pwm.h"
+#endif
+#include "rtos_lib.h"
+
+extern unsigned char __heap_start__[];
+extern unsigned char __heap_end__[];
+extern unsigned char __nocache_buffer_start__[];
+
+/**
+ * This function will init goke board
+ */
+void rt_hw_board_init(void)
+{
+    rt_uint32_t code_seg_size = 0;
+    rt_uint32_t heap_seg_size = 0;
+    rt_uint32_t os_end_address=0;
+
+    GD_TIMER_INIT_PARAMS_S gdTimerParams;
+    GD_GPIO_XREF_S gdGpioXrefTable[] = { SYSTEM_GPIO_XREF_TABLE };
+    GD_GPIO_INIT_PARAMS_S gdGpioInitParam =
+    {
+        .irqPriority = GD_INT_MID_PRIORITY,
+        .phyType = 0,
+        .xrefTableCount = sizeof(gdGpioXrefTable)/sizeof(gdGpioXrefTable[0]),
+        .xrefTable = gdGpioXrefTable,
+    };
+
+    gdTimerParams.softTimerReg      = GD_REG_TIMER1;
+    gdTimerParams.hardTimerReg      = GD_REG_TIMER2;
+    gdTimerParams.gpregTimerReg     = GD_REG_TIMER3;
+    gdTimerParams.softTimerpriority  = GD_INT_MID_PRIORITY;
+    gdTimerParams.hardTimerpriority  = GD_INT_MID_PRIORITY;
+    gdTimerParams.gpregTimerpriority = GD_INT_MID_PRIORITY;
+
+    GD_INT_DisableAllInterrupts();
+
+    // Sensor ioctrl
+    GH_PLL_set_IOCTRL_SENSOR(0x00000012);
+
+    GD_INT_Init(NULL);
+    GD_TIMER_Init(&gdTimerParams);
+    GD_GPIO_Init(&gdGpioInitParam);
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+
+    /* initialize heap memory system */
+    code_seg_size = __heap_end__ - __nocache_buffer_start__;
+    heap_seg_size = DDR_MEMORY_OS_SIZE - code_seg_size;
+    os_end_address= (rt_uint32_t)__heap_end__+heap_seg_size;
+    rt_system_heap_init((void*)__heap_end__, (void*)os_end_address);
+
+    /* initialize uart */
+    rt_hw_uart_init();
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+
+    /* initalize sflash */
+    rt_flash_init();
+
+    RTOS_HwTickInit();
+}
+
+int rt_board_driver_init(void)
+{
+#ifdef RT_USING_I2C
+    rt_hw_i2c_init();
+#endif
+
+#ifdef RT_USING_SPI
+    rt_hw_spi_init();
+#endif
+
+#ifdef RT_USING_WDT
+    rt_hw_wdt_init();
+#endif
+
+#ifdef RT_USING_GK_DMA
+    rt_gk_dma_init();
+#endif
+
+#ifdef RT_USING_ADC
+    rt_hw_adc_init();
+#endif
+
+#ifdef RT_USING_PWM
+    rt_hw_pwm_init();
+#endif
+
+    return 0;
+}
+
+//static unsigned long nticks = 0;
+unsigned long gkosGetTicks(void)
+{
+    return rt_tick_get();
+}
+
+/*@}*/

+ 32 - 0
bsp/gkipc/drivers/board.h

@@ -0,0 +1,32 @@
+/*
+ * File      : board.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006, RT-Thread Develop Team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-01-13     weety      add board.h to this bsp
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+unsigned long gkosGetTicks(void);
+void rt_hw_board_init(void);
+int rt_board_driver_init(void);
+
+#endif

+ 237 - 0
bsp/gkipc/drivers/drv_adc.c

@@ -0,0 +1,237 @@
+/*
+ * File      : drv_adc.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "drv_adc.h"
+#ifdef RT_USING_ADC
+#include "gtypes.h"
+#include "gd_adc.h"
+#include "platform.h"
+
+#include <rtdef.h>
+#include <rtthread.h>
+
+#define GK_TEST_ADC
+
+#define IOCTL_GET_ADC_DATA 1
+#define IOCTL_ADC_POWER_DOWN 0xff
+#define ADC_WRAP_BASE (0xf1200000)
+#define ADC_IRQn (23)
+#define ADC_MAX_CONTROLLER (1)
+#define ADC_STATUS_COLESD (0)
+#define ADC_STATUS_OPEN (1)
+
+static rt_err_t gk_adc_read_data(struct wrap_adc_obj *adc, rt_uint32_t channel,
+                               rt_uint32_t *buf)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = GD_ADC_Read((GD_HANDLE*)&(adc->handle), buf);
+
+    return ret;
+}
+
+static rt_err_t gk_adc_init(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = (rt_err_t)GD_ADC_Init();
+
+    return ret;
+}
+
+static rt_err_t gk_adc_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    rt_err_t ret = RT_EOK;
+    GD_ADC_OPEN_PARAMS_S openParams;
+
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+    rt_memset(&openParams, 0, sizeof(GD_ADC_OPEN_PARAMS_S));
+    openParams.channel = adc_pri->active_channel_no;
+
+    ret = (rt_err_t)GD_ADC_Open(&openParams, (GD_HANDLE*)&(adc_pri->handle));
+
+    return ret;
+}
+
+static rt_err_t gk_adc_close(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+
+    ret = (rt_err_t)GD_ADC_Close((GD_HANDLE*)(adc_pri->handle));
+
+    return ret;
+}
+
+static rt_err_t gk_adc_ioctl(rt_device_t dev, int cmd, void *arg)
+{
+    rt_uint32_t control_reg;
+    struct wrap_adc_obj *adc_pri = (struct wrap_adc_obj *)dev->user_data;
+    rt_uint32_t ad_data;
+
+    ADC_INFO *adc_info = (ADC_INFO *)arg;
+    rt_err_t ret;
+
+    switch (cmd)
+    {
+        case ADC_CMD_READ_RAW_DATA:
+            ret = gk_adc_read_data(adc_pri, adc_info->channel, &ad_data);
+            if (ret != RT_EOK)
+            {
+                return ret;
+            }
+
+            adc_info->adc_data = ad_data;
+
+            break;
+
+        case ADC_CMD_DISABLE:
+            gk_adc_close(dev);
+
+            break;
+
+        default:
+            rt_kprintf("wrong para...\n");
+            return RT_EIO;
+    }
+
+    return RT_EOK;
+}
+
+int gk_adc_probe(void *priv_data)
+{
+    rt_device_t adc_dev;
+    // check if the hw is init already...
+    // caution this is a read only data...if the driver want to use.malloc and
+    // copy it..
+    struct wrap_adc_obj *adc_obj = (struct wrap_adc_obj *)priv_data;
+    if (adc_obj->init_flag == ADC_INIT_ALREADY) return RT_EFULL;
+
+    // malloc a rt device..
+    adc_dev = RT_KERNEL_MALLOC(sizeof(struct rt_device));
+    if (!adc_dev)
+    {
+        return RT_ENOMEM;
+    }
+    rt_memset(adc_dev, 0, sizeof(struct rt_device));
+    rt_kprintf("id:%d\n", adc_obj->id);
+
+    // bind rtdev to obj data...
+    // caution ...this is used to free mem when exit....
+    // free step:1:get adc obj...2:free adc_obj->rt_dev->user_data..3:free
+    // adc_obj->rt_dev 4:adc_obj->rt_dev = NULL
+    adc_obj->rt_dev = adc_dev;
+
+    // malloc a private data adc use only...copy data from platform...
+    struct wrap_adc_obj *adc_pri =
+        RT_KERNEL_MALLOC(sizeof(struct wrap_adc_obj));
+    if (!adc_pri)
+    {
+        RT_KERNEL_FREE(adc_dev);
+        return RT_ENOMEM;
+    }
+
+    // copy platform data to pri data..
+    rt_memcpy(adc_pri, adc_obj, sizeof(struct wrap_adc_obj));
+
+    rt_kprintf("id:%d\n", adc_pri->id);
+
+    // bind pri data to rt_adc_dev...
+    adc_dev->user_data = (void *)adc_pri;
+    adc_dev->open      = gk_adc_open;
+    adc_dev->close     = gk_adc_close;
+    adc_dev->control   = gk_adc_ioctl;
+    adc_dev->init      = gk_adc_init;
+    adc_dev->type      = RT_Device_Class_Miscellaneous;
+
+    rt_device_register(adc_dev, "adc", RT_DEVICE_FLAG_RDWR);
+
+    adc_obj->init_flag = ADC_INIT_ALREADY;
+
+    return RT_EOK;
+}
+
+int gk_adc_exit(void *priv_data)
+{
+    struct wrap_adc_obj *adc_obj = (struct wrap_adc_obj *)priv_data;
+
+    struct wrap_adc_obj *adc_pri = adc_obj->rt_dev->user_data;
+
+    RT_KERNEL_FREE(adc_obj->rt_dev->user_data);
+
+    adc_obj->rt_dev->user_data = RT_NULL;
+    RT_KERNEL_FREE(adc_obj->rt_dev);
+    adc_obj->rt_dev = RT_NULL;
+
+    GD_ADC_Exit();
+
+    return 0;
+}
+
+struct gk_platform_driver adc_driver_ops = {
+    .name = "adc", .probe = gk_adc_probe, .remove = gk_adc_exit,
+};
+
+void rt_hw_adc_init(void)
+{
+    gk_platform_driver_init(&adc_driver_ops);
+}
+
+#ifdef GK_TEST_ADC
+int gk_adc_test(void)
+{
+    rt_device_t adc_dev;
+    ADC_INFO info;
+    info.channel   = 0;
+    info.adc_data = 0;
+    adc_dev       = rt_device_find("adc");
+    if (!adc_dev)
+    {
+        rt_kprintf("cann't find the adc dev\n");
+        return -1;
+    }
+    adc_dev->init(adc_dev);
+    adc_dev->open(adc_dev, 0);
+    while (1)
+    {
+        adc_dev->control(adc_dev, ADC_CMD_READ_RAW_DATA, &info);
+        rt_kprintf("channel:%d, data:0x%x\n", info.channel, info.adc_data);
+    }
+
+    return 0;
+}
+#endif
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#ifdef GK_TEST_ADC
+FINSH_FUNCTION_EXPORT(gk_adc_test, gk_adc_test);
+#endif
+#endif
+
+#endif

+ 77 - 0
bsp/gkipc/drivers/drv_adc.h

@@ -0,0 +1,77 @@
+/*
+ * File      : drv_adc.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef ADC_H_
+#define ADC_H_
+
+#include <rtdef.h>
+#ifdef RT_USING_ADC
+
+/****************************************************************************
+ * #define section
+ *	add constant #define here if any
+ ***************************************************************************/
+#define MAX_CHANNEL_NO (2)
+#define ADC_INIT_ALREADY (0x33)
+
+#define ADC_CMD_READ_RAW_DATA (0x22)
+#define ADC_CMD_DISABLE (0x44)
+
+/****************************************************************************
+ * ADT section
+ *	add Abstract Data Type definition here
+ ***************************************************************************/
+
+struct wrap_adc_obj
+{
+    rt_uint32_t id;
+    rt_uint32_t init_flag;
+    rt_uint32_t active_channel_no;
+    rt_uint32_t handle;
+    rt_uint16_t channel_data[MAX_CHANNEL_NO];
+
+    // bind to the rtdev..
+    rt_device_t rt_dev;
+};
+
+typedef struct
+{
+    rt_uint32_t channel;
+    rt_uint32_t adc_data;
+} ADC_INFO;
+
+/****************************************************************************
+ *  extern variable declaration section
+ ***************************************************************************/
+
+/****************************************************************************
+ *  section
+ *	add function prototype here if any
+ ***************************************************************************/
+void rt_hw_adc_init(void);
+#endif
+#endif /* ADC_H_ */

+ 226 - 0
bsp/gkipc/drivers/drv_dma.c

@@ -0,0 +1,226 @@
+/*
+ * File      : drv_dma.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 ChengDu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+/*****************************************************************************
+ *  Include Section
+ *  add all #include here
+ *****************************************************************************/
+#include "drivers/drv_dma.h"
+
+#include "gd_dma.h"
+
+/*****************************************************************************
+ * Define section
+ * add all #define here
+ *****************************************************************************/
+
+//#define GK_DMA_DEBUG
+#ifndef GK_DMA_DEBUG
+#define DMA_PRINT_DBG(fmt, args...)
+#define DMA_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#else
+#define DMA_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
+#define DMA_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#endif
+
+/****************************************************************************
+ * ADT section
+ *  add definition of user defined Data Type that only be used in this file here
+ ***************************************************************************/
+
+static struct rt_dma_device _dma_device;
+
+
+/******************************************************************************
+ * Function prototype section
+ * add prototypes for all functions called by this file,execepting those
+ * declared in header file
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Global variables section - Exported
+ * add declaration of global variables that will be exported here
+ * e.g.
+ *  int8_t foo;
+ ****************************************************************************/
+
+/*****************************************************************************
+
+ *  static fun;
+ *****************************************************************************/
+static rt_err_t rt_dma_init(struct rt_device *dev);
+static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag);
+static rt_err_t rt_dma_close(struct rt_device *dev);
+static rt_err_t rt_dma_control(struct rt_device *dev, int cmd,void *args);
+/*****************************************************************************
+ * Global variables section - Local
+ * define global variables(will be refered only in this file) here,
+ * static keyword should be used to limit scope of local variable to this file
+ * e.g.
+ *  static uint8_t ufoo;
+ *****************************************************************************/
+
+/* function body */
+/*****************************************************************************
+ * Description:
+ *      add funtion description here
+ * Parameters:
+ *      description for each argument, new argument starts at new line
+ * Return:
+ *      what does this function returned?
+ *****************************************************************************/
+static rt_err_t rt_dma_init(struct rt_device *dev)
+{
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_open(struct rt_device *dev, rt_uint16_t oflag)
+{
+    rt_uint32_t retVal = 0;
+    struct rt_dma_device *dma;
+
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    retVal = GD_DMA_Open((GD_DMA_OPEN_PARAM_S *)&dma->openParam,(GD_HANDLE *)&dma->handle);
+    if(retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Open failed!\n");
+        return (-RT_ERROR);
+    }
+
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_close(struct rt_device *dev)
+{
+    rt_uint32_t retVal = 0;
+    struct rt_dma_device *dma;
+
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    GD_DMA_Stop((GD_HANDLE)dma->handle);
+
+    retVal = GD_DMA_Close((GD_HANDLE)dma->handle);
+    if (retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Close failed!\n");
+        return (-RT_ERROR);
+    }
+
+    return (RT_EOK);
+}
+
+static rt_err_t rt_dma_control(struct rt_device *dev, int cmd,void *args)
+{
+    rt_uint32_t retVal = 0;
+    rt_uint32_t des    = 0;
+    RT_DMA_DESCRIPTOR_S *descriptor;
+
+    struct rt_dma_device *dma;
+    RT_ASSERT(dev != RT_NULL);
+    dma = (struct rt_dma_device *)dev->user_data;
+
+    switch(cmd)
+    {
+        case DMA_CMD_ADD_DESCRIPTOR:
+            descriptor = (RT_DMA_DESCRIPTOR_S *)args;
+            retVal = GD_DMA_AddDescriptor((GD_HANDLE)dma->handle,(GD_DMA_DESCRIPTOR_S *)descriptor);
+            if (retVal != RT_EOK)
+            {
+                DMA_PRINT_ERR("GD_DMA_AddDescriptor failed!\n");
+                return (-RT_ERROR);
+            }
+
+            break;
+
+        case DMA_CMD_START:
+            des = *(rt_uint32_t*)args;
+            retVal = GD_DMA_Start((GD_HANDLE)dma->handle,des);
+            if (retVal != RT_EOK)
+            {
+                DMA_PRINT_ERR("GD_DMA_Start failed!\n");
+                return (-RT_ERROR);
+            }
+
+            break;
+
+        case DMA_CMD_STOP:
+            GD_DMA_Stop((GD_HANDLE)dma->handle);
+            break;
+
+        default:break;
+
+
+    }
+
+    return (RT_EOK);
+}
+
+/**
+ * This function register a dma device
+ */
+static rt_err_t rt_hw_dma_register(const char *name,rt_uint32_t flag)
+{
+    rt_uint32_t ret;
+    struct rt_device *device;
+
+    device = &(_dma_device.parent);
+
+    device->type        = RT_Device_Class_Miscellaneous;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+
+    device->init      = rt_dma_init;
+    device->open      = rt_dma_open;
+    device->close     = rt_dma_close;
+    device->read      = RT_NULL;
+    device->write     = RT_NULL;
+    device->control   = rt_dma_control;
+    device->user_data = (void *)&_dma_device;
+
+    /* register a character device */
+    ret = rt_device_register(device, name, flag);
+
+    return ret;
+}
+
+void rt_gk_dma_init(void)
+{
+    rt_uint32_t retVal = 0;
+
+    retVal = GD_DMA_Init();
+    if (retVal != RT_EOK)
+    {
+        DMA_PRINT_ERR("GD_DMA_Init failed!\n");
+		return;
+    }
+
+    rt_hw_dma_register("gk_dma",RT_DEVICE_FLAG_RDWR);
+}
+

+ 121 - 0
bsp/gkipc/drivers/drv_dma.h

@@ -0,0 +1,121 @@
+/*
+ * File      : drv_dma.h
+ * This file is part of FH8620 BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.fullhan.com to get contact with Fullhan.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef DMA_H_
+#define DMA_H_
+#include <rtthread.h>
+/****************************************************************************
+* #include section
+*	add #include here if any
+***************************************************************************/
+
+/****************************************************************************
+* #define section
+*	add constant #define here if any
+***************************************************************************/
+#define RT_DEVICE_CTRL_DMA_OPEN (1)
+#define RT_DEVICE_CTRL_DMA_CLOSE (2)
+#define RT_DEVICE_CTRL_DMA_REQUEST_CHANNEL (3)
+#define RT_DEVICE_CTRL_DMA_RELEASE_CHANNEL (4)
+#define RT_DEVICE_CTRL_DMA_SINGLE_TRANSFER (5)
+
+// cyclic add func below....
+
+#define RT_DEVICE_CTRL_DMA_CYCLIC_PREPARE (6)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_START (7)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_STOP (8)
+#define RT_DEVICE_CTRL_DMA_CYCLIC_FREE (9)
+#define RT_DEVICE_CTRL_DMA_PAUSE (10)
+#define RT_DEVICE_CTRL_DMA_RESUME (11)
+
+//#define RT_DEVICE_CTRL_  	 (3) /* get the left time before reboot(in
+//seconds) */
+//#define RT_DEVICE_CTRL_      (4) /* refresh watchdog */
+//#define RT_DEVICE_CTRL_      (5) /* start watchdog */
+//#define RT_DEVICE_CTRL_      (6) /* stop watchdog */
+
+/****************************************************************************
+* ADT section
+*	add Abstract Data Type definition here
+***************************************************************************/
+
+#define ADC_CMD_READ_RAW_DATA (0x22)
+#define ADC_CMD_DISABLE (0x44)
+
+
+/*dma cmd */
+typedef enum
+{
+    DMA_CMD_ADD_DESCRIPTOR = 0,
+    DMA_CMD_START,
+    DMA_CMD_STOP,
+}RT_DMA_DMD;
+
+
+
+typedef void (*RT_DMA_NOTIFIER_F)(void);
+
+typedef struct rt_dma_descriptor_s
+{
+    rt_uint32_t srcAddr;        /*  Source address */
+    rt_uint32_t dstAddr;        /* Destination address */
+    struct dma_descriptor_s *next; /* Pointing to next descriptor */
+    rt_uint32_t reportAddr;     /* The physical address to store DMA hardware reporting status */
+    rt_uint32_t dataLength;     /* Transfer byte count , max value = 2^22 */
+    rt_uint32_t descAttr;       /* Descriptor 's attribute */
+}RT_DMA_DESCRIPTOR_S;
+
+typedef struct
+{
+    rt_uint32_t      channel;
+    rt_uint32_t      mode;
+	RT_DMA_NOTIFIER_F intNotifier;
+}RT_DMA_OPEN_PARAM_S;
+
+typedef struct rt_dma_device
+{
+    // the parent must be the fitst para..
+    rt_uint32_t         handle;
+    struct rt_device    parent;
+    RT_DMA_OPEN_PARAM_S openParam;
+}rt_dma_device_s;
+
+
+/****************************************************************************
+*  extern variable declaration section
+***************************************************************************/
+
+/****************************************************************************
+*  section
+*	add function prototype here if any
+***************************************************************************/
+
+void rt_gk_dma_init(void);
+
+/********************************End Of File********************************/
+
+#endif

+ 349 - 0
bsp/gkipc/drivers/drv_flash.c

@@ -0,0 +1,349 @@
+#include <stdio.h>
+#include <rtdevice.h>
+
+#include "gtypes.h"
+#include "gd_sflash.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* local data types                                                          */
+/*---------------------------------------------------------------------------*/
+
+struct gk_flash
+{
+
+    struct rt_device device;
+    struct rt_mutex lock;
+    struct rt_device_blk_geometry flashinfo;
+
+    GD_HANDLE    handle;
+
+};
+
+static struct gk_flash flashdev;
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+
+
+static rt_uint32_t auctempArr[512] = {0};
+
+/*---------------------------------------------------------------------------*/
+/* local  functions                                                          */
+/*---------------------------------------------------------------------------*/
+static rt_err_t  gk_flash_init  (rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_err_t  gk_flash_open  (rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t  gk_flash_close (rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+static rt_size_t gk_flash_read  (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(buffer != RT_NULL);
+    RT_ASSERT(size > 0);
+    RT_ASSERT(dev->user_data != NULL);
+
+    int  ret     = 0;
+    rt_uint32_t temp        = 0;
+    rt_uint32_t readSize    = 0;
+    char *ptr            = NULL;
+    U8  readLastBuffer[4] = {0};
+    rt_uint32_t numReadSize        = 0;
+    rt_uint32_t offsetAddr         = 0;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    rt_memset(auctempArr, 0, 512);
+
+    if(pos%4 != 0)
+    {
+        temp = pos%4;
+        if((size+8) > 512)
+        {
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos-temp, auctempArr, 4);
+            readSize = 4-temp;
+            ptr = (char*)auctempArr;
+            rt_memcpy(buffer,ptr+temp,readSize);
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos+readSize, (rt_uint32_t *)buffer+readSize, (size-readSize)/4);
+        }
+        else
+        {
+            readSize = ((size+8)/4);
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos-temp, auctempArr, readSize);
+            ptr = (char *)auctempArr;
+            rt_memcpy(buffer, ptr+temp, size);
+        }
+    }
+    else
+    {
+        if (size % 4)
+        {
+            if (size/4 != 0)
+            {
+                ret |= GD_SFLASH_Read(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+                if ( ret != GD_OK )
+                {
+                   rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+                }
+            }
+
+            numReadSize = size % 4;
+            offsetAddr  = size - numReadSize;
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos+offsetAddr, (rt_uint32_t *)readLastBuffer, 1); // read 4 bytes
+            if ( ret != GD_OK )
+            {
+               rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+            }
+
+            rt_memcpy((U8 *)buffer+offsetAddr, readLastBuffer, numReadSize);
+
+        }
+        else
+        {
+            ret |= GD_SFLASH_Read(flashdevPtr->handle, pos, (rt_uint32_t *)buffer, size/4);
+            if ( ret != GD_OK )
+            {
+               rt_kprintf( "\n[%d][gk_flash_read] GD_SFLASH_Read_Byte err!!\n",__LINE__);
+            }
+        }
+
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return (ret == GD_OK)?RT_EOK:RT_ERROR;
+
+}
+
+static rt_size_t gk_flash_write (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(buffer != RT_NULL);
+    RT_ASSERT(size > 0);
+    RT_ASSERT(dev->user_data != NULL);
+
+    int ret             = GD_OK;
+    U8  writeLastBuffer[4] = {0};
+    rt_uint32_t numWriteSize       = 0;
+    rt_uint32_t offsetAddr         = 0;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    if(pos %4 != 0)
+    {
+        rt_kprintf("\n[gk_flash_write] the write flash address isn't assigned in 4 bytes.\n");
+        return RT_ERROR;
+    }
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    if(size%4)
+    {
+        if (size/4 != 0)
+        {
+            ret = GD_SFLASH_Write(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+            if ( ret != GD_OK )
+            {
+               rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+            }
+        }
+        numWriteSize = size%4;
+        offsetAddr   = size - numWriteSize;
+
+        rt_memcpy(writeLastBuffer, (U8 *)buffer+offsetAddr, numWriteSize);
+
+        ret |= GD_SFLASH_Program(flashdevPtr->handle, (pos + offsetAddr), (rt_uint32_t*)writeLastBuffer, 1);// write 4 bytes
+        if ( ret != GD_OK )
+        {
+           rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+        }
+    }
+    else
+    {
+        ret = GD_SFLASH_Write(flashdevPtr->handle, pos, (rt_uint32_t*)buffer, size/4);
+        if ( ret != GD_OK )
+        {
+           rt_kprintf("\n[gk_flash_write:%d] GD_SFLASH_Write_Byte err!!,ret = %ld\n",__LINE__,ret);
+        }
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return (ret == GD_OK)?RT_EOK:RT_ERROR;
+
+}
+
+static rt_err_t  gk_flash_control(rt_device_t dev, int cmd, void *args)
+{
+    RT_ASSERT(dev != RT_NULL);
+    RT_ASSERT(dev->user_data != NULL);
+    RT_ASSERT(args != RT_NULL);
+    rt_uint32_t i = 0,ret;
+
+    struct gk_flash *flashdevPtr = (struct gk_flash *)dev->user_data;
+
+    rt_mutex_take(&flashdevPtr->lock, RT_WAITING_FOREVER);
+
+    switch(cmd)
+    {
+        case RT_DEVICE_CTRL_BLK_GETGEOME:
+        {
+            struct rt_device_blk_geometry *geometry;
+
+            geometry = (struct rt_device_blk_geometry *)args;
+            if (geometry == RT_NULL)
+            {
+                rt_mutex_release(&flashdevPtr->lock);
+                return -RT_ERROR;
+            }
+            geometry->bytes_per_sector = flashdevPtr->flashinfo.bytes_per_sector;
+            geometry->sector_count = flashdevPtr->flashinfo.sector_count;
+            geometry->block_size = flashdevPtr->flashinfo.bytes_per_sector;//64k
+
+            break;
+        }
+        case RT_DEVICE_CTRL_BLK_ERASE: //params are sector index to erase start and end.
+        {
+            rt_uint32_t *addrs = (rt_uint32_t *) args, start_sector = addrs[0], end_sector = addrs[1];
+
+            rt_size_t phy_size;
+
+            if (addrs == RT_NULL || start_sector > end_sector || start_sector > flashdevPtr->flashinfo.sector_count)
+            {
+                rt_mutex_release(&flashdevPtr->lock);
+                return -RT_ERROR;
+            }
+
+            for(i = start_sector; i <= end_sector; i++)
+            {
+                ret = GD_SFLASH_EraseSector(flashdevPtr->handle, (rt_uint16_t)i);
+                if ( ret != GD_OK )
+                {
+                    rt_kprintf("\n[gk_flash_control] GD_SFLASH_EraseSector err!!\n");
+                }
+
+                rt_kprintf("\n[gk_flash_control] erase sector number = %ld\n", i);
+            }
+
+            break;
+        }
+        default:
+            break;
+    }
+
+    rt_mutex_release(&flashdevPtr->lock);
+
+    return RT_EOK;
+}
+
+
+void rt_flash_init(void)
+{
+
+    GD_SFLASH_CHANNEL_E channel = GD_SFLASH_CHANNEL_0;
+    rt_uint32_t deviceBytes = 0;
+    rt_uint16_t sectorCount = 0;
+    rt_uint32_t sectorSize = 0;
+    rt_uint16_t tmp_sectorIndex = 16;
+    rt_int32_t ret;
+
+    GD_SFLASH_Init();
+
+    rt_memset((void *)&flashdev,0,sizeof(struct gk_flash));
+
+    for(;channel<GD_SFLASH_SPI_CHANNEL_0_0; channel++)
+    {
+      ret = GD_SFLASH_Open((GD_HANDLE *)&flashdev.handle, GD_SFLASH_FREQ_DIV4, channel);
+      if(ret == GD_OK)
+          break;
+    }
+
+    if ( channel == GD_SFLASH_SPI_CHANNEL_0_0 )
+    {
+      rt_kprintf("\nrt_flash_init failed!!\n");
+      return;
+    }
+
+
+    ret = GD_SFLASH_GetSize(flashdev.handle, &deviceBytes);
+
+    deviceBytes *= sizeof(rt_uint32_t);
+
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[rt_flash_init] GD_SFLASH_GetSize err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[rt_flash_init] deviceBytes = 0x%lx\n", deviceBytes);
+    }
+
+
+    ret = GD_SFLASH_GetNumberOfSectors(flashdev.handle, &sectorCount);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[rt_flash_init] GD_SFLASH_GetNumberOfSectors err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[rt_flash_init] sectorCount = %ld\n", sectorCount);
+    }
+
+
+    ret = GD_SFLASH_GetSectorSize(flashdev.handle, tmp_sectorIndex, &sectorSize);
+    sectorSize *= sizeof(rt_uint32_t);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("\n[gk_flash_control] GD_SFLASH_GetSectorSize err!!\n");
+    }
+    else
+    {
+        //rt_kprintf("\n[gk_flash_control] sectorBytes = 0x%lx\n", sectorSize);
+    }
+
+    flashdev.flashinfo.bytes_per_sector = sectorSize;
+    flashdev.flashinfo.sector_count = sectorCount;
+    flashdev.flashinfo.block_size = sectorSize;//64k
+
+    flashdev.device.type            = RT_Device_Class_Block;
+    flashdev.device.rx_indicate     = RT_NULL;
+    flashdev.device.tx_complete     = RT_NULL;
+
+    flashdev.device.init            = gk_flash_init;
+    flashdev.device.open            = gk_flash_open;
+    flashdev.device.close           = gk_flash_close;
+    flashdev.device.read            = gk_flash_read;
+    flashdev.device.write           = gk_flash_write;
+    flashdev.device.control         = gk_flash_control;
+    flashdev.device.user_data       = (void *)&flashdev;
+
+
+    ret = rt_mutex_init(&flashdev.lock,"sflash", RT_IPC_FLAG_FIFO);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("\nrt_flash_init creat mutex failed!!\n");
+        return;
+    }
+
+    rt_device_register(&flashdev.device, "sflash",
+                               RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
+
+}
+

+ 6 - 0
bsp/gkipc/drivers/drv_flash.h

@@ -0,0 +1,6 @@
+#ifndef __FLASH__
+#define __FLASH__
+
+void rt_flash_init(void);
+
+#endif

+ 519 - 0
bsp/gkipc/drivers/drv_gmac.c

@@ -0,0 +1,519 @@
+/*
+ * File      : drv_gmac.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+/*****************************************************************************
+ *  Include Section
+ *  add all #include here
+ *****************************************************************************/
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+#include <netif/ethernetif.h>
+#include "lwipopts.h"
+#include "drv_gmac.h"
+#include "gtypes.h"
+#include "gd_ethernet.h"
+
+#ifdef RT_USING_GMAC
+/*****************************************************************************
+ * Define section
+ * add all #define here
+ *****************************************************************************/
+#define GMAC_TX_BUFFER_SIZE 2048
+#define GMAC_RX_BUFFER_SIZE 2048
+
+#define MAC_ADDR0   0x11
+#define MAC_ADDR1   0x10
+#define MAC_ADDR2   0xAA
+#define MAC_ADDR3   0xBB
+#define MAC_ADDR4   0xCC
+#define MAC_ADDR5   0x01
+
+
+/****************************************************************************
+ * ADT section
+ *  add definition of user defined Data Type that only be used in this file here
+ ***************************************************************************/
+
+#define MAX_ADDR_LEN 6
+typedef struct gk_gmac_object
+{
+    /* inherit from ethernet device */
+    struct eth_device parent;
+
+    GD_ETH_InitParamsT init_param;
+    GD_ETH_OpenParamsT params;
+    GD_HANDLE eth_handle;
+
+    int link;
+    struct rt_timer timer;
+    U8 local_mac_address[MAX_ADDR_LEN];
+
+    U8* rx_buffer;
+    U16 rx_len;
+    struct rt_semaphore rx_lock;
+#if 0
+    UINT8 local_mac_address[MAX_ADDR_LEN];
+    unsigned short phy_addr;
+    int full_duplex;  // read only
+    int speed_100m;   // read only
+
+    UINT8* rx_ring_original;
+    UINT8* tx_ring_original;
+    UINT8* rx_buffer_original;
+    UINT8* tx_buffer_original;
+
+    UINT8* rx_buffer;
+    UINT8* tx_buffer;
+
+    Gmac_Rx_DMA_Descriptors* rx_ring;
+    Gmac_Tx_DMA_Descriptors* tx_ring;
+
+    unsigned long rx_buffer_dma;
+    unsigned long tx_buffer_dma;
+    unsigned long rx_ring_dma;
+    unsigned long tx_ring_dma;
+
+    unsigned int tx_stop;
+
+    struct rt_semaphore tx_lock;
+    struct rt_semaphore rx_lock;
+    struct rt_semaphore tx_ack;
+    struct rt_semaphore rx_ack;
+    struct rt_semaphore mdio_bus_lock;
+    int speed;
+    int duplex;
+    int link;
+    int phy_interface;
+    struct rt_timer timer;
+    struct rt_timer rx_poll_timer;
+
+    gk_gmac_stats_t stats;
+
+    unsigned int rx_cur_desc;
+    unsigned int tx_cur_desc;
+    unsigned int get_frame_no;
+    struct rt_workqueue* rx_queue;
+    struct rt_work* rx_work;
+#endif
+
+} gk_gmac_object_t;
+
+static int recv_state = 0;
+static void recv_isr_callback(volatile U8* buffer, U16 len);
+
+/******************************************************************************
+ * Function prototype section
+ * add prototypes for all functions called by this file,execepting those
+ * declared in header file
+ *****************************************************************************/
+int gk_gmac_init(rt_device_t dev)
+{
+    GERR ret = GD_OK;
+    int open_retry = 3;
+    GD_ETH_MacT macaddr;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    // eth init .....
+    gmac->init_param.bHWReset = GFALSE;
+    gmac->init_param.phyreset = GD_GPIO_0;
+    gmac->init_param.phyType = 0;
+    ret = GD_ETH_Init(&(gmac->init_param));
+    if (ret != GD_OK)
+    {
+        rt_kprintf("GD_ETH_Init error", ret);
+        return -1;
+    }
+
+    gmac->eth_handle = 0;
+    // Open eth device.
+    gmac->params.addr = GD_ETH_PHY_EXTERNAL_AUTO;
+    gmac->params.workmode.speed       = GD_ETH_SPEED_100M;
+    gmac->params.workmode.duplex      = GD_ETH_FULL_DUPLEX;
+    gmac->params.workmode.loopback    = GD_ETH_LOOP_OFF;
+    gmac->params.workmode.mode        = GD_ETH_PHY_IF_MODE_RMII;
+
+    ret = GD_ETH_Open(&(gmac->params), &(gmac->eth_handle));
+    while ((ret != GD_OK) && (open_retry--)) {
+        rt_kprintf("GD_ETH_Open: device open failed(%ld)"
+                                            ", retry %ld\n", ret, open_retry);
+        rt_thread_delay(10);
+        ret = GD_ETH_Open(&(gmac->params), &(gmac->eth_handle));
+    }
+    if  (ret == GD_OK) {
+        rt_kprintf("GD_ETH_Open: device open successed 0x%x.\n", gmac->eth_handle);
+    }
+
+    ret = GD_ETH_GetMacAddress(gmac->eth_handle, &macaddr);
+    if (ret != GD_OK) {
+        rt_kprintf("GD_ETH_GetMacAddress: device getMacAddress failed, use default.\n");
+
+        macaddr[0] = MAC_ADDR0;
+        macaddr[1] = MAC_ADDR1;
+        macaddr[2] = MAC_ADDR2;
+        macaddr[3] = MAC_ADDR3;
+        macaddr[4] = MAC_ADDR4;
+        macaddr[5] = MAC_ADDR5;
+    }
+
+    rt_memcpy(gmac->local_mac_address, macaddr, MAX_ADDR_LEN);
+
+    // set data coming callback.
+    GD_ETH_SetNetReceiveFuc(recv_isr_callback);
+
+    return 0;
+}
+
+void gk_gmac_update_link(void* param)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)param;
+
+    rt_device_t dev = &gmac->parent.parent;
+    GD_ETH_StatParamsT ethstat;
+
+    GD_ETH_GetStat(gmac->eth_handle, &ethstat);
+    if (gmac->link != ethstat.linkup)
+    {
+        rt_kprintf("ipc ethif link is %s\n", (ethstat.linkup == GD_ETH_LINKUP ?"UP":"DOWN"));
+        rt_kprintf("  speed is %d\n", (int)ethstat.speed);
+        rt_kprintf("  duplex is %d\n", (int)ethstat.duplex);
+
+        if (ethstat.linkup == GD_ETH_LINKUP)
+        {
+            rt_kprintf("%s: link up\n", dev->parent.name);
+            eth_device_linkchange(&gmac->parent, RT_TRUE);
+        }
+        else
+        {
+            rt_kprintf("%s: link down\n", dev->parent.name);
+            eth_device_linkchange(&gmac->parent, RT_FALSE);
+        }
+
+        gmac->link = ethstat.linkup;
+    }
+}
+
+
+/*********************
+ *
+ * up level use interface
+ *
+ *********************/
+static rt_err_t rt_gk_gmac_init(rt_device_t dev)
+{
+    int ret;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_timer_init(&gmac->timer, "link_timer", gk_gmac_update_link, (void*)gmac,
+                  RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC);
+
+    rt_timer_start(&gmac->timer);
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_gk_gmac_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rt_gk_gmac_close(rt_device_t dev)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    GD_ETH_Close(&(gmac->eth_handle));
+
+    return RT_EOK;
+}
+static rt_size_t rt_gk_gmac_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_gk_gmac_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_gk_gmac_control(rt_device_t dev, int cmd, void* args)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    switch (cmd)
+    {
+    case NIOCTL_GADDR:
+        /* get mac address */
+        if (args)
+            rt_memcpy(args, gmac->local_mac_address, MAX_ADDR_LEN);
+        else
+            return -RT_ERROR;
+
+        break;
+
+    default:
+        break;
+    }
+
+    return RT_EOK;
+}
+
+/* ethernet device interface */
+/* transmit packet. */
+static rt_uint8_t g_output_buf[PBUF_POOL_BUFSIZE+20];
+static rt_err_t rt_gk_gmac_tx(rt_device_t dev, struct pbuf* p)
+{
+    rt_err_t ret = RT_EOK;
+    struct pbuf *q = NULL;
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (p == NULL)
+    {
+        rt_kprintf("rt_gk_gmac_tx: out_pbuf is NULL\n");
+        ret = ERR_MEM;
+        return ret;
+    }
+    if (gmac->eth_handle == 0)
+    {
+        rt_kprintf("rt_gk_gmac_tx: eth_handle is 0\n");
+        ret = ERR_MEM;
+        return ret;
+    }
+
+    rt_uint8_t *output_bufptr = p->payload;
+
+    if (p->len != p->tot_len)
+    {
+        rt_uint8_t *bufptr = g_output_buf;
+        for (q = p; q != NULL; q = q->next)
+        {
+            rt_memcpy(bufptr, q->payload, q->len);
+            bufptr += q->len;
+        }
+        output_bufptr = g_output_buf;
+    }/* (else)  write to ethernet, reduce memcpy */
+
+
+    ret = GD_ETH_Write(gmac->eth_handle, (char *) output_bufptr, p->tot_len, GD_ETH_FRAME_END);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("rt_gk_gmac_tx: eth Write error, len = %d, ret = %lu\n", p->tot_len, ret);
+        ret = RT_EIO;
+    }
+    else
+    {
+        ret = RT_EOK;
+    }
+
+    return ret;
+}
+
+static struct pbuf * _convert_data_to_pbuf(U8 *buffer, U32 len)
+{
+    struct pbuf *p, *q;
+    U8 *bufptr;
+    U32 buflen;
+
+    if (len <= 0) {
+        rt_kprintf("_convert_data_to_pbuf: len(%d) <= 0\n", len);
+        return NULL;
+    }
+    buflen = len;
+    p = pbuf_alloc(PBUF_RAW, buflen, PBUF_POOL);
+    if (p != NULL) {
+
+        bufptr = (U8 *) buffer;
+        for (q = p; q != NULL; q = q->next) {
+            SMEMCPY(q->payload, bufptr, q->len);
+            bufptr += q->len;
+        }
+
+    } else {
+        rt_kprintf("_convert_data_to_pbuf: can't alloc pbuf(len=%lu)\n", buflen);
+        return NULL;
+    }
+
+    return p;
+}
+
+/* reception packet. */
+static struct pbuf* rt_gk_gmac_rx(rt_device_t dev)
+{
+    gk_gmac_object_t* gmac;
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (!recv_state)
+    {
+        return RT_NULL;
+    }
+
+    struct pbuf* temp_pbuf = RT_NULL;
+
+    if (gmac->rx_len <= 0)
+    {
+        rt_kprintf("rt_gk_gmac_rx: len(%d) <= 0\n", gmac->rx_len);
+        return RT_NULL;
+    }
+
+    rt_sem_take(&gmac->rx_lock, RT_WAITING_FOREVER);
+
+    //rt_kprintf("rt_gk_gmac_rx buffer = 0x%x, len = %d\n", gmac->rx_buffer, gmac->rx_len);
+
+    //temp_pbuf = pbuf_alloc(PBUF_LINK, gmac->rx_len, PBUF_RAM);
+    temp_pbuf = _convert_data_to_pbuf(gmac->rx_buffer, gmac->rx_len);
+    if (!temp_pbuf)
+    {
+        rt_kprintf("alloc pbuf failed\n");
+        rt_sem_release(&gmac->rx_lock);
+        return RT_NULL;
+    }
+
+    //rt_memcpy(temp_pbuf->payload, gmac->rx_buffer, gmac->rx_len);
+
+    recv_state = 0;
+
+    rt_sem_release(&gmac->rx_lock);
+
+    return temp_pbuf;
+}
+
+static void recv_isr_callback(volatile U8* buffer, U16 len)
+{
+    gk_gmac_object_t* gmac;
+    int ret_eth;
+
+    recv_state = 1;
+
+    rt_device_t dev = rt_device_find("e0");
+    if (dev == RT_NULL)
+    {
+        rt_kprintf("rt_device_find e0 == NULL\n");
+        return;
+    }
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    if (buffer == NULL) {
+        rt_kprintf("recv_isr_callback: error buffer == NULL\n");
+        return;
+    }
+
+    if ((len <= 0) || (len > GMAC_RX_BUFFER_SIZE)) {
+        rt_kprintf("recv_isr_callback: error len = %d(1~%d)\n", len, GMAC_RX_BUFFER_SIZE);
+        return;
+    }
+
+    gmac->rx_buffer = (U8*)buffer;
+    gmac->rx_len = len;
+    //rt_kprintf("recv_isr_callback = 0x%x, len = %d\n", gmac->rx_buffer, gmac->rx_len);
+
+    ret_eth = eth_device_ready(&(gmac->parent));
+    if (ret_eth != RT_EOK)
+    {
+        rt_kprintf("eth_device_ready error %d\n",ret_eth);
+    }
+}
+
+int rt_app_gk_gmac_init(void)
+{
+    gk_gmac_object_t* gmac;
+
+    GD_ETH_MacT macaddr;
+    gmac = (gk_gmac_object_t*)rt_malloc(sizeof(*gmac));
+    if (gmac == NULL)
+    {
+        rt_kprintf("gk_eth_initialize: Cannot allocate Gmac_Object %d\n", 1);
+        return (-1);
+    }
+
+    memset(gmac, 0, sizeof(gk_gmac_object_t));
+
+    rt_sem_init(&gmac->rx_lock, "rx_lock", 1, RT_IPC_FLAG_FIFO);
+
+    gmac->parent.parent.init      = rt_gk_gmac_init;
+    gmac->parent.parent.open      = rt_gk_gmac_open;
+    gmac->parent.parent.close     = rt_gk_gmac_close;
+    gmac->parent.parent.read      = rt_gk_gmac_read;
+    gmac->parent.parent.write     = rt_gk_gmac_write;
+    gmac->parent.parent.control   = rt_gk_gmac_control;
+    gmac->parent.parent.user_data = (void*)gmac;
+
+    gmac->parent.eth_rx = rt_gk_gmac_rx;
+    gmac->parent.eth_tx = rt_gk_gmac_tx;
+
+    gk_gmac_init(&gmac->parent.parent);
+
+    eth_device_init(&(gmac->parent), "e0");
+
+    return 0;
+}
+
+#ifdef RT_USING_FINSH
+#include "finsh.h"
+
+void dump_rx_desc(void)
+{
+    int i;
+    gk_gmac_object_t* gmac;
+    rt_device_t dev = rt_device_find("e0");
+
+    if (dev == RT_NULL) return;
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_kprintf("soft current desc is:%d\n", gmac->link);
+}
+
+void dump_tx_desc(void)
+{
+    int i;
+    gk_gmac_object_t* gmac;
+    rt_device_t dev = rt_device_find("e0");
+
+    if (dev == RT_NULL) return;
+
+    gmac = (gk_gmac_object_t*)dev->user_data;
+
+    rt_kprintf("soft current desc is:%d\n", gmac->link);
+}
+
+
+FINSH_FUNCTION_EXPORT(dump_rx_desc, dump e0 rx desc);
+FINSH_FUNCTION_EXPORT(dump_tx_desc, dump e0 tx desc);
+
+#endif
+
+#endif

+ 35 - 0
bsp/gkipc/drivers/drv_gmac.h

@@ -0,0 +1,35 @@
+/*
+ * File      : drv_gmac.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef GMAC_H_
+#define GMAC_H_
+
+#ifdef RT_USING_GMAC
+int rt_app_gk_gmac_init(void);
+#endif
+
+#endif /* GMAC_H_ */

+ 304 - 0
bsp/gkipc/drivers/drv_i2c.c

@@ -0,0 +1,304 @@
+/*
+ * File      : drv_i2c.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2016 Shanghai goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Fullhan.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include <rtdevice.h>
+#include <rthw.h>
+#include "drv_i2c.h"
+
+#include "gtypes.h"
+
+#include "platform.h"
+
+#include "gd_i2c.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+//#define GK_I2C_DEBUG
+#ifndef GK_I2C_DEBUG
+#define I2C_PRINT_DBG(fmt, args...)
+#define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#else
+#define I2C_PRINT_DBG(fmt, args...) rt_kprintf(fmt, ##args);
+#define I2C_PRINT_ERR(fmt, args...) rt_kprintf(fmt, ##args);
+#endif
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+
+static int gk_i2c_init(struct gk_i2c_obj *i2c_obj)
+{
+    int ret = RT_EOK;
+
+    ret = GD_I2C_Init((GD_I2C_INIT_PARAMS_S*)&i2c_obj->config.i2cInitParams);
+
+    return ret;
+}
+
+static rt_size_t gk_i2c_xfer(struct rt_i2c_bus_device *dev,
+                             struct rt_i2c_msg msgs[], rt_uint32_t num)
+{
+    int ret;
+    U8 address    = 0;
+    U8* buffer    = NULL;
+    U8* regbuffer = NULL;
+    U32 regbytes  = 0;
+    U32 bytes     = 0;
+
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)dev->priv;
+
+    if (num < 2)
+    {
+        if (msgs[0].flags == RT_I2C_WR)
+        {
+            address = msgs[0].addr;
+            buffer  = msgs[0].buf;
+            bytes   = msgs[0].len;
+            ret = GD_I2C_Write( (GD_HANDLE *)&i2c_obj->handle,address,buffer,bytes );
+            if (ret != RT_EOK)
+            {
+                I2C_PRINT_ERR("[%s:%d]I2C Write error!\n",__func__,__LINE__);
+                return RT_ERROR;
+            }
+
+        }
+    }
+    else
+    {
+        if ((msgs[0].flags == RT_I2C_WR) && (msgs[1].flags == RT_I2C_RD))
+        {
+            address    = msgs[0].addr;
+            regbuffer  = msgs[0].buf;
+            regbytes   = msgs[0].len;
+
+            buffer     = msgs[1].buf;
+            bytes      = msgs[1].len;
+        }
+        else if ((msgs[0].flags == RT_I2C_RD ) && (msgs[1].flags == RT_I2C_WR))
+        {
+            address    = msgs[1].addr;
+            regbuffer  = msgs[1].buf;
+            regbytes   = msgs[1].len;
+
+            buffer     = msgs[0].buf;
+            bytes      = msgs[0].len;
+        }
+        ret = GD_I2C_Read( (GD_HANDLE *)&i2c_obj->handle,(U8)address, (U8*)regbuffer,(U32)regbytes,(U8*) buffer, (U32)bytes );
+        if (ret != RT_EOK)
+        {
+            I2C_PRINT_ERR("[%s:%d]I2C_Read error!\n",__func__,__LINE__);
+            return RT_ERROR;
+        }
+
+    }
+
+    return ret;
+}
+
+
+static const struct rt_i2c_bus_device_ops gk_i2c_ops = {
+    .master_xfer = gk_i2c_xfer,
+};
+
+int gk_i2c_probe(void *priv_data)
+{
+    int ret;
+    struct rt_i2c_bus_device *i2c_bus_dev;
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
+    char i2c_dev_name[5]       = {0};
+
+    i2c_bus_dev = (struct rt_i2c_bus_device *)rt_malloc(sizeof(struct rt_i2c_bus_device));
+    rt_memset(i2c_bus_dev, 0, sizeof(struct rt_i2c_bus_device));
+    i2c_bus_dev->ops = &gk_i2c_ops;
+
+    rt_sprintf(i2c_dev_name, "%s%d", "i2c", i2c_obj->id);
+    ret = rt_i2c_bus_device_register(i2c_bus_dev, i2c_dev_name);
+    if (ret != RT_EOK)
+    {
+        I2C_PRINT_ERR("ERROR:rt_spi_bus_register failed, ret=%d\n", ret);
+        return -RT_ENOMEM;
+    }
+
+    // priv struct init
+    i2c_obj->lock = rt_mutex_create("i2c_mux", RT_IPC_FLAG_FIFO);
+
+    gk_i2c_init(i2c_obj);
+
+    return ret;
+}
+
+
+int gk_i2c_exit(void *priv_data)
+{
+    struct gk_i2c_obj *i2c_obj = (struct gk_i2c_obj *)priv_data;
+
+    GD_I2C_Close((GD_HANDLE *)&i2c_obj->handle);
+    GD_I2C_Exit();
+    return 0;
+}
+
+struct gk_platform_driver i2c_driver_ops = {
+    .name = "i2c", .probe = gk_i2c_probe, .remove = gk_i2c_exit,
+};
+
+void rt_hw_i2c_init(void)
+{
+    I2C_PRINT_DBG("%s start\n", __func__);
+    gk_platform_driver_init(&i2c_driver_ops);
+    I2C_PRINT_DBG("%s end\n", __func__);
+    // fixme: never release?
+}
+
+
+//#define GK_TEST_I2C
+#ifdef GK_TEST_I2C
+static rt_err_t gk_i2c_test_read_reg(struct rt_i2c_bus_device *gk_i2c,
+                                rt_uint16_t reg, rt_uint8_t *data)
+{
+    struct rt_i2c_msg msg[2];
+    rt_uint8_t send_buf[2];
+    rt_uint8_t recv_buf[1] = {0};
+
+    I2C_PRINT_DBG("%s start\n", __func__);
+
+    send_buf[0] = (reg & 0xFF);
+
+    msg[0].addr  = 0x51;
+    msg[0].flags = RT_I2C_WR;
+    msg[0].len   = 1;
+    msg[0].buf   = send_buf;
+
+    msg[1].addr  = 0x51;
+    msg[1].flags = RT_I2C_RD;
+    msg[1].len   = 1;
+    msg[1].buf   = recv_buf;
+
+    rt_i2c_transfer(gk_i2c, msg, 2);
+    *data = recv_buf[0];
+    return RT_EOK;
+}
+static rt_err_t gk_i2c_test_write_reg(struct rt_i2c_bus_device *gk_i2c,
+                                 rt_uint16_t reg, rt_uint8_t data)
+{
+    struct rt_i2c_msg msg;
+    rt_uint8_t send_buf[3];
+
+    I2C_PRINT_DBG("%s start\n", __func__);
+
+    // send_buf[0] = ((reg >> 8) & 0xff);
+    send_buf[1] = (reg & 0xFF);
+    send_buf[2] = data;
+
+    msg.addr  = 0x51;
+    msg.flags = RT_I2C_WR;
+    msg.len   = 2;
+    msg.buf   = send_buf;
+
+    rt_i2c_transfer(gk_i2c, &msg, 1);
+    I2C_PRINT_DBG("%s end\n", __func__);
+    return RT_EOK;
+}
+
+void i2c_test_sensor()
+{
+    struct rt_i2c_bus_device *gk_i2c;
+    gk_i2c_obj_s i2c_obj;
+
+    rt_uint8_t data[1] = {0x00};
+    int ret = 0;
+    gk_i2c = rt_i2c_bus_device_find("i2c1");
+
+    GD_I2C_OPEN_PARAMS_S i2c_param;
+    i2c_param.channel = GADI_I2C_CHANNEL_ONE;
+    i2c_param.speed   = GADI_I2C_100KBPS;
+    i2c_param.mode    = GADI_I2C_INTERRUPT;//GADI_I2C_NORMAL;
+
+    i2c_obj.handle = 0;
+    ret = GD_I2C_Open((GD_I2C_OPEN_PARAMS_S*)&i2c_param, &i2c_obj.handle);
+    if (ret != 0)
+    {
+        I2C_PRINT_DBG("GD_I2C_Open error!\n");
+        return -1;
+    }
+    gk_i2c.priv = &i2c_obj;
+
+    gk_i2c_test_write_reg(gk_i2c, 0x04, 0x02);
+
+    gk_i2c_test_read_reg(gk_i2c, 0x02, data);
+
+    I2C_PRINT_DBG("data read from 0x3038 is 0x%x\r\n", data[0]);
+    I2C_PRINT_DBG("%s end\n", __func__);
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(i2c_test_sensor, sensor i2c test);
+#endif
+
+
+#endif /*GK_TEST_I2C end*/
+

+ 144 - 0
bsp/gkipc/drivers/drv_i2c.h

@@ -0,0 +1,144 @@
+/*
+ * File      : drv_i2c.h
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 ChengDu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+#include <rtthread.h>
+
+
+/*!
+*******************************************************************************
+** \brief I2C channel number.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_CHANNEL_ONE = 0, /*!< I2C channel 1.*/
+    RT_I2C_CHANNEL_TWO,     /*!< I2C channel 2.*/
+}RT_I2C_ChannelT;
+
+
+/*!
+*******************************************************************************
+** \brief I2C operition modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_GENERIC_MASTER_MODE, /*!< Generic master mode.*/
+    RT_I2C_GENERIC_SLAVER_MODE, /*!< Generic slave mode.*/
+    RT_I2C_AUTO_MASTER_MODE,    /*!< Auto master mode.*/
+    RT_I2C_AUTO_SLAVER_MODE,    /*!< Auto slave mode.*/
+    RT_I2C_DMA_MASTER_MODE,     /*!< DMA master mode.*/
+    RT_I2C_DMA_SLAVER_MODE,     /*!< DMA slave mode.*/
+}RT_I2C_OpenModeT;
+
+
+/*!
+*******************************************************************************
+** \brief Protocol modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_COMMON_PROTOCOL = 0,  /*!< Common protocol.*/
+    RT_I2C_RESTART_PROTOCOL,     /*!< Protocol with restart.*/
+}RT_I2C_ProtocolT;
+
+
+/*!
+*******************************************************************************
+** \brief I2C datarate speed modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_100KBPS = 100000, /*!< 100kHz datarate.*/
+    RT_I2C_400KBPS = 400000,     /*!< 400kHz datarate.*/
+}RT_I2C_SpeedT;
+
+/*!
+*******************************************************************************
+** \brief I2C transmit modes.
+*******************************************************************************
+*/
+typedef enum
+{
+    RT_I2C_NORMAL = 0,
+    RT_I2C_TURBO_MODE,  // write operation only.
+    RT_I2C_INTERRUPT,
+}RT_I2C_ModeT;
+
+/*!
+*******************************************************************************
+** \brief Init parameters.
+*******************************************************************************
+*/
+typedef struct
+{
+    RT_I2C_OpenModeT       mode;          /*!< Operation mode.*/
+    rt_int8_t              priority;      /*!< IRQ priority */
+    rt_int8_t              gpioSdaPinCh1; /*!< GPIO SDA pin assigmnet channel 1.*/
+    rt_int8_t              gpioSclPinCh1; /*!< GPIO SCL pin assigmnet channel 1.*/
+    rt_int8_t              gpioSdaPinCh2; /*!< For future use.*/
+    rt_int8_t              gpioSclPinCh2; /*!< For future use.*/
+}RT_I2C_InitParamsT;
+
+
+/*!
+*******************************************************************************
+** \brief Open parameters.
+*******************************************************************************
+*/
+typedef struct
+{
+    RT_I2C_ChannelT    channel;   /*!< i2c channel index*/
+    RT_I2C_SpeedT      speed;     /*!< i2c speed*/
+    RT_I2C_ModeT       mode;      /*!< i2c mode*/
+}RT_I2C_OpenParamsT;
+
+typedef struct gk_i2c_config
+{
+    RT_I2C_InitParamsT  i2cInitParams;
+}gk_i2c_config_s;
+
+
+
+typedef struct gk_i2c_obj
+{
+    rt_uint32_t id;
+    rt_uint32_t handle;
+    rt_mutex_t lock;
+    gk_i2c_config_s config;
+}gk_i2c_obj_s;
+
+
+void rt_hw_i2c_init(void);
+
+
+#endif/*_I2C_H_*/

+ 342 - 0
bsp/gkipc/drivers/drv_mmc.c

@@ -0,0 +1,342 @@
+/*
+ * File      : drv_mmc.c
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 chengdu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "platform.h"
+#include <rtdef.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+#include <dfs_fs.h>
+
+#include "gd_sdio.h"
+#include "drv_mmc.h"
+
+
+//#define GK_MMC_DEBUG
+
+#if defined(GK_MMC_DEBUG) && defined(RT_DEBUG)
+#define PRINT_MMC_DBG(fmt, args...)                           \
+    do                                                        \
+    {                                                         \
+        rt_kprintf("FH_MMC_DEBUG: tick-%d, ", rt_tick_get()); \
+        rt_kprintf(fmt, ##args);                              \
+    } while (0)
+#else
+#define PRINT_MMC_DBG(fmt, args...) \
+    do                              \
+    {                               \
+    } while (0)
+#endif
+
+
+#define RT_SDIO_MAX_BLOCK_LEN       512    /*block size*/
+
+
+/*GLOBAL SD DEVICE PONITER*/
+static gk_mmc_driver_s sd_driver;
+fs_sdio_notify_func_t notifyFunc = NULL;
+
+
+static rt_err_t rt_sdcard_init(rt_device_t dev)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+    if (mmc_drv->handle.inUse == 0)
+    {
+        mmc_drv->openParams.isUseDmaWay      = 0;
+        retVal = GD_SDIO_Open((GD_SDIO_OpenParamsT *)&mmc_drv->openParams,(sdioHandleT *)&mmc_drv->handle,index);
+        if (retVal != RT_EOK)    {
+            rt_kprintf("[%s:%d]GD_SDIO_Open failed!\n",__func__,__LINE__);
+            return-RT_ENOMEM;
+        }
+    }
+    else
+    {
+        PRINT_MMC_DBG("----ALREADY_OPEN SDIO_%d----\n",index);
+    }
+
+	return RT_EOK;
+}
+
+static rt_err_t rt_sdcard_close(rt_device_t dev)
+{
+    gk_mmc_driver_s *mmc_drv = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index        = mmc_drv->handle.index;
+    rt_uint32_t retVal       = RT_EOK;
+
+
+    retVal = GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d] failed!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        return-RT_ENOMEM;
+    }
+
+
+    rt_device_unregister(mmc_drv->deviceP[index]);
+
+    if (mmc_drv->deviceP[index] != NULL){
+        rt_free(mmc_drv->deviceP[index]);
+        mmc_drv->deviceP[index] = NULL;
+    }
+
+    if (mmc_drv->partP[index] != NULL)
+    {
+        rt_free(mmc_drv->partP[index]);
+        mmc_drv->partP[index] = NULL;
+    }
+
+	return RT_EOK;
+}
+
+static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+    rt_sem_take(part->lock, RT_WAITING_FOREVER);
+    retVal = GD_SDIO_ReadSector((sdioHandleT *)&mmc_drv->handle, pos, buffer, size);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]error!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        rt_sem_release(part->lock);
+        return -RT_ENOMEM;
+    }
+    rt_sem_release(part->lock);
+
+    return size;
+
+}
+
+static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+    rt_sem_take(part->lock, RT_WAITING_FOREVER);
+    retVal = GD_SDIO_WriteSector((sdioHandleT *)&mmc_drv->handle,pos,(void*)buffer,size);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]GD_SDIO_WriteSector failed!\n",__FILE__,__func__,__LINE__);
+        rt_sem_release(part->lock);
+        return -RT_ENOMEM;
+    }
+    rt_sem_release(part->lock);
+
+    return size;
+}
+
+static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
+{
+    gk_mmc_driver_s *mmc_drv   = (gk_mmc_driver_s *)dev->user_data;
+    rt_uint32_t index          = mmc_drv->handle.index;
+    struct dfs_partition *part = (struct dfs_partition *)mmc_drv->partP[index];
+    rt_uint32_t retVal         = RT_EOK;
+
+
+    switch(cmd)
+    {
+        case RT_DEVICE_CTRL_BLK_GETGEOME:
+        {
+            struct rt_device_blk_geometry *geometry;
+            GD_SDIO_VolumeInfoT sdInfo;
+            rt_memset(&sdInfo,0,sizeof(sdInfo));
+            geometry = (struct rt_device_blk_geometry *)args;
+            retVal = GD_SDIO_GetCardInfo((sdioHandleT *)&mmc_drv->handle,&sdInfo,index);
+            if (retVal != RT_EOK)
+            {
+                rt_kprintf("[%s:%d]GD_SDIO_GetCardInfo failed!\n",__func__,__LINE__);
+                return-RT_ENOMEM;
+            }
+
+            geometry->block_size       = sdInfo.sectorSize;
+            geometry->sector_count     = sdInfo.sectorCount;
+            geometry->bytes_per_sector = sdInfo.sectorSize;
+            PRINT_MMC_DBG("[%s:%d]sd card block_size:%d,sector_count:%d!\n",__func__,__LINE__,
+                                                        geometry->block_size,geometry->sector_count);
+
+            break;
+        }
+
+        case RT_DEVICE_CTRL_BLK_ERASE:
+        {
+            unsigned int eraseAdress = 0x00;
+            unsigned short blkcnt = *(unsigned short *)args;
+            retVal = GD_SDIO_EraseSector((sdioHandleT *)&mmc_drv->handle,eraseAdress,blkcnt);
+            if (retVal != RT_EOK)
+            {
+                rt_kprintf("[%s-%s:%d]GD_SDIO_EraseSector failed!\n",__FILE__,__func__,__LINE__);
+                return-RT_ENOMEM;
+            }
+
+            break;
+        }
+
+        default:break;
+    }
+
+
+	return RT_EOK;
+}
+
+
+int rt_hw_mmc_init(gk_mmc_driver_s *pMmcParams)
+{
+    gk_mmc_driver_s *mmc_drv   = &sd_driver;
+    rt_uint32_t index          = pMmcParams->handle.index;
+    rt_uint32_t retVal         = RT_EOK;
+    rt_uint8_t *sector         = NULL;
+    rt_uint8_t sname[8]        = {0};
+    rt_uint8_t sdDeviceName[4] = {0};
+
+    if (pMmcParams == NULL)
+    {
+        rt_kprintf("[%s:%d] sdio init params is error!\n",__func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    mmc_drv->openParams.isUseDmaWay      = pMmcParams->openParams.isUseDmaWay;
+    mmc_drv->openParams.notifyFunc       = pMmcParams->openParams.notifyFunc;
+    mmc_drv->openParams.notifyFuncOptPtr = pMmcParams->openParams.notifyFuncOptPtr;
+    retVal = GD_SDIO_Open((GD_SDIO_OpenParamsT *)&mmc_drv->openParams,(sdioHandleT *)&mmc_drv->handle,index);
+    if (retVal != RT_EOK)    {
+        rt_kprintf("[%s:%d]GD_SDIO_Open failed!\n",__func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    /* get the first sector to read partition table */
+    sector = (rt_uint8_t*) rt_malloc (RT_SDIO_MAX_BLOCK_LEN);
+    if (sector == RT_NULL)
+    {
+        rt_kprintf("allocate partition sector buffer failed\n");
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        return -RT_ENOMEM;
+    }
+
+    /*alloc device buffer*/
+    mmc_drv->deviceP[index] = (struct rt_device*)rt_malloc(sizeof(struct rt_device));
+    if(mmc_drv->deviceP[index] == RT_NULL)
+    {
+         rt_kprintf("[%s:%d]allocate device failed\n",__func__,__LINE__);
+         GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+         return -RT_ENOMEM;
+    }
+
+    mmc_drv->partP[index] = (struct dfs_partition*)rt_malloc(sizeof(struct dfs_partition));
+    if(mmc_drv->partP[index] == RT_NULL)
+    {
+         rt_kprintf("[%s:%d]allocate partP failed\n",__func__,__LINE__);
+         GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+         return -RT_ENOMEM;
+    }
+
+    retVal = GD_SDIO_ReadSector((sdioHandleT *)&mmc_drv->handle, 0, sector, 1);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d]GD_SDIO_ReadSector failed!\n",__FILE__,__func__,__LINE__);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+
+    /* get the first partition */
+    retVal = dfs_filesystem_get_partition(mmc_drv->partP[index], sector, 0);
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s-%s:%d] failed!,retVal = %d\n",__FILE__,__func__,__LINE__,retVal);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+    rt_snprintf(sname, 8, "sem_sd%d", index);
+    mmc_drv->partP[index]->lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
+
+    /* sdcard hardware init */
+    rt_memset(mmc_drv->deviceP[index],0,sizeof(struct rt_device));
+    mmc_drv->deviceP[index]->type       = RT_Device_Class_Block;
+    mmc_drv->deviceP[index]->init       = rt_sdcard_init;
+    mmc_drv->deviceP[index]->open       = rt_sdcard_open;
+    mmc_drv->deviceP[index]->close      = rt_sdcard_close;
+    mmc_drv->deviceP[index]->read       = rt_sdcard_read;
+    mmc_drv->deviceP[index]->write      = rt_sdcard_write;
+    mmc_drv->deviceP[index]->control    = rt_sdcard_control;
+    mmc_drv->deviceP[index]->user_data  = (void *)mmc_drv;
+
+
+    rt_snprintf(sdDeviceName, 4, "sd%d",index);
+    retVal = rt_device_register(mmc_drv->deviceP[index], sdDeviceName,
+        RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
+
+    if (retVal != RT_EOK)
+    {
+        rt_kprintf("[%s:%d]rt_device_register name :%s failed!\n",__func__,__LINE__,sdDeviceName);
+        GD_SDIO_Close((sdioHandleT *)&mmc_drv->handle,index);
+        goto err;
+    }
+
+    /* release sector buffer */
+    if (sector != NULL){
+        rt_free(sector);
+        sector = NULL;
+    }
+
+    return RT_EOK;
+
+err:
+    if (mmc_drv->deviceP[index] != NULL){
+        rt_free(mmc_drv->deviceP[index]);
+        mmc_drv->deviceP[index] = NULL;
+    }
+
+    if (mmc_drv->partP[index] != NULL)
+    {
+        rt_free(mmc_drv->partP[index]);
+        mmc_drv->partP[index] = NULL;
+    }
+
+    if (sector != NULL){
+        rt_free(sector);
+        sector = NULL;
+    }
+
+    return -RT_ETIMEOUT;
+
+}
+

+ 186 - 0
bsp/gkipc/drivers/drv_mmc.h

@@ -0,0 +1,186 @@
+/*
+ * File      : drv_mmc.h
+ * This file is part of gkipc BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 chengdu goke Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef MMC_H_
+#define MMC_H_
+
+#include "rtdevice.h"
+
+#define MMC_FEQ_MIN 100000
+#define MMC_FEQ_MAX 50000000
+#define MMC_DMA_DESC_BUFF_SIZE (0x1f00)
+#define MMC_HANDLE_COUNT 2
+
+
+#define CARD_UNPLUGED 1
+#define CARD_PLUGED 0
+
+typedef enum {
+    RT_GAPI_SDIO_VERSION = (rt_int32_t)0x00010000 //!< The current driver version
+} RT_SDIO_VersionEnumT;
+
+
+ typedef enum {
+    RT_GAPI_SDIO_TRANSFER_TYPE_NORMAL = 0,     //!< Normal transfer type for SD/SDHC/MMC cards (default)
+    RT_GAPI_SDIO_TRANSFER_TYPE_DIRECT,         //!< Direct transfer mode special for SDIO cards
+    RT_GAPI_SDIO_TRANSFER_TYPE_SECURE,         //!< Spezial secure transfer mode for SD-Cards
+    RT_GAPI_SDIO_TRANSFER_TYPE_WIFI
+} RT_SDIO_TransferTypeEnumT;
+
+ typedef enum rt_card_type
+ {
+     RT_CARDTYPE_NONE = 0,
+     RT_CARDTYPE_MMC,
+     RT_CARDTYPE_SD10,
+     RT_CARDTYPE_SD20,
+     RT_CARDTYPE_SDHC
+ }RT_SDIO_Card_Type;
+
+ /*!
+****************************************************************************
+**
+** \brief SDIO callback function signature
+**
+** This is the callback function signature required by the SDIO driver
+** for internally notification functions.
+**
+** \param comState  Comunication status.
+** \param optArgPtr Optional arg pointer.
+**
+****************************************************************************
+*/
+typedef void (*RT_SDIO_NotifyFuncT)(rt_uint32_t index, rt_uint32_t comState, void* optArgPtr);
+
+typedef void (*RT_SDIO_IRQFuncT)();
+typedef void (*RT_SDIO_RESETFuncT)(rt_uint32_t index);
+
+
+
+
+typedef struct {
+    /*!
+       The version of the driver.
+       \ref GAPI_SDIO_VersionEnumT "GAPI_SDIO_VERSION".
+    */
+    RT_SDIO_VersionEnumT      version;
+	RT_SDIO_TransferTypeEnumT type;
+    /*!
+    ** The handle specific notification function.
+    */
+    RT_SDIO_NotifyFuncT  notifyFunc;
+
+	RT_SDIO_IRQFuncT	 irqFunc;
+
+	RT_SDIO_RESETFuncT   resetFunc;
+    /*!
+    ** Optional data pointer for the notification function.
+    */
+    void*                notifyFuncOptPtr;
+    /*!
+       Flag to request DMA for read/write transfer operation.
+    */
+    rt_uint32_t          isUseDmaWay;
+}RT_SDIO_OpenParamsT;
+
+
+/*cid info */
+typedef struct
+{
+    rt_uint8_t    MID;        /*Manufacturer ID            width:8[127:120]*/
+    rt_uint16_t   OID;        /*OEM/Application ID       width:16[119:104]*/
+    rt_uint8_t    PNM[5];     /*Product name               width:40[103:64]*/
+    rt_uint8_t    PRV;        /*Product revision            width:8[63:56]*/
+    rt_uint32_t   PSN;        /*Product serial number    width:32[55:24]*/
+    rt_uint16_t   MDT;        /*Manufacturing date        width:12[19:8]*/
+}rtSdioCidInfo;
+
+/*I just care about usefull info of CSD*/
+typedef struct
+{
+    rt_uint8_t    csdStructure;        /*csd revision*/
+    rt_uint32_t   classes;            /*Describes the card command classes  CCC*/
+    rt_uint32_t   tranSpeed;           /*transfer speed*/
+    rt_uint8_t    eraseBlkEn;          /*erase block enable*/
+    rt_uint8_t    permWriteProtect;    /*write protect*/
+    rt_uint8_t    tmpWriteProtect;     /*write protect*/
+}rtSdiocsdInfo;
+
+/*I just case ablot usefull info of SCR*/
+typedef struct
+{
+    rt_uint32_t    scrStructure;        // SCR Register Structure Version
+    rt_uint32_t    sdSpec;              // Describes the Physical Layer Specification Version supported by the card.
+    rt_uint32_t    stateaftererase;     // Defines the data status after erase, whether it is 0 or 1.
+    rt_uint32_t    sdSecurity;          // Describes the Security Specification Version supported by the card.
+    rt_uint32_t    sdBusWith;           // Describes all the DAT bus widths that are supported by this card.
+}rtSdioScrInfo;
+
+typedef struct
+{
+    rt_uint32_t    index;                /*index of handle array*/
+    rt_uint32_t    ocr;                  /*card volage info*/
+    rt_uint32_t    csd[4];               /*csd info (invert)*/
+    rt_uint32_t    read_bl_len;
+    rt_uint32_t    write_bl_len;
+    unsigned long long    capacity_user;
+    rt_uint32_t    sectorcount;
+    rt_uint32_t    inhighspeed;
+    rt_uint32_t    maxTransferBlk;
+    rt_uint32_t    eraseGrpSize;
+    rtSdioScrInfo  scr;
+    rtSdiocsdInfo  csdInfo;
+    rt_uint32_t    tran_speed;            /*max transfer speed*/
+    rt_uint32_t    rca;                   /*card address*/
+    rt_uint32_t    cid[4];                /*card  cid info*/
+    enum rt_card_type    type;       /*card type*/
+    rt_uint32_t      highCapacity;          /*is high capacity*/
+    rtSdioCidInfo    cidInfo;
+}rtSdioBlockT;
+
+/* SDIO specific handle */
+typedef struct
+ {
+     rt_uint32_t           inUse;        /* specifies if handle is in use */
+     rt_uint32_t           index;        /*index of handle array*/
+     RT_SDIO_OpenParamsT   openParams;   /* open params of the handle */
+     rtSdioBlockT          devicePtr;    /* pointer to hardware device */
+ } rtSdioHandleT;
+
+typedef struct gk_mmc_driver
+{
+    rtSdioHandleT        handle;
+    RT_SDIO_OpenParamsT  openParams;
+    struct rt_device     *deviceP[MMC_HANDLE_COUNT];
+    struct dfs_partition *partP[MMC_HANDLE_COUNT];
+}gk_mmc_driver_s;
+
+
+typedef void (*fs_sdio_notify_func_t)(rt_uint32_t index, rt_uint32_t comState, void* optArgPtr);
+
+int rt_hw_mmc_init(gk_mmc_driver_s *pMmcParams);
+
+#endif /* MMC_H_ */

+ 512 - 0
bsp/gkipc/drivers/drv_pwm.c

@@ -0,0 +1,512 @@
+/*
+ * File      : drv_pwm.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+#include <rtdevice.h>
+//#include "gpio.h"
+
+#include "drv_pwm.h"
+
+#include <rtdef.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/watchdog.h>
+
+#include "gtypes.h"
+#include "gd_pwm.h"
+#include "platform.h"
+
+#define GK_TEST_PWM
+static struct gk_pwm_obj *pwm_drv = NULL;
+static struct pwm_driver pwm_drv_table;
+
+static rt_err_t pwm_get_status(rt_uint32_t *status)
+{
+    rt_uint32_t channel_enable;
+
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    if(status == NULL || pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    if (GD_OK != GD_PWM_Get_Status(pwm_obj->id, &channel_enable))
+    {
+        rt_kprintf("get pwm status failed!\n");
+        return RT_ERROR;
+    }
+    *status = channel_enable;
+
+    return RT_EOK;
+}
+
+static rt_err_t pwm_enable(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t ret = RT_EOK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    ret = GD_PwmOnOff(pwm_obj->id, GTRUE);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("enable pwm device failed!\n");
+        return RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t pwm_disable(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t ret = RT_EOK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    ret = GD_PwmOnOff(pwm_obj->id, GFALSE);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("disable pwm device failed!\n");
+        return RT_ERROR;
+    }
+
+    return ret;
+}
+
+static int pwm_get_duty_cycle_ns(struct pwm_device *pwm)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t freq, duty;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    if (GD_PWM_Get_Param(pwm_obj->id, &freq, &duty))
+    {
+        rt_kprintf("GD_PWM_Get_Param error.\n");
+        return -1;
+    }
+
+    rt_kprintf("get duty: %lu%%, freq: %lu\n", duty, freq);
+
+    return 0;
+}
+
+static int pwm_set_duty_cycle_ns(struct pwm_device *pwm)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t range, duty, freq;
+    GERR ret = 0;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    freq = pwm->freq;
+    range = pwm->range;
+    duty = pwm->duty;
+    //param mode The PWM mode: 0 - Normal Speed Mode; 1 - Sync Speed Mode.
+    ret = GD_PWM_Set_Mode(pwm_obj->id, 0);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm mode 0 failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Set_Param(pwm_obj->id, freq, range, duty);
+    if (GD_PWM_NO_ERR != ret)
+    {
+        if (GD_PWM_ERR_NOT_SUPPORTED_CHANNEL == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support channel.\n",
+                       (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_NOT_SUPPORTED_FREQUENCY == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support Freq.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_NOT_SUPPORTED_RANGE == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *not support Range.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_WRONG_DUTY_CONFIGURATION == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *wrong duty.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+        else if(GD_PWM_ERR_RANGE_EXCEED_LIMIT == ret)
+        {
+            rt_kprintf("PWM Set_Param:set[%d %d %d]error *exceed Range limit.\n",
+                    (int)freq, (int)range, (int)duty);
+        }
+
+        return -1;
+    }
+
+    return 0;
+}
+
+static int pwm_get_vsync_mode_param(rt_uint16_t *speed)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    GERR ret = GD_OK;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    ret = GD_PWM_Get_Speed(pwm_obj->id, speed);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Get pwm speed failed!\n");
+        return -1;
+    }
+
+    rt_kprintf("get speed: %u\n", *speed);
+
+    return 0;
+}
+
+static int pwm_set_vsync_mode_param(struct pwm_param_vsync_mode *param)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    GERR ret = GD_OK;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    //param mode The PWM mode: 0 - Normal Speed Mode; 1 - Sync Speed Mode.
+    ret = GD_PWM_Set_Mode(pwm_obj->id, 1);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm mode 1 failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Set_Speed(pwm_obj->id, param->speed);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm speed failed!\n");
+        return -1;
+    }
+
+    ret = GD_PWM_Cycle(pwm_obj->id, param->highLevelCnt, param->lowLevelCnt);
+    if(ret != GD_OK)
+    {
+        rt_kprintf("Set pwm cycle failed!\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int pwm_set_clock_divider(int ratio)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+    rt_uint32_t range, duty, freq;
+    GERR ret = 0;
+
+    if (pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+	if ((ratio != 1) && (ratio != 2) && (ratio != 3))
+	{
+	    rt_kprintf("pwm_set_clock_divider:%d wrong param.\n", ratio);
+		return -1;
+	}
+
+	if (GD_OK != GD_PWM_Set_Clock_Divider(pwm_obj->id, ratio))
+	{
+		rt_kprintf("gadi_pwm_set_clock_divider:%d set error.\n", ratio);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int pwm_set_active_channel(int id)
+{
+    GERR ret = 0;
+
+    if (id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return -1;
+    }
+
+    if (pwm_drv_table.pwm[id].gpio_id == 0xff)
+    {
+        rt_kprintf("channel not open \n");
+        return -1;
+    }
+
+    pwm_drv->id = id;
+
+    return 0;
+}
+
+static rt_err_t pwm_start(struct gk_pwm_obj *pwm_obj)
+{
+    rt_uint32_t pwmStatus = 0;
+    rt_uint32_t ret = GD_OK;
+
+    ret = pwm_get_status(&pwmStatus);
+    if(ret != RT_EOK)
+    {
+        return ret;
+    }
+
+    if(pwmStatus)
+    {
+        ret = pwm_disable(pwm_obj);
+        if(ret != RT_EOK)
+        {
+            return ret;
+        }
+    }
+
+    return pwm_enable(pwm_obj);
+}
+
+static rt_err_t gk_pwm_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    rt_err_t ret = RT_EOK;
+    int index;
+
+    for (index=0; index<PWM_MAX_CHANNEL; index++)
+    {
+        if ((pwm_drv_table.pwm[index].id != 0xff) && (pwm_drv_table.pwm[index].gpio_id != 0xff))
+        {
+            rt_kprintf("pwm_drv_table.pwm[%d] id= %d, gpio_id = %d\n",
+                        index,
+                        pwm_drv_table.pwm[index].id,
+                        pwm_drv_table.pwm[index].gpio_id);
+
+            ret = GD_PWM_Open(pwm_drv_table.pwm[index].id, pwm_drv_table.pwm[index].gpio_id);
+            if(ret != GD_OK)
+            {
+               rt_kprintf("open pwm device %d channel failed!\n", pwm_drv_table.pwm[index].id);
+               continue;
+            }
+        }
+    }
+
+    if (pwm_drv_table.pwm[0].gpio_id != 0xff)
+    {
+        pwm_drv->id = pwm_drv_table.pwm[0].id;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_pwm_close(rt_device_t dev)
+{
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+
+    if(pwm_obj->id >= PWM_MAX_CHANNEL)
+    {
+        rt_kprintf("PWM: > max channel \n");
+        return RT_ERROR;
+    }
+
+    GD_PWM_Close(pwm_obj->id);
+
+    return RT_EOK;
+}
+
+static rt_err_t gk_pwm_ioctl(rt_device_t dev, int cmd, void *arg)
+{
+    int ratio, ret = 0;
+    rt_uint16_t *speed = NULL;
+    struct pwm_device *pwm = NULL;
+    struct pwm_param_vsync_mode *vsync_param = NULL;
+    struct gk_pwm_obj *pwm_obj = (struct gk_pwm_obj *)pwm_drv;
+
+    switch (cmd)
+    {
+        case ENABLE_PWM:
+            pwm_start(pwm_obj);
+            break;
+
+        case DISABLE_PWM:
+            pwm_disable(pwm_obj);
+            break;
+
+        case SET_PWM_DUTY_CYCLE:
+            pwm = (struct pwm_device *)arg;
+            pwm_set_duty_cycle_ns(pwm);
+            break;
+
+        case GET_PWM_DUTY_CYCLE:
+            pwm = (struct pwm_device *)arg;
+            pwm_get_duty_cycle_ns(pwm);
+            break;
+
+        case SET_PWM_VSYNC_MODE:
+            vsync_param = (struct pwm_param_vsync_mode *)arg;
+            pwm_set_vsync_mode_param(vsync_param);
+            break;
+
+        case GET_PWM_VSYNC_MODE:
+            speed = (rt_uint16_t *)arg;
+            pwm_get_vsync_mode_param(speed);
+            break;
+
+        case SET_PWM_CLOCK_DIV:
+            ratio = *((int*)arg);
+            pwm_set_clock_divider(ratio);
+            break;
+
+        case SET_PWM_ACT_CHANNEL:
+            ratio = *((int*)arg);
+            pwm_set_active_channel(ratio);
+            break;
+
+        default:
+            break;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_pwm_init(rt_device_t dev)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = (rt_err_t)GD_PWM_Init();
+
+    return ret;
+}
+
+int gk_pwm_probe(void *priv_data)
+{
+    rt_device_t pwm_dev;
+    int index;
+
+    for (index=0; index < PWM_MAX_CHANNEL; index++)
+    {
+        pwm_drv_table.pwm[index].id  = 0xff;
+        pwm_drv_table.pwm[index].gpio_id = 0xff;
+    }
+
+    for (index=0; index < PWM_MAX_CHANNEL; index++)
+    {
+        if (((struct pwm_driver *)priv_data)->pwm[index].gpio_id > 0)
+        {
+            pwm_drv_table.pwm[index].id  = ((struct pwm_driver *)priv_data)->pwm[index].id;
+            pwm_drv_table.pwm[index].gpio_id = ((struct pwm_driver *)priv_data)->pwm[index].gpio_id;
+        }
+    }
+
+    pwm_drv = rt_malloc(sizeof(struct gk_pwm_obj));
+    if (pwm_drv == RT_NULL)
+    {
+        rt_kprintf("ERROR: %s pwm_drv malloc failed\n", __func__);
+    }
+    rt_memset(pwm_drv, 0, sizeof(struct gk_pwm_obj));
+
+    pwm_dev = rt_malloc(sizeof(struct rt_device));
+    if (pwm_dev == RT_NULL)
+    {
+        rt_kprintf("ERROR: %s rt_device malloc failed\n", __func__);
+    }
+    rt_memset(pwm_dev, 0, sizeof(struct rt_device));
+
+    pwm_dev->user_data = &pwm_drv_table;
+    pwm_dev->open      = gk_pwm_open;
+    pwm_dev->close     = gk_pwm_close;
+    pwm_dev->control   = gk_pwm_ioctl;
+    pwm_dev->init      = gk_pwm_init;
+    pwm_dev->type      = RT_Device_Class_Miscellaneous;
+
+    rt_device_register(pwm_dev, "pwm", RT_DEVICE_FLAG_RDWR);
+
+    return 0;
+}
+
+int gk_pwm_exit(void *priv_data) { return 0; }
+struct gk_platform_driver pwm_driver_ops = {
+    .name = "pwm", .probe = gk_pwm_probe, .remove = gk_pwm_exit,
+};
+
+void rt_hw_pwm_init(void)
+{
+	gk_platform_driver_init(&pwm_driver_ops);
+}
+
+#ifdef GK_TEST_PWM
+int gk_pwm_test(void)
+{
+    rt_device_t pwm_dev;
+    struct pwm_device pwm;
+
+    pwm.duty = 50;
+    pwm.range = 100;
+    pwm.freq = 1000;
+
+    pwm_dev = rt_device_find("pwm");
+    if (!pwm_dev)
+    {
+        rt_kprintf("cann't find the pwm dev\n");
+    }
+
+    pwm_dev->init(pwm_dev);
+    pwm_dev->open(pwm_dev, 0);
+    pwm_dev->control(pwm_dev, SET_PWM_DUTY_CYCLE, &pwm);
+    pwm_dev->control(pwm_dev, ENABLE_PWM, NULL);
+
+    return 0;
+}
+#endif
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+#ifdef GK_TEST_PWM
+FINSH_FUNCTION_EXPORT(gk_pwm_test, gk_pwm_test);
+#endif
+#endif

+ 75 - 0
bsp/gkipc/drivers/drv_pwm.h

@@ -0,0 +1,75 @@
+/*
+ * File      : drv_pwm.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef PWM_H_
+#define PWM_H_
+
+#include <rtthread.h>
+#include <rtdef.h>
+
+#define ENABLE_PWM (0x10)
+#define DISABLE_PWM (0x11)
+
+#define SET_PWM_DUTY_CYCLE (0x12)
+#define GET_PWM_DUTY_CYCLE (0x13)
+
+#define SET_PWM_VSYNC_MODE (0x14)
+#define GET_PWM_VSYNC_MODE (0x15)
+
+#define SET_PWM_CLOCK_DIV  (0x16)
+#define SET_PWM_ACT_CHANNEL (0x17)
+
+#define PWM_MAX_CHANNEL 8
+
+struct pwm_param_vsync_mode
+{
+    rt_uint16_t speed;
+    rt_uint32_t highLevelCnt;
+    rt_uint32_t lowLevelCnt;
+};
+
+struct pwm_device
+{
+    rt_uint32_t freq;
+    rt_uint32_t range;
+    rt_uint32_t duty;
+};
+
+struct gk_pwm_obj
+{
+    int id;
+    rt_uint32_t gpio_id;
+};
+
+struct pwm_driver
+{
+    struct gk_pwm_obj pwm[PWM_MAX_CHANNEL];
+};
+
+void rt_hw_pwm_init(void);
+
+#endif /* PWM_H_ */

+ 1684 - 0
bsp/gkipc/drivers/drv_sdio.c

@@ -0,0 +1,1684 @@
+#include <rtdef.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+
+#include <string.h>
+#include <gd_int.h>
+#include <gd_timer.h>
+#include <gh_sdio_all.h>
+
+#include "drv_sdio.h"
+#include "platform.h"
+
+/*
+*interrupt config
+*/
+#define SDIO_USE_DMA    (0)
+#define SDIO_INT_STATUS_EN  (1 | 1<<1 | 1<<3 | 1<<4 |1<<5 | 1<<6 | 1<<7)
+#define SDIO_INT_SIG_EN     (1 | 1<<1 | 1<<3 | 1<<4 |1<<5 | 1<<6 | 1<<7)
+
+/*config for dma*/
+/* 7 -> 512Kbyte 6->256 5->128 4->64 3->32 2->16 1->8 0->4*/
+#define SDIO_DEFAULT_BOUNDARY_SIZE    (64* 1024)//support max 512Kbyte,for memory issue,use 64kbyte
+#define SDIO_DEFAULT_BOUNDARY_ARG     (4)
+
+#define MMC_NOREP          (1<<0)        /* no response*/
+#define MMC_REP_136        (1<<1)        /* 136 bit response */
+#define MMC_REP_48         (1<<2)        /* 48 bit response */
+#define MMC_REP_48_BUSY    (1<<3)        /* card may send busy */
+#define MMC_REP_CRC        (1<<4)        /* expect valid crc */
+#define MMC_COM_INDEX_CHEC (1<<5)        /* command index check enable */
+#define MMC_DATE_PRES      (1<<6)        /* data present select */
+
+
+#define MMC_RSP_NONE  (0)
+#define MMC_RSP_R1    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R1B   (MMC_REP_48_BUSY|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R2    (MMC_REP_136|MMC_REP_CRC)
+#define MMC_RSP_R3    (MMC_REP_48)
+#define MMC_RSP_R4    (MMC_REP_48)
+#define MMC_RSP_R5    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R6    (MMC_REP_48|MMC_REP_CRC|MMC_COM_INDEX_CHEC)
+#define MMC_RSP_R7    (MMC_REP_48)
+
+#define SDIO_IRQ_CMD_COMPLETE        0x0001
+#define SDIO_IRQ_BLOCK_GAP_EVENT     0x0002
+#define SDIO_IRQ_DMA                 0x0004
+#define SDIO_IRQ_TRANSFER_COMPLETE   0x0008
+#define SDIO_IRQ_WRITE_READY         0x0010
+#define SDIO_IRQ_CARD_INSERTED       0x0020
+#define SDIO_IRQ_READ_READY          0x0040
+#define SDIO_IRQ_CARD_REMOVED        0x0080
+#define SDIO_IRQ_CARD_INT            0x0100
+#define SDIO_ERROR_IRQ               0x8000
+
+#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b         */
+
+#ifdef CODEC_710XS
+#define SDIO_SLOT_COUNT       2              /* total handle count */
+#else
+#define SDIO_SLOT_COUNT       1              /* total handle count */
+#endif
+
+#define SDIO_CMD_DEFAULT_TIMEOUT  3     /* FIXME, default 3s for one sdio cmd */
+
+static GD_HANDLE inthandleArray[SDIO_SLOT_COUNT*2];
+static struct gk_sdio *sdioInstancePtr[SDIO_SLOT_COUNT] = {RT_NULL};
+
+#if SDIO_USE_DMA
+static rt_uint8_t  dmBuf[SDIO_SLOT_COUNT][SDIO_DEFAULT_BOUNDARY_SIZE] __attribute__((aligned(32))) __attribute__ ((section(".nocache_buffer"))) = {0,};//64kbyte
+#endif
+
+static void sdio_soft_reset(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control01Reg_SoftwareResetAll(index, 1);
+    GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index, 1);
+    GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index, 1);
+
+#elif defined GK7102C
+
+    GH_SDIO_set_SoftResetReg_SoftwareResetAll(index,1);
+    GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+    GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+#elif defined CODEC_710XS
+    GH_SDIO_set_Control01Reg_SoftwareResetAll(index,1);
+    GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+    GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+#endif
+}
+
+static void sdio_clock_onoff(rt_uint32_t index, rt_uint32_t on)
+{
+#ifdef CODEC_710X
+    if (on == 0)
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 1);
+    }
+
+#elif defined GK7102C
+
+    if (on == 0)
+    {
+        GH_SDIO_set_ClkControlReg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_ClkControlReg_SdClkEn(index, 1);
+    }
+#elif defined CODEC_710XS
+
+    if (on == 0)
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 0);
+    }
+    else
+    {
+        GH_SDIO_set_Control01Reg_SdClkEn(index, 1);
+    }
+
+#endif
+}
+
+static void sdio_set_clockdiv(rt_uint32_t index, rt_uint8_t div)
+{
+#ifdef CODEC_710X
+
+    GH_SDIO_set_Control01Reg_SdclkFreSelect(index, div);
+    GH_SDIO_set_Control01Reg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_Control01Reg_InternalClkStable(index)&0x1)
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#elif defined GK7102C
+    GH_SDIO_set_ClkControlReg_SdclkFreSelect(index, div);
+    GH_SDIO_set_ClkControlReg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_ClkControlReg_InternalClkStable(index)&0x1)
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#elif defined CODEC_710XS
+
+    GH_SDIO_set_Control01Reg_SdclkFreSelect(index, div);
+    GH_SDIO_set_Control01Reg_InternalClkEn(index, 1);
+
+    while(1)
+    {
+        if(GH_SDIO_get_Control01Reg(index)&(0x1<<16))
+              break;
+    }
+    sdio_clock_onoff(index, 1);
+
+#endif
+}
+
+static void sdio_select_voltage(rt_uint32_t index)
+{
+    rt_uint32_t caps = 0;
+    caps=GH_SDIO_get_CapReg(index);
+
+    if(caps & 0x1<<24)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x7);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+    else if(caps & 0x1<<25)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x6);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+    else if(caps & 0x1<<26)
+    {
+        GH_SDIO_set_Control00Reg_SdBusVoltageSelect(index, 0x5);
+        GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+    }
+
+}
+
+static void sdio_set_timeout_control(rt_uint32_t index,rt_uint8_t timeout)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control01Reg_DataTimeoutCounterValue(index, timeout);
+#elif defined GK7102C
+    GH_SDIO_set_SoftResetReg_DataTimeoutCounterValue(index,timeout);
+#elif defined CODEC_710XS
+    GH_SDIO_set_SoftResetReg_DataTimeoutCounterValue(index,timeout);
+#endif
+}
+
+static void sdio_set_host_ctl_speed(rt_uint32_t index, rt_uint8_t mode)
+{
+    GH_SDIO_set_Control00Reg_HostSpeedEn(index, mode);
+}
+
+static void sdio_set_host_ctl_width(rt_uint32_t index,rt_uint8_t mode)
+{
+    GH_SDIO_set_Control00Reg_DataTraWidth(index, mode);
+}
+
+static void sdio_enable_int_status(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    /*clear int*/
+    if(GH_SDIO_get_NorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStaReg(index, GH_SDIO_get_ErrIntStaReg(index));
+    }
+    GH_SDIO_set_NorIntStaEnReg(index, 0x0000);
+    GH_SDIO_set_NorIntStaEnReg(index, SDIO_INT_STATUS_EN);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0xffff);
+
+#elif defined GK7102C
+    if(GH_SDIO_get_NorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_ErrIntStatusReg(index, \
+            GH_SDIO_get_ErrIntStatusReg(index));
+    }
+    GH_SDIO_set_NorIntStaEnReg(index, 0x0);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0x0);
+    GH_SDIO_set_NorIntStaEnReg_CmdCompleteStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_TraCompleteStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_DmaIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_BufWReadyStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_BufRReadyStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_CardInsertionStatusEn(index, 1);
+    GH_SDIO_set_NorIntStaEnReg_CardRemStatusEn(index, 1);
+    GH_SDIO_set_ErrIntStaEnReg(index, 0xffff);
+
+#elif defined CODEC_710XS
+
+    if(GH_SDIO_get_ErrIntStaEnNorIntStaReg_ErrInt(index) & 0x1)
+    {
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+        GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+    }
+    GH_SDIO_set_BlkSizeNorIntStaEnReg(index, \
+    GH_SDIO_get_BlkSizeNorIntStaEnReg(index)&0x0000ffff);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg(index, \
+    (GH_SDIO_get_BlkSizeNorIntStaEnReg(index)&0x0000ffff)|(SDIO_INT_STATUS_EN<<16));
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+    GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)|0x0000ffff);
+#endif
+}
+
+static void sdio_enable_intsig(rt_uint32_t index)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntSigEnReg(index, 0x0000);
+    GH_SDIO_set_NorIntSigEnReg(index, SDIO_INT_SIG_EN);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0xffff);
+
+#elif defined GK7102C
+    GH_SDIO_set_NorIntSigEnReg(index, 0x0);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0x0);
+    GH_SDIO_set_NorIntSigEnReg_CmdCompleteSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_TraCompleteSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_DmaIntSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_BufWReadySigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_BufRReadySigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardInsertionSigEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardRemSigEn(index, 1);
+    GH_SDIO_set_ErrIntSigEnReg(index, 0xffff);
+#elif defined CODEC_710XS
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+    GH_SDIO_get_TranModeNorIntSigEnReg(index)&0x0000ffff);
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+    (GH_SDIO_get_TranModeNorIntSigEnReg(index)&0x0000ffff)|(SDIO_INT_SIG_EN<<16));
+    GH_SDIO_set_ErrIntSigEnBlkCouReg(index, \
+    GH_SDIO_get_ErrIntSigEnBlkCouReg(index)|0x0000ffff);
+#endif
+}
+
+
+static void sdio_set_blksize_reg(rt_uint32_t index, U16 boundary,U16 blksize)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_BlkSizeReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeReg_TraBlkSize(index, blksize);
+#elif defined GK7102C
+    GH_SDIO_set_BlkSizeReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeReg_TraBlkSize(index, blksize);
+#elif defined CODEC_710XS
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_HostSdmaBufSize(index, boundary);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_TraBlkSize(index, blksize);
+#endif
+}
+
+static void sdio_set_blkcnt_reg(rt_uint32_t index, U16  blkcnt)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_BlkCouReg_BlkCountForCurTra(index, blkcnt);
+#elif defined GK7102C
+    GH_SDIO_set_BlkCouReg_BlkCountForCurTra(index, blkcnt);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntSigEnBlkCouReg_BlkCountForCurTra(index, blkcnt);
+#endif
+}
+
+static void sdio_set_arg_reg (rt_uint32_t index, rt_uint32_t arg)
+{
+    GH_SDIO_set_ArgReg(index, arg);
+}
+
+static rt_uint32_t sdio_set_tramode_reg (rt_uint32_t index, rt_uint32_t  multblk, rt_uint32_t direction, rt_uint32_t  autocmd12en,
+    rt_uint32_t  blkcnten, rt_uint32_t  dmaen)
+{
+#ifdef CODEC_710X
+    rt_uint32_t modereg=GH_SDIO_get_TranModeReg(index);
+    modereg=(modereg & ~0xffff) | (direction << 5)| (multblk << 4) | (dmaen << 2) | (autocmd12en << 1) | (blkcnten << 0) ;
+    return modereg<<16;
+
+#elif defined GK7102C
+
+    GH_SDIO_TRANMODEREG_S tansModRegVal;
+    rt_uint32_t retVal;
+
+    tansModRegVal.bitc.msblkselect = multblk;
+    tansModRegVal.bitc.datatradirselect = direction;
+    tansModRegVal.bitc.dmaen = dmaen;
+    tansModRegVal.bitc.autocmd12en = autocmd12en;
+    tansModRegVal.bitc.blkcounten = blkcnten;
+
+    retVal = ((U32)tansModRegVal.all) << 16;
+    return retVal;
+
+#elif defined CODEC_710XS
+    rt_uint32_t modereg=GH_SDIO_get_TranModeNorIntSigEnReg(index);
+    modereg=(modereg & ~0xffff) | (multblk << 4) | (direction << 5)| (dmaen << 2) | (autocmd12en << 1) | (blkcnten << 0) ;
+    return modereg<<16;
+
+#endif
+}
+
+static void sdio_set_system_address_reg(rt_uint32_t index,rt_uint32_t addr)
+{
+    GH_SDIO_set_SysAddrReg(index, addr);
+}
+static void sdio_set_hostctl8BitMode(rt_uint8_t channel,rt_uint8_t mode)
+{
+#ifdef CODEC_710X
+    GH_SDIO_set_Control00Reg_Sd8BitMode(channel,mode);
+#elif defined GK7102C
+
+#elif defined CODEC_710XS
+
+#endif
+}
+
+static void sdio_reset(rt_uint8_t index)
+{
+    sdio_soft_reset(index);
+    sdio_clock_onoff(index, 0);
+#ifdef CODEC_710X
+    sdio_set_clockdiv(index, 1);
+#elif defined GK7102C
+    sdio_set_clockdiv(index, 0x40);
+#elif defined CODEC_710XS
+    sdio_set_clockdiv(index, 0x02);
+#endif
+    sdio_select_voltage(index);
+    sdio_set_timeout_control(index, 0xe);
+    sdio_set_host_ctl_speed(index, 0);
+    sdio_set_host_ctl_width(index, 0);
+    /*clear interrupt status*/
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+    GH_SDIO_set_ErrIntStaReg(index, GH_SDIO_get_ErrIntStaReg(index));
+#elif defined GK7102C
+    GH_SDIO_set_NorIntStaReg(index, GH_SDIO_get_NorIntStaReg(index));
+    GH_SDIO_set_ErrIntStatusReg(index,  GH_SDIO_get_ErrIntStatusReg(index));
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+#endif
+    /*card remove*/
+    sdio_enable_int_status(index);
+    sdio_enable_intsig(index);
+}
+
+static void sdio_power_on(rt_uint32_t index)
+{
+    /* Bus power on */
+    GH_SDIO_set_Control00Reg_SdBusPower(index, 1);
+
+    /* Enable SDIO interrupt */
+    sdio_enable_int_status(index);
+    sdio_enable_intsig(index);
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 1);
+#elif GK7102C
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 1);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 1);
+#elif defined(CODEC_710XS)
+    GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 1);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 1);
+#endif
+
+}
+
+
+static void sdio_power_off(rt_uint32_t index)
+{
+    /* Disable SDIO interrupt */
+
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaReg(index, 0);
+    GH_SDIO_set_ErrIntStaReg(index, 0);
+#elif defined GK7102C
+    GH_SDIO_set_NorIntStaReg(index, 0);
+    GH_SDIO_set_ErrIntStatusReg(index,  0);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, 0);
+#endif
+
+    /* Bus power off */
+    GH_SDIO_set_Control00Reg_SdBusPower(index, 0);
+}
+
+static void sdio_set_dma(rt_uint32_t index, struct rt_mmcsd_data *data,rt_uint8_t isDmaEnd)
+{
+#if SDIO_USE_DMA
+
+    rt_uint32_t total_len = data->blks * data->blksize;
+    rt_int32_t dma_len = 0,left_len = 0;
+    rt_uint32_t offset = 0;
+    rt_uint32_t read_len = 0;
+
+    if(!data)
+        return;
+
+    offset = data->bytes_xfered;
+
+    read_len = ((total_len - data->bytes_xfered) > SDIO_DEFAULT_BOUNDARY_SIZE)?\
+            SDIO_DEFAULT_BOUNDARY_SIZE:(total_len - data->bytes_xfered);
+
+    left_len = total_len - data->bytes_xfered;
+
+    if(left_len <= 0 && (data->flags & DATA_DIR_WRITE))
+        return;
+
+    dma_len = (left_len > SDIO_DEFAULT_BOUNDARY_SIZE)?SDIO_DEFAULT_BOUNDARY_SIZE:left_len;
+
+    if(data->flags & DATA_DIR_WRITE)
+    {
+        rt_memcpy((void *)&dmBuf[index][0],(void *)((rt_uint32_t)data->buf + offset),dma_len);
+        sdio_set_system_address_reg(index,(rt_uint32_t)&dmBuf[index][0]);
+
+        data->bytes_xfered += dma_len;
+    }
+    else if(data->flags & DATA_DIR_READ)
+    {
+        if(isDmaEnd)
+        {
+            rt_memcpy((void *)((rt_uint8_t *)data->buf + offset),(void *)&dmBuf[index][0],read_len);
+            data->bytes_xfered += dma_len;
+        }
+
+        if(dma_len <= 0)
+            return;
+
+        //rt_memset((void *)&dmBuf[index][0],0x0,SDIO_DEFAULT_BOUNDARY_SIZE);
+        sdio_set_system_address_reg(index,(rt_uint32_t)&dmBuf[index][0]);
+    }
+
+#endif
+
+}
+static void sdio_isr0(void)
+{
+    rt_int32_t   ret = RT_EOK;
+    rt_uint32_t  index = 0;
+    rt_uint32_t  bufferpos= 0,*pdata = NULL;
+#ifdef CODEC_710X
+    rt_uint32_t  irq_status_reg =(GH_SDIO_get_NorIntStaReg(index)| GH_SDIO_get_ErrIntStaReg(index)<<16);
+#elif defined GK7102C
+    rt_uint32_t irq_status_reg=(GH_SDIO_get_NorIntStaReg(index) | GH_SDIO_get_ErrIntStatusReg(index)<<16);
+#elif defined CODEC_710XS
+    rt_uint32_t  irq_status_reg=(((GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0xffff0000)>>16) | \
+    ((GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)<<16));
+#endif
+
+    //rt_kprintf("%s, irq_status_reg = 0x%x\n", __func__,irq_status_reg);
+    if( irq_status_reg & SDIO_ERROR_IRQ )
+    {
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStaReg(index,GH_SDIO_get_ErrIntStaReg(index));
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStatusReg(index,GH_SDIO_get_ErrIntStatusReg(index));
+        GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index,GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+        *(volatile rt_int16_t *)(0x90000000+0x14) = *(volatile U16 *)(0x90000000+0x14);
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+#endif
+        rt_kprintf("%s,error irq\n",__FUNCTION__);
+        ret = RT_ERROR;
+
+        goto EXIT;
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CMD_COMPLETE )
+    {
+
+#ifdef CODEC_710X
+        if(GH_SDIO_get_CmdReg_RepTypeSelect(index)==1)
+#elif defined GK7102C
+        if(GH_SDIO_get_CommondReg_RepTypeSelect(index)==1)
+#elif defined CODEC_710XS
+        if(GH_SDIO_get_ErrIntStatusCommondReg_RepTypeSelect(index)==1)
+#endif
+        {
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp3Reg(index)<<8 | (GH_SDIO_get_Resp2Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[1] = GH_SDIO_get_Resp2Reg(index)<<8 | (GH_SDIO_get_Resp1Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[2] = GH_SDIO_get_Resp1Reg(index)<<8 | (GH_SDIO_get_Resp0Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[3] = GH_SDIO_get_Resp0Reg(index)<<8;
+        }
+        else
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp0Reg(index);
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CMD_COMPLETE<<16));
+
+#endif
+
+        if(!sdioInstancePtr[index]->cmd->data)
+        {
+            sdioInstancePtr[index]->cmd->err = RT_EOK;
+            rt_completion_done(&(sdioInstancePtr[index]->completion));
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_REMOVED )
+    {
+        sdio_reset(index);
+
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#elif defined CODEC_710XS
+    GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+        (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|SDIO_IRQ_CARD_REMOVED<<16);
+#endif
+        if(sdioInstancePtr[index]->cmd)
+        {
+            sdioInstancePtr[index]->cmd->err = ret;
+            if(sdioInstancePtr[index]->cmd->data)
+                sdioInstancePtr[index]->cmd->data->err = ret;
+        }
+
+        rt_completion_done(&(sdioInstancePtr[index]->completion));
+        mmcsd_change(sdioInstancePtr[index]->host);
+
+    }
+    else if( irq_status_reg & SDIO_IRQ_CARD_INSERTED )
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CARD_INSERTED<<16));
+
+#endif
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_READ_READY )
+    {
+
+#ifdef CODEC_710X
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#elif defined GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufREn(index)))
+#elif defined CODEC_710XS
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#endif
+        {
+            ret = RT_EBUSY;
+            goto EXIT;
+        }
+        else
+        {
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_READ_READY);
+#elif defined GK7102C
+            GH_SDIO_set_NorIntStaReg(index,SDIO_IRQ_READ_READY);
+#elif defined CODEC_710XS
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_READ_READY<<16));
+
+#endif
+
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                *pdata++ = GH_SDIO_get_BufferDataPortReg(index);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_WRITE_READY )
+    {
+
+#ifdef CODEC_710X
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#elif defined GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufWEn(index)))
+#elif defined CODEC_710XS
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#endif
+        {
+            ret = RT_EBUSY;
+            goto EXIT;
+        }
+        else
+        {
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);
+#elif defined GK7102C
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);//|(SDIO_IRQ_WRITE_READY<<16));
+#elif defined CODEC_710XS
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_WRITE_READY<<16));//|(SDIO_IRQ_WRITE_READY<<16));
+
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize )
+            {
+                GH_SDIO_set_BufferDataPortReg(index, *pdata++);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+    }
+
+    if(irq_status_reg & SDIO_IRQ_DMA)//FIXME,need check
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_DMA<<16));
+#endif
+
+        if(!sdioInstancePtr[index]->cmd)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            return;
+
+        sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_TRANSFER_COMPLETE )
+    {
+#ifdef CODEC_710X
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#elif defined GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#elif defined CODEC_710XS
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_TRANSFER_COMPLETE<<16));
+#endif
+        ret = RT_EOK;
+
+        if(!sdioInstancePtr[index]->cmd)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            goto EXIT;
+
+        if(sdioInstancePtr[index]->cmd->data->flags & DATA_DIR_READ)
+            sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+        goto EXIT;
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_INT )
+    {
+        do
+        {
+            if(!sdioInstancePtr[index])
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host)
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host->sdio_irq_sem)
+                goto CASE2;
+
+        CASE1:
+            sdio_irq_wakeup(sdioInstancePtr[index]->host);
+            break;
+
+        CASE2:
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif GK7102C
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif defined(CODEC_710XS)
+            GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 0);
+            GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 0);
+#endif
+
+        }while(0);
+
+    }
+
+    return;
+
+EXIT:
+
+    if(sdioInstancePtr[index]->cmd)
+    {
+        sdioInstancePtr[index]->cmd->err = ret;
+        if(sdioInstancePtr[index]->cmd->data)
+            sdioInstancePtr[index]->cmd->data->err = ret;
+    }
+
+    rt_completion_done(&(sdioInstancePtr[index]->completion));
+}
+
+#ifdef CODEC_710X
+
+static void sdio_isr1(void)
+{
+
+}
+
+#else
+static void sdio_isr1(void)
+{
+    rt_int32_t   ret = RT_EOK;
+    rt_uint8_t   index = 1;
+    rt_uint32_t  bufferpos= 0;
+    rt_uint32_t  *pdata;
+
+#ifdef GK7102C
+    rt_uint32_t irq_status_reg=(GH_SDIO_get_NorIntStaReg(index) | \
+        GH_SDIO_get_ErrIntStatusReg(index)<<16);
+#else
+    rt_uint32_t  irq_status_reg=(((GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0xffff0000)>>16) | \
+        ((GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)<<16));
+
+#endif
+
+    //rt_kprintf("%s, irq_status_reg = 0x%x\n", __func__,irq_status_reg);
+
+    if( irq_status_reg & SDIO_ERROR_IRQ )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index,GH_SDIO_get_NorIntStaReg(index));
+        GH_SDIO_set_ErrIntStatusReg(index,GH_SDIO_get_ErrIntStatusReg(index));
+        GH_SDIO_set_SoftResetReg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_SoftResetReg_SoftwareResetCmdLine(index,1);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index,GH_SDIO_get_ErrIntStaEnNorIntStaReg(index));
+        *(volatile U16 *)(0x90010000+0x14) = *(volatile U16 *)(0x90010000+0x14);
+        GH_SDIO_set_Control01Reg_SoftwareResetDatLine(index,1);
+        GH_SDIO_set_Control01Reg_SoftwareResetCmdLine(index,1);
+
+#endif
+        ret = RT_ERROR;
+
+        goto EXIT;
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CMD_COMPLETE )
+    {
+#ifdef GK7102C
+        if(GH_SDIO_get_CommondReg_RepTypeSelect(index)==1)
+#else
+        if(GH_SDIO_get_ErrIntStatusCommondReg_RepTypeSelect(index)==1)
+#endif
+        {
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp3Reg(index)<<8 | (GH_SDIO_get_Resp2Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[1] = GH_SDIO_get_Resp2Reg(index)<<8 | (GH_SDIO_get_Resp1Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[2] = GH_SDIO_get_Resp1Reg(index)<<8 | (GH_SDIO_get_Resp0Reg(index) & 0xff000000)>>24;
+            sdioInstancePtr[index]->cmd->resp[3] = GH_SDIO_get_Resp0Reg(index)<<8;
+        }
+        else
+            sdioInstancePtr[index]->cmd->resp[0] = GH_SDIO_get_Resp0Reg(index);
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CMD_COMPLETE);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CMD_COMPLETE<<16));
+
+#endif
+        if(!sdioInstancePtr[index]->cmd->data)
+        {
+            sdioInstancePtr[index]->cmd->err = RT_EOK;
+            rt_completion_done(&(sdioInstancePtr[index]->completion));
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_REMOVED )
+    {
+        sdio_reset(index);
+
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_REMOVED);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|SDIO_IRQ_CARD_REMOVED<<16);
+
+#endif
+        if(sdioInstancePtr[index]->cmd)
+        {
+            sdioInstancePtr[index]->cmd->err = ret;
+            if(sdioInstancePtr[index]->cmd->data)
+                sdioInstancePtr[index]->cmd->data->err = ret;
+        }
+
+        rt_completion_done(&(sdioInstancePtr[index]->completion));
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+    else if( irq_status_reg & SDIO_IRQ_CARD_INSERTED )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_CARD_INSERTED);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_CARD_INSERTED<<16));
+
+#endif
+
+        mmcsd_change(sdioInstancePtr[index]->host);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_READ_READY )
+    {
+#ifdef GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufREn(index)))
+#else
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<11))
+#endif
+        {
+            ret = RT_EBUSY;
+
+            goto EXIT;
+        }
+        else
+        {
+#ifdef GK7102C
+            GH_SDIO_set_NorIntStaReg(index,SDIO_IRQ_READ_READY);
+#else
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_READ_READY<<16));
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                *pdata++ = GH_SDIO_get_BufferDataPortReg(index);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+        }
+
+    }
+
+    if( irq_status_reg & SDIO_IRQ_WRITE_READY )
+    {
+#ifdef GK7102C
+        if (!(GH_SDIO_get_PresentStateReg_BufWEn(index)))
+#else
+        if (!(GH_SDIO_get_PresentStateReg(index) & 0x1<<10))
+#endif
+        {
+            ret = RT_EBUSY;
+
+            goto EXIT;
+        }
+        else
+        {
+#ifdef GK7102C
+            GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_WRITE_READY);//|(SDIO_IRQ_WRITE_READY<<16));
+#else
+            GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+                (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_WRITE_READY<<16));//|(SDIO_IRQ_WRITE_READY<<16));
+
+#endif
+            if(!sdioInstancePtr[index]->cmd)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data)
+                return;
+
+            if(!sdioInstancePtr[index]->cmd->data->buf)
+                return;
+
+            pdata = sdioInstancePtr[index]->cmd->data->buf + sdioInstancePtr[index]->cmd->data->bytes_xfered/4;
+            while( bufferpos < sdioInstancePtr[index]->cmd->data->blksize)
+            {
+                GH_SDIO_set_BufferDataPortReg(index, *pdata++);
+                bufferpos += 4;
+                sdioInstancePtr[index]->cmd->data->bytes_xfered += 4;
+            }
+
+        }
+    }
+
+    if(irq_status_reg & SDIO_IRQ_DMA)//FIXME,need check
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_DMA);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_DMA<<16));
+#endif
+        if(!sdioInstancePtr[index]->cmd)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            return;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            return;
+
+        sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+    }
+
+    if( irq_status_reg & SDIO_IRQ_TRANSFER_COMPLETE )
+    {
+#ifdef GK7102C
+        GH_SDIO_set_NorIntStaReg(index, SDIO_IRQ_TRANSFER_COMPLETE);
+#else
+        GH_SDIO_set_ErrIntStaEnNorIntStaReg(index, \
+            (GH_SDIO_get_ErrIntStaEnNorIntStaReg(index)&0x0000ffff)|(SDIO_IRQ_TRANSFER_COMPLETE<<16));
+#endif
+        ret = RT_EOK;
+
+        if(!sdioInstancePtr[index]->cmd)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data)
+            goto EXIT;
+
+        if(!sdioInstancePtr[index]->cmd->data->buf)
+            goto EXIT;
+
+        if(sdioInstancePtr[index]->cmd->data->flags & DATA_DIR_READ)
+            sdio_set_dma(index,sdioInstancePtr[index]->cmd->data,1);
+
+        goto EXIT;
+    }
+
+    if( irq_status_reg & SDIO_IRQ_CARD_INT )
+    {
+        do
+        {
+            if(!sdioInstancePtr[index])
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host)
+                goto CASE2;
+
+            if(!sdioInstancePtr[index]->host->sdio_irq_sem)
+                goto CASE2;
+
+        CASE1:
+            sdio_irq_wakeup(sdioInstancePtr[index]->host);
+            break;
+
+        CASE2:
+#ifdef CODEC_710X
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif GK7102C
+            GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(index, 0);
+            GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(index, 0);
+#elif defined(CODEC_710XS)
+            GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(index, 0);
+            GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(index, 0);
+#endif
+
+        }while(0);
+
+    }
+
+    return;
+
+EXIT:
+
+    if(sdioInstancePtr[index]->cmd)
+    {
+        sdioInstancePtr[index]->cmd->err = ret;
+        if(sdioInstancePtr[index]->cmd->data)
+            sdioInstancePtr[index]->cmd->data->err = ret;
+    }
+
+    rt_completion_done(&(sdioInstancePtr[index]->completion));
+}
+
+#endif
+
+static rt_int32_t sdio_init(rt_uint32_t index)
+{
+    rt_int32_t ret;
+    GD_INT_OPEN_PARAMS_S     intParams;
+
+#ifdef CODEC_710XS
+    rt_int8_t detect_irq[SDIO_SLOT_COUNT] = {GD_INT_SD_CARD_DETECT_IRQ, GD_INT_SD2_CARD_DETECT_IRQ};
+    rt_int8_t ctl_irq[SDIO_SLOT_COUNT]  = {GD_INT_SD_CONTROLLER_IRQ, GD_INT_SD2_CONTROLLER_IRQ};
+#else
+    rt_int8_t detect_irq[SDIO_SLOT_COUNT] = {GD_INT_SD_CARD_DETECT_IRQ};
+    rt_int8_t ctl_irq[SDIO_SLOT_COUNT]  = {GD_INT_SD_CONTROLLER_IRQ};
+#endif
+    rt_int8_t i = (index == 0)? 0:2;
+
+    intParams.type           = ctl_irq[index];
+    intParams.sensitivity    = GD_INT_LEVEL_HIGH;
+    intParams.active         = GD_INT_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+    intParams.isrFct.lowPrio = (index == 0)? sdio_isr0:sdio_isr1;
+    ret = GD_INT_Open(&intParams, &inthandleArray[i]);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    GD_INT_Enable(&inthandleArray[i],GD_INT_ENABLED);
+    /*open the sdio detec interrupt*/
+    intParams.type           = detect_irq[index];
+    intParams.sensitivity    = GD_INT_BOTH_EDGES;
+    intParams.active         = GD_INT_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+    intParams.isrFct.lowPrio = (index == 0)? sdio_isr0:sdio_isr1;
+    ret = GD_INT_Open(&intParams, &inthandleArray[i+1]);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    GD_INT_Enable(&inthandleArray[i+1],GD_INT_ENABLED);
+    if(ret != 0)
+    {
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+static rt_uint8_t sdio_get_inserted_flag(rt_uint32_t index)
+{
+    return ((GH_SDIO_get_PresentStateReg(index)&0x00070000) == 0x00070000);
+}
+
+static void sdio_set_cmd_reg(rt_uint32_t index,rt_uint32_t cmdarg,rt_uint32_t data,rt_uint32_t flags)
+{
+#ifdef GK7102C
+
+    rt_uint8_t cmd = cmdarg & 0x3f;
+    rt_uint16_t transMod = cmdarg >> 16;
+    GH_SDIO_COMMONDREG_S commRegVal;
+
+    commRegVal.all = 0;
+    commRegVal.bitc.cmdindex = cmd;
+
+    if(cmd == 12)
+    {
+        /*abort cmd*/
+        commRegVal.bitc.cmdtype = 3;
+    }
+    else
+    {
+        /*suspend/resume cmd(sdio)*/
+    }
+
+    if (flags & MMC_REP_136)                /* Long REP */
+    {
+        commRegVal.bitc.reptypeselect = 1;
+    }
+    else if (flags & MMC_REP_48_BUSY)        /* R1B */
+    {
+        commRegVal.bitc.reptypeselect = 3;
+    }
+    else if (flags & MMC_REP_48)            /* Normal REP */
+    {
+        commRegVal.bitc.reptypeselect = 2;
+    }
+
+    if (flags & MMC_COM_INDEX_CHEC)
+    {
+        commRegVal.bitc.cmdindexchecken = 1;
+    }
+
+    if (flags & MMC_REP_CRC)
+    {
+        commRegVal.bitc.cmdcrcchecken = 1;
+    }
+
+    if (data)
+    {
+        commRegVal.bitc.datapreselect = 1;
+    }
+
+    GH_SDIO_set_TranModeReg(index, transMod);
+    GH_SDIO_set_CommondReg(index, commRegVal.all);
+#else
+
+    rt_uint8_t cmd=cmdarg & 0x3f;
+    unsigned short cmdval=(cmd<<8);
+
+    if(cmd == MMC_STOP_TRANSMISSION)
+    {
+        /*abort cmd*/
+        cmdval |=(3<<6);
+    }
+    else
+    {
+        /*suspend/resume cmd(sdio)*/
+    }
+
+    if (flags & MMC_REP_136)                /* Long REP */
+    {
+        cmdval |= 0x01;
+    }
+    else if (flags & MMC_REP_48_BUSY)        /* R1B */
+    {
+        cmdval |= 0x03;
+    }
+    else if (flags & MMC_REP_48)            /* Normal REP */
+    {
+        cmdval |= 0x02;
+    }
+
+    if (flags & MMC_COM_INDEX_CHEC)
+    {
+        cmdval |= (1<<5);
+    }
+
+    if (flags & MMC_REP_CRC)
+    {
+        cmdval |= (1<<3);
+    }
+
+    if (data)
+    {
+        cmdval |= (1<<4);
+    }
+
+    #ifdef CODEC_710X
+
+    GH_SDIO_set_TranModeReg(index, cmdarg>>16);
+    GH_SDIO_set_CmdReg(index, cmdval);
+
+    #elif defined(CODEC_710XS)
+
+    GH_SDIO_set_TranModeNorIntSigEnReg(index, \
+        (GH_SDIO_get_TranModeNorIntSigEnReg(index)&0xffff0000)|(cmdarg>>16));
+    GH_SDIO_set_ErrIntStatusCommondReg(index, \
+        (GH_SDIO_get_ErrIntStatusCommondReg(index)&0x0000ffff)|(cmdval<<16));
+
+    #endif
+
+#endif
+}
+
+static int sdio_issue_cmd(rt_uint8_t index,rt_uint32_t cmd, rt_uint32_t arg, rt_uint32_t data, rt_uint32_t flags)
+{
+    int i;
+
+    if(data == 0)
+    {
+        /*wait for cmd line free */
+        for(i = 0; i < 0x1000; i++)
+        {
+            if(!(GH_SDIO_get_PresentStateReg_CmdInhibitCmd(index)))
+                break;
+            GD_TIMER_Delay(10);
+        }
+
+        if (i >= 0x1000)
+        {
+            return -RT_EBUSY;
+        }
+    }
+    else
+    {
+        /*wait for data line (Cmd_inhibit_dat) free */
+        if(flags & MMC_REP_48_BUSY && cmd != MMC_STOP_TRANSMISSION)
+        {
+             for(i = 0; i < 0x1000; i++)
+             {
+                 if(!(GH_SDIO_get_PresentStateReg_CmdInhibitData(index)))
+                     break;
+                 GD_TIMER_Delay(10);
+             }
+
+             if (i >= 0x1000)
+             {
+                return -RT_EBUSY;
+             }
+        }
+    }
+
+    sdio_set_arg_reg(index, arg);
+    sdio_set_cmd_reg(index,cmd,data,flags);
+
+    return RT_EOK;
+}
+
+static void sdio_send_command(struct gk_sdio *sdiodrv, struct rt_mmcsd_cmd *cmd)
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t cmd_flags = 0,tmp_cmd = 0;
+    rt_uint8_t multblk = 0,readop = 1,timeout = SDIO_CMD_DEFAULT_TIMEOUT;
+    struct gk_sdio_info *sdio_info;
+    struct rt_mmcsd_data *data;
+
+    if (!sdiodrv || !cmd)
+    {
+        rt_kprintf("ERROR: %s, params is NULL\n", __func__);
+        return;
+    }
+
+    sdio_info = (struct gk_sdio_info *)sdiodrv->priv;
+
+
+    data = cmd->data;
+
+    rt_enter_critical();
+    sdiodrv->cmd = cmd;
+    sdiodrv->req = cmd->mrq;
+    rt_exit_critical();
+
+
+    if (data)
+    {
+        data->bytes_xfered = 0;
+
+        sdio_set_dma(sdio_info->id,data,0);
+        sdio_set_blksize_reg(sdio_info->id, SDIO_DEFAULT_BOUNDARY_ARG,data->blksize);
+        sdio_set_blkcnt_reg(sdio_info->id, data->blks);
+
+        if(data->flags & DATA_DIR_WRITE)
+            readop = 0;
+
+        if(data->blks > 1)
+            multblk = 1;
+
+        if((data->stop != RT_NULL) && multblk)
+        {
+            if(data->stop->cmd_code == MMC_STOP_TRANSMISSION)
+                tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,1,multblk,SDIO_USE_DMA);
+            else
+                tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,0,multblk,SDIO_USE_DMA);
+        }
+        else
+            tmp_cmd = sdio_set_tramode_reg(sdio_info->id,multblk,readop,0,multblk,SDIO_USE_DMA);
+
+    }
+
+    switch (resp_type(cmd))
+    {
+        case RESP_NONE:
+            cmd_flags = MMC_RSP_NONE;
+            break;
+        case RESP_R1:
+            cmd_flags = MMC_RSP_R1;
+            break;
+        case RESP_R2:
+            cmd_flags = MMC_RSP_R2;
+            break;
+        case RESP_R3:
+            cmd_flags = MMC_RSP_R3;
+            break;
+        case RESP_R4:
+            cmd_flags = MMC_RSP_R4;
+            break;
+        case RESP_R5:
+            cmd_flags = MMC_RSP_R5;
+            break;
+        case RESP_R6:
+            cmd_flags = MMC_RSP_R6;
+            break;
+        case RESP_R7:
+            cmd_flags = MMC_RSP_R7;
+            break;
+        case RESP_R1B:
+            cmd_flags = MMC_RSP_R1B;
+            break;
+        default:
+            rt_kprintf("ERROR: %s, unknown cmd type %x\n", __func__, resp_type(cmd));
+            return;
+    }
+
+    tmp_cmd |= cmd->cmd_code;
+
+    ret = sdio_issue_cmd(sdio_info->id, tmp_cmd, cmd->arg, (data != RT_NULL), cmd_flags);
+
+    if(ret != RT_EOK)
+    {
+        rt_kprintf("\n%s, issue cmd timeout!\n",__func__);
+        rt_kprintf("\ntmp_cmd: %d, cmd code: %d, args: 0x%x, resp type: 0x%x, dataflag: 0x%x, cmdflag: 0x%x\n",tmp_cmd, cmd->cmd_code, cmd->arg, resp_type(cmd), (data != RT_NULL),cmd_flags);
+        if(data == RT_NULL)
+            cmd->err = RT_ETIMEOUT;
+
+        return;
+    }
+
+    rt_completion_init(&sdiodrv->completion);
+    ret = rt_completion_wait(&sdiodrv->completion, RT_TICK_PER_SECOND * timeout);
+    if(ret != RT_EOK)
+    {
+        rt_kprintf("\n%s, cmd process timeout!\n",__func__);
+        rt_kprintf("\ntmp_cmd: %d, cmd code: %d, args: 0x%x, resp type: 0x%x, dataflag: 0x%x, cmdflag: 0x%x\n",tmp_cmd, cmd->cmd_code, cmd->arg, resp_type(cmd), (data != RT_NULL),cmd_flags);
+        if(data == RT_NULL)
+            cmd->err = RT_ETIMEOUT;
+
+        return;
+    }
+
+}
+
+
+static void gk_sdio_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+    int ret;
+    rt_uint32_t clkdiv;
+    struct gk_sdio *sdio_drv;
+    struct gk_sdio_info *sdio_info;
+
+    if(!host || !io_cfg)
+        return;
+
+    //rt_kprintf("\nclock: %d, vdd: %d, bus_mode: %d, bus_width: %d\n",io_cfg->clock,io_cfg->vdd,io_cfg->bus_mode,io_cfg->bus_width);
+    sdio_drv = host->private_data;
+    sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    switch (io_cfg->power_mode)
+    {
+        case MMCSD_POWER_OFF:
+            sdio_power_off(sdio_info->id);
+            break;
+        case MMCSD_POWER_UP:
+            break;
+        case MMCSD_POWER_ON:
+            sdio_power_on(sdio_info->id);
+            break;
+        default:
+            break;
+    }
+
+    if (io_cfg->bus_width == MMCSD_BUS_WIDTH_1)
+        sdio_set_host_ctl_width(sdio_info->id,0);
+    else if(io_cfg->bus_width == MMCSD_BUS_WIDTH_4)
+        sdio_set_host_ctl_width(sdio_info->id,1);
+    else if(io_cfg->bus_width == MMCSD_BUS_WIDTH_8)
+    {
+        sdio_set_host_ctl_width(sdio_info->id,0);
+        sdio_set_hostctl8BitMode(sdio_info->id,1);
+    }
+
+    if (io_cfg->vdd)
+        sdio_select_voltage(sdio_info->id);
+
+    if (io_cfg->clock > 25000000) //FIXME:need check
+    {
+#ifdef CODEC_710X
+        sdio_set_host_ctl_speed(sdio_info->id,1);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 0);
+#else
+        sdio_set_host_ctl_speed(sdio_info->id,0);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 1);
+#endif
+    }
+    else
+    {
+        sdio_set_host_ctl_speed(sdio_info->id,0);
+        sdio_clock_onoff(sdio_info->id, 0);
+        sdio_set_clockdiv(sdio_info->id, 1);
+    }
+
+}
+
+static void gk_sdio_enable_sdio_irq(struct rt_mmcsd_host *host,rt_int32_t enable)
+{
+    int ret;
+    struct gk_sdio *sdio_drv;
+    struct gk_sdio_info *sdio_info;
+
+    if(!host)
+        return;
+
+    sdio_drv = host->private_data;
+    sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    //rt_kprintf("\n%s, enable:%d\n", __func__,enable);
+#ifdef CODEC_710X
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+#elif GK7102C
+    GH_SDIO_set_NorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+    GH_SDIO_set_NorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+#elif defined(CODEC_710XS)
+    GH_SDIO_set_TranModeNorIntSigEnReg_CardIntSigEN(sdio_info->id, enable);
+    GH_SDIO_set_BlkSizeNorIntStaEnReg_CardIntStatusEn(sdio_info->id, enable);
+#endif
+
+}
+
+static void gk_sdio_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+    int ret;
+
+    struct gk_sdio *sdio_drv = (struct gk_sdio *)host->private_data;
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)sdio_drv->priv;
+
+    if (!host || !req || !sdio_drv)
+    {
+        rt_kprintf("ERROR: %s, params is NULL\n", __func__);
+        return;
+    }
+
+    if(sdio_info->type != SDIO_DEVICE_TYPE_WIFI)
+    {
+        if (!sdio_get_inserted_flag(sdio_info->id))
+        {
+            if(req->cmd)
+                req->cmd->err = -RT_EIO;
+
+            mmcsd_req_complete(host);
+
+            return;
+        }
+    }
+
+    if(req->cmd)
+        sdio_send_command(sdio_drv, req->cmd);
+
+#if 0
+    if(req->stop && req->stop != req->cmd )
+        sdio_send_command(sdio_drv, req->stop);
+#endif
+
+    rt_enter_critical();
+    sdio_drv->cmd = RT_NULL;
+    sdio_drv->req = RT_NULL;
+    rt_exit_critical();
+
+    mmcsd_req_complete(host);
+
+}
+
+static rt_int32_t gk_sdio_get_card_status(struct rt_mmcsd_host *host)
+{
+    return 0;
+}
+
+
+static const struct rt_mmcsd_host_ops gk_sdio_ops = {
+
+    .request         = gk_sdio_request,
+    .set_iocfg       = gk_sdio_set_iocfg,
+    .get_card_status = gk_sdio_get_card_status,
+    .enable_sdio_irq = gk_sdio_enable_sdio_irq,
+};
+
+int gk_sdio_probe(void *priv_data)
+{
+    struct gk_sdio *sdio_drv;
+    struct rt_mmcsd_host *host;
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)priv_data;
+
+    sdio_drv = (struct gk_sdio *)rt_malloc(sizeof(struct gk_sdio));
+
+    if (!sdio_drv)
+    {
+        rt_kprintf("ERROR: %s,line:%d, failed to malloc host\n", __func__,__LINE__);
+        return -RT_ENOMEM;
+    }
+
+    rt_memset(sdio_drv, 0, sizeof(struct gk_sdio));
+
+    host = mmcsd_alloc_host();
+    if (!host)
+    {
+        rt_kprintf("ERROR: %s,LINE:%d failed to malloc host\n", __func__,__LINE__);
+        rt_free((void *)sdio_drv);
+        return -RT_ENOMEM;
+    }
+
+    host->ops       = &gk_sdio_ops;
+    host->freq_min  = 400*1000; ///FIXME:need check
+    host->freq_max  = 50*1000000; ///FIXME:need check
+    host->valid_ocr = VDD_32_33 | VDD_33_34 | VDD_165_195;
+
+    host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
+    host->max_seg_size  = SDIO_DEFAULT_BOUNDARY_SIZE;
+    host->max_blk_size  = 1024;
+    host->max_blk_count = 65535;
+    host->private_data  = sdio_drv;
+
+    sdio_drv->host = host;
+    sdio_drv->priv = sdio_info;
+
+    sdio_init(sdio_info->id);
+    sdio_reset(sdio_info->id);
+
+    sdioInstancePtr[sdio_info->id] = sdio_drv;
+
+    mmcsd_change(host);
+
+    return 0;
+}
+
+int gk_sdio_exit(void *priv_data)
+{
+    struct gk_sdio_info *sdio_info = (struct gk_sdio_info *)priv_data;
+    rt_int8_t i;
+
+    if(!sdio_info)
+        return RT_EINVAL;
+
+    if(!sdioInstancePtr[sdio_info->id])
+        return RT_EINVAL;
+
+    i = (sdio_info->id == 0)? 0:2;
+
+    GD_INT_Close(&inthandleArray[i]);
+    GD_INT_Close(&inthandleArray[i+1]);
+
+    rt_completion_done(&(sdioInstancePtr[sdio_info->id]->completion));
+
+    if(sdioInstancePtr[sdio_info->id]->host)
+        mmcsd_free_host(sdioInstancePtr[sdio_info->id]->host);
+
+    rt_free(sdioInstancePtr[sdio_info->id]);
+    sdioInstancePtr[sdio_info->id] = RT_NULL;
+
+    return 0;
+}
+
+struct gk_platform_driver sdio_driver_ops = {
+
+    .name = "gk-sdio", .probe = gk_sdio_probe, .remove = gk_sdio_exit,
+
+};
+
+#if 0
+#include "adi_types.h"
+#include "adi_gpio.h"
+
+static GADI_SYS_HandleT resetHandle = NULL;
+
+void gk_sdio_wifi_reset_gpio_init(GADI_U8 num_gpio)
+{
+    rt_int32_t error;
+    GADI_GPIO_OpenParam resetParam;
+
+    if(num_gpio == 0)
+    {
+        resetHandle = NULL;
+        return;
+    }
+
+    resetParam.active_low = 0;
+    resetParam.direction = 1;
+    resetParam.num_gpio = num_gpio;
+    resetParam.value = 1;
+
+    rt_kprintf("wifi reset num_gpio %d !\n", num_gpio);
+
+    if(resetHandle == NULL)
+    {
+        resetHandle = gadi_gpio_open(&error, &resetParam);
+        if(resetHandle == NULL)
+        {
+            rt_kprintf("open sensor reset GPIO failed %d !\n", error);
+            return;
+        }
+    }
+}
+
+int gk_sdio_wifi_hw_reset(void)
+{
+
+    rt_int32_t error;
+
+    if(resetHandle == NULL)
+    {
+        return 1;
+    }
+
+    error = gadi_gpio_clear(resetHandle);
+    rt_thread_delay(20);
+    error = gadi_gpio_set(resetHandle);
+    rt_thread_delay(20);
+    if(error != 0)
+    {
+        rt_kprintf("wifi reset failed %d !\n", error);
+        return -1;
+    }
+
+    return 0;
+
+}
+#endif
+
+void rt_hw_sdio_init(void)
+{
+    GH_SDIO_init();
+    gk_platform_driver_init(&sdio_driver_ops);
+}
+

+ 41 - 0
bsp/gkipc/drivers/drv_sdio.h

@@ -0,0 +1,41 @@
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef enum
+ {
+    SDIO_DEVICE_TYPE_NORMAL = 0,     //!< Normal transfer type for SD/SDHC/MMC cards (default)
+    SDIO_DEVICE_TYPE_WIFI,
+    
+} SDIO_DEVICE_TYPE_E;
+
+
+struct gk_sdio_info
+{
+    rt_uint32_t id;
+	SDIO_DEVICE_TYPE_E type;
+};
+
+struct gk_sdio
+{
+    struct rt_mmcsd_host *host;
+    struct rt_mmcsd_req  *req;
+    struct rt_mmcsd_cmd  *cmd;
+	
+    struct rt_completion completion;
+    void *priv;
+};
+void rt_hw_sdio_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
+

+ 317 - 0
bsp/gkipc/drivers/drv_ssi.c

@@ -0,0 +1,317 @@
+#include <rtdevice.h>
+#include "gtypes.h"
+#include "gd_spi.h"
+#include "drv_ssi.h"
+#include "platform.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+
+/*---------------------------------------------------------------------------*/
+/* local data types                                                          */
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------------------------------------*/
+/* local  functions                                                          */
+/*---------------------------------------------------------------------------*/
+static void *gk_get_spi_dev_pri_data(struct rt_spi_device *device)
+{
+    return device->parent.user_data;
+}
+
+static rt_err_t gk_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *configuration)
+{
+	struct gk_spi_slave_info *spi_slave;
+	struct gk_spi_controller *spi_control;
+	GD_SPI_OPEN_PARAMS_S openParamsP;
+	rt_uint32_t spi_hz;
+	rt_int32_t	ret;
+	rt_uint8_t	data_width = 8,polarity;
+
+	if(!device || !configuration)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return RT_ERROR;
+	}
+
+	spi_slave   = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
+	spi_control = spi_slave->control;
+
+	rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
+
+	if(spi_slave->spihandle > 0)
+	{
+		GD_SPI_Close(&spi_slave->spihandle);
+		spi_slave->spihandle = -1;
+	}
+
+	 openParamsP.spi 	    = spi_control->id;
+	 openParamsP.slave      = spi_slave->id;
+	 openParamsP.csgpio     = spi_slave->cs_pin;
+	 openParamsP.used_irq   = 1;
+
+	 if (configuration->max_hz > GD_SPI_FREQ_81M)
+		 spi_hz = GD_SPI_FREQ_81M;
+	 else
+		 spi_hz = configuration->max_hz;
+
+	 openParamsP.baudrate = spi_hz;
+
+	 /* CPOL */
+	 if (configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE3;
+	 }
+	 else if(configuration->mode & RT_SPI_CPOL && !configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE2;
+	 }
+	 else if(!configuration->mode & RT_SPI_CPOL && configuration->mode & RT_SPI_CPHA)
+	 {
+	 	polarity = SPI_POLARITY_MODE1;
+	 }
+	 else
+		 polarity = SPI_POLARITY_MODE0;
+
+	 openParamsP.polarity = polarity;
+
+	 ret = GD_SPI_Open(&openParamsP,&(spi_slave->spihandle));
+	 if(ret != GD_OK)
+	 {
+	     rt_kprintf("GD_SPI_Open failed!\n");
+		 rt_sem_release(&spi_control->xfer_lock);
+	     return RT_ERROR;
+	 }
+
+	 /* data_width */
+	 if (configuration->data_width <= 8)
+	 {
+	 	data_width = 8;
+	 }
+	 else if (configuration->data_width <= 16)
+	 {
+
+	 	data_width = 16;
+	 }
+
+	 ret = GD_SPI_SetDatFormat(spi_slave->spihandle, data_width);;
+	 if(ret != GD_OK)
+	 {
+	     rt_kprintf("GD_SPI_SetDatFormat failed!\n");
+		 rt_sem_release(&spi_control->xfer_lock);
+	     return RT_ERROR;
+	 }
+
+	 rt_sem_release(&spi_control->xfer_lock);
+
+	return RT_EOK;
+}
+
+static rt_uint32_t gk_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
+{
+	struct gk_spi_slave_info *spi_slave;
+	struct gk_spi_controller *spi_control;
+	GERR ret = GD_OK;
+
+	if(!device || !message)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	spi_slave   = (struct gk_spi_slave_info *)gk_get_spi_dev_pri_data(device);
+
+	if(!spi_slave)
+	{
+		rt_kprintf("%s,%d,param wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	spi_control = spi_slave->control;
+
+	if(spi_slave->spihandle < 0)
+	{
+		rt_kprintf("%s,%d,spi channel not configured!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	if(!message)
+	{
+		rt_kprintf("%s,%d,params wrong!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+
+	rt_sem_take(&spi_control->xfer_lock, RT_WAITING_FOREVER);
+
+	if(message->cs_take)
+		GD_SPI_GetDevice(spi_slave->spihandle);
+
+	if(message->recv_buf && message->send_buf)
+    	ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length,
+    	(rt_uint8_t *)message->recv_buf,message->length);
+	else if(message->send_buf && !message->recv_buf)
+		ret = GD_SPI_WriteBytes(spi_slave->spihandle,(rt_uint8_t *)message->send_buf,message->length);
+	else if(!message->send_buf && message->recv_buf)
+		ret = GD_SPI_WriteThenReadBytes(spi_slave->spihandle,NULL,0,(rt_uint8_t *)message->recv_buf,message->length);
+
+
+	if(message->cs_release)
+		GD_SPI_ReleaseDevice(spi_slave->spihandle);
+
+	rt_sem_release(&spi_control->xfer_lock);
+
+
+	if(ret != GD_OK)
+	{
+		rt_kprintf("%s,%d,transfer error!\n",__FUNCTION__,__LINE__);
+		return 0;
+	}
+	else
+	{
+		return message->length;
+	}
+
+}
+
+static struct rt_spi_ops gk_spi_ops = {
+
+    .configure = gk_spi_configure, .xfer = gk_spi_xfer,
+
+};
+
+int gk_spi_probe(void *priv_data)
+{
+	int ret,i;
+    char spi_dev_name[20]  = {0};
+    char spi_bus_name[20]  = {0};
+    char spi_lock_name[20] = {0};
+    struct gk_spi_controller *spi_control;
+	struct gk_spi_controller_data *spi_controller_data = (struct gk_spi_controller_data *)priv_data;
+    struct gk_spi_slave_info **control_slave;
+    struct gk_spi_slave_info *spi_slave,*next_slave;
+
+	if (!spi_controller_data)
+	{
+		rt_kprintf("%s,%d input param wrong!\n",__FUNCTION__,__LINE__);
+		return -1;
+	}
+
+    spi_control = (struct gk_spi_controller *)rt_malloc(sizeof(struct gk_spi_controller));
+    if (!spi_control)
+    {
+        rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
+        return -1;
+    }
+
+    rt_memset(spi_control, 0, sizeof(struct gk_spi_controller));
+
+	spi_control->id = spi_controller_data->id;
+
+    rt_sprintf(spi_lock_name, "%s%d", "spi_lock", spi_control->id);
+    rt_sprintf(spi_bus_name, "%s%d", "spi_bus", spi_control->id);
+
+    rt_sem_init(&spi_control->xfer_lock, spi_lock_name, 1, RT_IPC_FLAG_FIFO);
+
+    ret = rt_spi_bus_register(&spi_control->spi_bus, spi_bus_name, &gk_spi_ops);
+
+	control_slave = &spi_control->spi_slave;
+
+    for (i = 0; i < spi_controller_data->total_slave; i++)
+    {
+        spi_slave = (struct gk_spi_slave_info *)rt_malloc(sizeof(struct gk_spi_slave_info));
+        if (!spi_slave)
+        {
+			rt_kprintf("%s,%d malloc failed!\n",__FUNCTION__,__LINE__);
+            goto exit;
+        }
+        rt_memset(spi_slave, 0, sizeof(struct gk_spi_slave_info));
+
+        spi_slave->id      = i;
+        spi_slave->control = spi_control;
+        spi_slave->cs_pin  = spi_controller_data->slave_cs_pin[i];
+		spi_slave->spihandle = -1;
+
+        rt_sprintf(spi_dev_name, "%s%d%s%d", "ssi", spi_control->id, "_", spi_slave->id);
+
+        *control_slave = spi_slave;
+        control_slave  = &spi_slave->next;
+
+        ret = rt_spi_bus_attach_device(&spi_slave->spi_device, spi_dev_name,spi_bus_name, spi_slave);
+        if (ret != RT_EOK)
+        {
+            rt_kprintf("register dev to bus failed...\n");
+            goto exit;
+        }
+    }
+
+	spi_controller_data->control = spi_control;
+
+	GD_SPI_Init();
+
+    return RT_EOK;
+
+exit:
+
+	spi_slave = spi_control->spi_slave;
+	while (spi_slave != RT_NULL)
+	{
+		next_slave = spi_slave->next;
+		rt_free(spi_slave);
+		spi_slave = next_slave;
+	}
+
+    rt_sem_detach(&spi_control->xfer_lock);
+
+    rt_free(spi_control);
+
+	return RT_ERROR;
+}
+
+int gk_spi_exit(void *priv_data)
+{
+
+    struct gk_spi_controller *spi_control;
+    struct gk_spi_controller_data *plat_data;
+    struct gk_spi_slave_info *spi_slave;
+    struct gk_spi_slave_info *next_slave;
+
+    plat_data   = (struct gk_spi_controller_data *)priv_data;
+    spi_control = plat_data->control;
+    spi_slave   = spi_control->spi_slave;
+
+    while (spi_slave != RT_NULL)
+    {
+        next_slave = spi_slave->next;
+        rt_free(spi_slave);
+        spi_slave = next_slave;
+    }
+
+    rt_sem_detach(&spi_control->xfer_lock);
+
+    rt_free(spi_control);
+
+    return RT_EOK;
+}
+
+struct gk_platform_driver gk_spi_driver_ops = {
+
+    .name = "spi", .probe = gk_spi_probe, .remove = gk_spi_exit,
+
+};
+
+void rt_hw_spi_init(void)
+{
+
+	gk_platform_driver_init(&gk_spi_driver_ops);
+}
+

+ 43 - 0
bsp/gkipc/drivers/drv_ssi.h

@@ -0,0 +1,43 @@
+#ifndef SSI_H_
+#define SSI_H_
+
+#include "gtypes.h"
+#include <rtdevice.h>
+
+#define MAX_SLAVE_DEVICE (2)
+
+struct gk_spi_slave_info
+{
+    rt_uint32_t id;	
+	rt_uint32_t cs_pin;
+	GD_HANDLE spihandle;
+	
+    struct rt_spi_device spi_device;
+    struct gk_spi_controller *control;
+    struct gk_spi_slave_info *next;
+};
+
+struct gk_spi_controller;
+struct gk_spi_controller_data
+{
+    rt_uint32_t id;
+    rt_uint32_t total_slave;
+    rt_uint32_t slave_cs_pin[MAX_SLAVE_DEVICE];
+	struct gk_spi_controller *control;
+};
+
+struct gk_spi_controller
+{
+    rt_uint32_t id;
+    struct rt_spi_bus spi_bus;
+    struct rt_spi_message *current_message;
+    struct rt_completion transfer_completion;
+    struct rt_semaphore xfer_lock;
+	
+	struct gk_spi_slave_info *spi_slave;
+
+};
+
+void rt_hw_spi_init(void);
+
+#endif

+ 474 - 0
bsp/gkipc/drivers/drv_uart.c

@@ -0,0 +1,474 @@
+#include <rtdevice.h>
+
+#include "gtypes.h"
+#include "gh_uart.h"
+#include "gh_debug_rct.h"
+#include "gd_uart.h"
+#include "gd_int.h"
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+
+#define UART_IRQ_CLEAR_ALL   0x3 /* IRQ CLR Register: rx_IRQ, rx_parity_IRQ  */
+#define UART_RISING_TXE_RXE  0x3 /* for UART_control register:               */
+                                 /* clock edge polarity = rising,            */
+                                 /* TX = enable, RX = enable                 */
+
+/* UART[x]_FC_REG */
+#define UART_FC_RX_ONECHAR              0x0 /* RCVR_Trigger: FIFO has 1 char */
+#define UART_FC_RX_QUARTER_FULL         0x1 /* RCVR_Trigger: FIFO is one-fourth to full */
+#define UART_FC_RX_HALF_FULL            0x2 /* RCVR_Trigger: FIFO is half to full */
+#define UART_FC_RX_2_TO_FULL            0x3 /* RCVR_Trigger: FIFO is 2 char to full */
+#define UART_FC_TX_EMPTY                0x0 /* TX_Empty_Trigger:  FIFO is empty */
+#define UART_FC_TX_2_IN_FIFO            0x1 /* TX_Empty_Trigger:  FIFO has 2 char */
+#define UART_FC_TX_QUATER_IN_FIFO       0x2 /* TX_Empty_Trigger:  FIFO is one-fourth to full */
+#define UART_FC_TX_HALF_IN_FIFO         0x3 /* TX_Empty_Trigger:  FIFO is half to full */
+
+/* UART[x]_II_REG */
+#define UART_II_MODEM_STATUS_CHANGED    0x0
+#define UART_II_NO_INT_PENDING          0x1
+#define UART_II_THR_EMPTY               0x2
+#define UART_II_RCV_DATA_AVAIL          0x4
+#define UART_II_RCV_STATUS              0x6
+#define UART_II_CHAR_TIMEOUT            0xc
+
+#define MAX_UART_CNT    (3)
+
+/*---------------------------------------------------------------------------*/
+/* local data types                                                          */
+/*---------------------------------------------------------------------------*/
+
+struct gk_uart
+{
+    u8 index;
+};
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+
+static struct gk_uart uart[MAX_UART_CNT] =
+{
+    {0},{1},{2}
+};
+
+static GD_HANDLE intHandle[MAX_UART_CNT];
+static struct rt_serial_device serial[MAX_UART_CNT];
+
+/*---------------------------------------------------------------------------*/
+/* local  functions                                                          */
+/*---------------------------------------------------------------------------*/
+
+static void uartSetBaudrate(U32 index, U32 baudRate)
+{
+    U32 brdi;
+    GH_PLL_set_SCALER_UART(0x01);
+    brdi = (48000000/2) * 10 / baudRate / 16;
+    if (brdi % 10 >= 5)
+        brdi = (brdi / 10) + 1;
+    else
+        brdi = (brdi / 10);
+    GH_UART_set_LCR_dlab(index, 1);
+    GH_UART_set_DLL_BaudDivint_L(index, brdi & 0xff);
+    GH_UART_set_DLH_BaudDivint_H(index, (brdi >> 8) & 0xff);
+    GH_UART_set_LCR_dlab(index, 0);
+}
+
+static void uartSetDataBits(U32 index, U32 dataBits)
+{
+    U32 data_bits = dataBits;
+    // 0 = use 5 data bits
+    // 1 = use 6 data bits
+    // 2 = use 7 data bits
+    // 3 = use 8 data bits
+    //data_bits -= GD_UART_5_DATATBITS;
+
+    if(GH_UART_get_LCR_cls(index) != data_bits)
+    {
+         GH_UART_set_LCR_cls(index, data_bits);
+    }
+}
+
+static void uartSetStopBits(U32 index, U32 stopBits)
+{
+    // 0 = use 1 stop bit
+    // 1 = use 2 stop bits
+    if(GH_UART_get_LCR_stop(index) != stopBits)
+    {
+         GH_UART_set_LCR_stop(index, stopBits);
+    }
+}
+
+static void uartSetParity(U32 index, U32 parity)
+{
+    switch(parity)
+    {
+    case GD_UART_NO_PARITY:
+        if(GH_UART_get_LCR_pen(index))
+        {
+            GH_UART_set_LCR_pen(index, 0);
+        }
+        break;
+
+    case GD_UART_ODD_PARITY:
+        if(!GH_UART_get_LCR_pen(index))
+        {
+            GH_UART_set_LCR_pen(index, 1);
+        }
+        if(GH_UART_get_LCR_eps(index))
+        {
+            GH_UART_set_LCR_eps(index, 0);
+        }
+        break;
+
+    case GD_UART_EVEN_PARITY:
+        if(!GH_UART_get_LCR_pen(index))
+        {
+            GH_UART_set_LCR_pen(index, 1);
+        }
+        if(!GH_UART_get_LCR_eps(index))
+        {
+            GH_UART_set_LCR_eps(index, 1);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+static void uartSetFlowControl(U32 index, U32 flowCtrl)
+{
+    if(index == 0)
+    {
+        // In UART0, only the Loopback bit is used and flow control is not supported.
+        // In UART1, all the bits are used.
+        if((flowCtrl == 0) || (flowCtrl == 0x10))
+        {
+            if(GH_UART_get_MCR(index) != flowCtrl)
+            {
+                GH_UART_set_MCR(index, flowCtrl);
+            }
+        }
+        return;
+    }
+    if(GH_UART_get_MCR(index) != flowCtrl)
+    {
+        GH_UART_set_MCR(index, flowCtrl);
+    }
+}
+
+static void uartISR(void)
+{
+    U8 interruptID;
+    interruptID = GH_UART_get_IIR_interrupt_id(0);
+
+    switch (interruptID)
+    {
+        case UART_II_MODEM_STATUS_CHANGED:
+        case UART_II_NO_INT_PENDING:
+            break;
+        case UART_II_THR_EMPTY:
+            rt_hw_serial_isr(&serial[0], RT_SERIAL_EVENT_TX_DONE);
+            break;
+        case UART_II_RCV_DATA_AVAIL:
+        case UART_II_RCV_STATUS:
+            rt_hw_serial_isr(&serial[0], RT_SERIAL_EVENT_RX_IND);
+            break;
+        case UART_II_CHAR_TIMEOUT:
+            GH_UART_get_RBR_Data(0);
+            rt_hw_serial_isr(&serial[0], RT_SERIAL_EVENT_RX_TIMEOUT);
+            break;
+        default:
+            break;
+    }
+
+}
+static void uartISR1(void)
+{
+    U8 interruptID;
+    interruptID = GH_UART_get_IIR_interrupt_id(1);
+
+    switch (interruptID)
+    {
+        case UART_II_MODEM_STATUS_CHANGED:
+        case UART_II_NO_INT_PENDING:
+            break;
+        case UART_II_THR_EMPTY:
+            rt_hw_serial_isr(&serial[1], RT_SERIAL_EVENT_TX_DONE);
+            break;
+        case UART_II_RCV_DATA_AVAIL:
+        case UART_II_RCV_STATUS:
+            rt_hw_serial_isr(&serial[1], RT_SERIAL_EVENT_RX_IND);
+            break;
+        case UART_II_CHAR_TIMEOUT:
+            GH_UART_get_RBR_Data(1);
+            rt_hw_serial_isr(&serial[1], RT_SERIAL_EVENT_RX_TIMEOUT);
+            break;
+        default:
+            break;
+    }
+
+}
+
+static void uartISR2(void)
+{
+    U8 interruptID;
+    interruptID = GH_UART_get_IIR_interrupt_id(2);
+
+    switch (interruptID)
+    {
+        case UART_II_MODEM_STATUS_CHANGED:
+        case UART_II_NO_INT_PENDING:
+            break;
+        case UART_II_THR_EMPTY:
+            rt_hw_serial_isr(&serial[2], RT_SERIAL_EVENT_TX_DONE);
+            break;
+        case UART_II_RCV_DATA_AVAIL:
+        case UART_II_RCV_STATUS:
+            rt_hw_serial_isr(&serial[2], RT_SERIAL_EVENT_RX_IND);
+            break;
+        case UART_II_CHAR_TIMEOUT:
+            GH_UART_get_RBR_Data(2);
+            rt_hw_serial_isr(&serial[2], RT_SERIAL_EVENT_RX_TIMEOUT);
+            break;
+        default:
+            break;
+    }
+
+}
+
+
+static GERR uartSetIntMode(U8 channel)
+{
+
+    GD_UART_STATE_MACHINE_S* uart_handle_ptr = NULL;
+    GD_INT_OPEN_PARAMS_S intParams;
+    GERR                 ret = GD_OK;
+
+    intParams.sensitivity    = GD_INT_LEVEL_HIGH;    //hhl note: check this value.
+    intParams.active         = GD_INT_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+
+    if(channel == 0)
+    {
+        intParams.type           = (S8)GD_INT_UART_IRQ;
+        intParams.isrFct.lowPrio = uartISR;
+        ret = GD_INT_Open(&intParams, &intHandle[0]);
+    }
+    else if(channel == 1)
+    {
+        intParams.type           = (S8)GD_INT_UART1_IRQ;
+        intParams.isrFct.lowPrio = uartISR1;
+        ret = GD_INT_Open(&intParams, &intHandle[1]);
+    }
+    else
+    {
+        intParams.type           = (S8)GD_INT_UART2_IRQ;
+        intParams.isrFct.lowPrio = uartISR2;
+        ret = GD_INT_Open(&intParams, &intHandle[2]);
+    }
+
+    return ret;
+}
+
+/**
+* UART device in RT-Thread
+*/
+static rt_err_t gk_uart_configure(struct rt_serial_device *serial,
+                                struct serial_configure *cfg)
+{
+    int div;
+    GD_UART_DATABITS_E data_mode;
+    GD_UART_STOPBITS_E stop_mode;
+    GD_UART_PARITY_E parity_mode;
+    struct gk_uart *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    RT_ASSERT(cfg != RT_NULL);
+    uart = (struct gk_uart *)serial->parent.user_data;
+
+    switch (cfg->data_bits)
+    {
+        case DATA_BITS_8:
+            data_mode = GD_UART_8_DATATBITS;
+            break;
+        case DATA_BITS_7:
+            data_mode = GD_UART_7_DATATBITS;
+            break;
+        case DATA_BITS_6:
+            data_mode = GD_UART_6_DATATBITS;
+            break;
+        case DATA_BITS_5:
+            data_mode = GD_UART_5_DATATBITS;
+            break;
+        default:
+            data_mode = GD_UART_8_DATATBITS;
+            break;
+    }
+
+    switch (cfg->stop_bits)
+    {
+        case STOP_BITS_2:
+            stop_mode = GD_UART_20_STOPBITS;//UART_STOP_BIT2;
+            break;
+        case STOP_BITS_1:
+        default:
+            stop_mode = GD_UART_10_STOPBITS;
+            break;
+    }
+
+    switch (cfg->parity)
+    {
+        case PARITY_ODD:
+            parity_mode = GD_UART_ODD_PARITY;
+            break;
+        case PARITY_EVEN:
+            parity_mode = GD_UART_EVEN_PARITY;
+            break;
+        case PARITY_NONE:
+        default:
+            parity_mode = GD_UART_NO_PARITY;
+            break;
+    }
+
+    uartSetBaudrate(uart->index,cfg->baud_rate);
+    uartSetDataBits(uart->index,   data_mode);
+    uartSetParity(uart->index,     parity_mode);
+    uartSetStopBits(uart->index,   stop_mode);
+    uartSetFlowControl(uart->index,0);
+
+    return RT_EOK;
+}
+
+#define RT_DEVICE_CTRL_GET_CONFIG 0xFF
+
+static rt_err_t gk_uart_control(struct rt_serial_device *serial,
+                              int cmd, void *arg)
+{
+    struct gk_uart* uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct gk_uart *)serial->parent.user_data;
+
+    switch (cmd)
+    {
+        case RT_DEVICE_CTRL_CLR_INT:
+            /* disable rx irq */
+            GD_INT_Enable(&intHandle[uart->index],0);
+
+            GH_UART_set_IER_erbfi(uart->index, 0);
+
+            break;
+        case RT_DEVICE_CTRL_SET_INT:
+            /* enable rx irq */
+
+            GH_UART_set_FCR_FIFO_Enable(uart->index, 1);
+            GH_UART_set_FCR_RCVR_Trigger(uart->index, UART_FC_RX_ONECHAR);
+            GH_UART_set_FCR_TX_Empty_Trigger(uart->index, UART_FC_TX_EMPTY);
+            GH_UART_set_FCR_XMIT_FIFO_Reset(uart->index, 1);
+            GH_UART_set_FCR_RCVR_FIFO_Reset(uart->index, 1);
+            GH_UART_set_IER_etbei(uart->index, 0); //Turn off THRE interrupt
+
+            uartSetIntMode(uart->index);
+
+            GD_INT_Enable(&intHandle[uart->index],1);
+
+            GH_UART_set_IER_erbfi(uart->index,1);
+            GH_UART_set_IER_elsi(uart->index,1);
+
+            break;
+
+        case RT_DEVICE_CTRL_GET_CONFIG:
+            if(!arg)
+            {
+                rt_kprintf("%s,line=%d,param is NULL!\n",__FUNCTION__,__LINE__);
+                return RT_ERROR;
+            }
+
+            *((struct serial_configure *)arg) = serial->config;
+
+            break;
+
+        default:
+            break;
+    }
+
+    return RT_EOK;
+}
+
+static int gk_uart_putc(struct rt_serial_device *serial, char c)
+{
+    struct gk_uart *uart = serial->parent.user_data;
+    unsigned int ret;
+    ret = GH_UART_get_LSR_temt(uart->index);
+
+    if(serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX){
+
+        GH_UART_set_THR_Data(uart->index, c);
+        if (GH_UART_get_IER_etbei(uart->index) == 0)
+        {
+            GH_UART_set_IER_etbei(uart->index, 1); //Turn on THRE interrupt
+        }
+        return 1;
+    }
+    else
+    {
+        while(!GH_UART_get_LSR_temt(uart->index));
+        GH_UART_set_THR_Data(uart->index, c);
+        return 1;
+    }
+
+}
+
+static int gk_uart_getc(struct rt_serial_device *serial)
+{
+    struct gk_uart *uart = serial->parent.user_data;
+
+    if(!GH_UART_get_LSR_dr(uart->index))
+        return -1;
+
+    return GH_UART_get_RBR_Data(uart->index);
+
+}
+
+static const struct rt_uart_ops gk_uart_ops =
+{
+    gk_uart_configure,
+    gk_uart_control,
+    gk_uart_putc,
+    gk_uart_getc,
+};
+
+/**
+ * This function will handle init uart
+ */
+void rt_hw_uart_init(void)
+{
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+    int i;
+    char devname[6];
+
+    for(i=0; i<MAX_UART_CNT; i++)
+    {
+        serial[i].ops = &gk_uart_ops;
+        serial[i].config = config;
+
+        rt_sprintf(devname,"uart%d",i);
+
+        rt_hw_serial_register(&serial[i], devname,
+                RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_STREAM ,
+                &uart[i]);
+    }
+}
+
+
+int GM_Printf(const char *__format, ...)
+{
+    rt_kprintf(__format);
+
+    return 0;
+}
+
+

+ 7 - 0
bsp/gkipc/drivers/drv_uart.h

@@ -0,0 +1,7 @@
+#ifndef UART_H_
+#define UART_H_
+
+void rt_hw_uart_init(void);
+
+
+#endif

+ 239 - 0
bsp/gkipc/drivers/drv_wdt.c

@@ -0,0 +1,239 @@
+/*
+ * File      : drv_wdt.c
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#include "drv_wdt.h"
+
+#include <rtdef.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/watchdog.h>
+
+#include "gtypes.h"
+#include "gd_wdog.h"
+#include "gd_timer.h"
+#include "platform.h"
+
+
+typedef enum
+{
+    RESTENABLE      = 0x4,
+    INTERRUPTENABLE = 0x2,
+}wdt_enable_mode;
+
+static rt_uint32_t heartbeat = 0;
+
+static rt_err_t gk_wdt_start(int mode)
+{
+    rt_err_t ret = RT_EOK;
+    wdt_enable_mode wdt_mode = RESTENABLE;
+
+    ret = GD_Wdog_Disable();
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("GD_Wdog_Disable error!\n");
+        return RT_ERROR;
+    }
+
+    if ((mode == RESTENABLE) || (mode == INTERRUPTENABLE))
+    {
+        wdt_mode = mode;
+    }
+
+    ret = GD_Wdog_Enable(wdt_mode);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("GD_Wdog_Enable error!\n");
+        return RT_ERROR;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_wdt_keepalive(void)
+{
+    rt_err_t ret = RT_EOK;
+
+    ret = GD_Wdog_ClrTimeout();
+    if (ret != GD_OK)
+    {
+        rt_kprintf("GD_Wdog_ClrTimeout error!\n");
+        return RT_ERROR;
+    }
+
+    return ret;
+}
+
+static rt_uint32_t gk_wdt_get_timeleft(void)
+{
+    GERR index = GD_OK;
+    rt_uint32_t second  = 0;
+
+    index = GD_Wdog_GetValue();
+    if (index < GD_OK )
+    {
+        rt_kprintf("GD_Wdog_GetValue error!\n");
+        return RT_ERROR;
+    }
+
+    second = index/GD_GET_APB_ClkHz();
+
+    return second;
+}
+
+static rt_err_t gk_wdt_set_timeout(rt_uint32_t second)
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t index = 0;
+
+    index = second * GD_GET_APB_ClkHz();
+    ret = GD_Wdog_LoadValue(index);
+    if (ret != GD_OK)
+    {
+        rt_kprintf("GD_Wdog_LoadValue error!\n");
+        return RT_ERROR;
+    }
+
+    return ret;
+}
+
+static rt_err_t gk_watchdog_init(rt_watchdog_t *wdt)
+{
+    struct wdt_driver *wdt_drv = wdt->parent.user_data;
+    if (wdt_drv->in_use) return -RT_EBUSY;
+
+    GD_Wdog_Init();
+
+    return RT_EOK;
+}
+
+static rt_err_t gk_watchdog_ctrl(rt_watchdog_t *wdt, int cmd, void *arg)
+{
+    rt_uint32_t val;
+    int mode;
+
+    switch (cmd)
+    {
+        case RT_DEVICE_CTRL_WDT_START:
+            mode = *((int *)(arg));
+            gk_wdt_start(mode);
+            break;
+
+        case RT_DEVICE_CTRL_WDT_STOP:
+            GD_Wdog_Disable();
+            break;
+
+        case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+            gk_wdt_keepalive();
+            break;
+
+        case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+            heartbeat = *((rt_uint32_t *)(arg));
+            gk_wdt_set_timeout(heartbeat);
+            break;
+
+        case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+            arg = &heartbeat;
+            break;
+
+        case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
+            val = gk_wdt_get_timeleft();
+            arg = &val;
+            break;
+
+        default:
+            return -RT_EIO;
+    }
+    return RT_EOK;
+}
+
+
+struct rt_watchdog_ops gk_watchdog_ops = {
+    .init = &gk_watchdog_init, .control = &gk_watchdog_ctrl,
+};
+
+int gk_wdt_probe(void *priv_data)
+{
+    rt_watchdog_t *wdt_dev;
+    struct wdt_driver *wdt_drv;
+
+    wdt_drv = (struct wdt_driver *)rt_malloc(sizeof(struct wdt_driver));
+    rt_memset(wdt_drv, 0, sizeof(struct wdt_driver));
+
+    wdt_dev = (rt_watchdog_t *)rt_malloc(sizeof(rt_watchdog_t));
+
+    if (wdt_dev == RT_NULL)
+    {
+        rt_kprintf("ERROR: %s rt_watchdog_t malloc failed\n", __func__);
+    }
+
+    wdt_dev->ops = &gk_watchdog_ops;
+
+    rt_hw_watchdog_register(wdt_dev, "gk_wdt", RT_DEVICE_OFLAG_RDWR, wdt_drv);
+
+    return 0;
+}
+
+int gk_wdt_exit(void *priv_data) { return 0; }
+struct gk_platform_driver wdt_driver_ops = {
+    .name = "wdt", .probe = gk_wdt_probe, .remove = gk_wdt_exit,
+};
+
+void rt_hw_wdt_init(void)
+{
+	gk_platform_driver_init(&wdt_driver_ops);
+}
+
+void gk_wdt_test(int timeout, int mode)
+{
+    rt_device_t wdt_dev;
+
+    wdt_dev = rt_device_find("gk_wdt");
+    if (!wdt_dev)
+    {
+        rt_kprintf("cann't find the wdt dev\n");
+    }
+
+    rt_device_open(wdt_dev, 0);
+
+    rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
+    rt_device_control(wdt_dev, RT_DEVICE_CTRL_WDT_START, &mode);
+
+    rt_kprintf("system shall reboot in %d seconds.\n", timeout);
+
+    for (; timeout > 0; timeout--)
+    {
+        rt_kprintf("kicked %d\n", timeout);
+        rt_thread_delay(RT_TICK_PER_SECOND);
+    }
+}
+
+#ifdef RT_USING_WDT
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+FINSH_FUNCTION_EXPORT(gk_wdt_test, enable wdt);
+#endif
+#endif

+ 40 - 0
bsp/gkipc/drivers/drv_wdt.h

@@ -0,0 +1,40 @@
+/*
+ * File      : wdt.h
+ * This file is part of GK710X BSP for RT-Thread distribution.
+ *
+ * Copyright (c) 2017 GOKE Microelectronics Co., Ltd.
+ * All rights reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *  Visit http://www.goke.com to get contact with Goke.
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ */
+
+#ifndef WDT_H_
+#define WDT_H_
+
+struct wdt_driver
+{
+    unsigned long in_use;
+
+    void* priv;
+};
+
+void rt_hw_wdt_init(void);
+
+#endif /* WDT_H_ */

+ 331 - 0
bsp/gkipc/gk7102c_evb_sc1135_config

@@ -0,0 +1,331 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=32
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+# CONFIG_RT_THREAD_PRIORITY_32 is not set
+CONFIG_RT_THREAD_PRIORITY_256=y
+CONFIG_RT_THREAD_PRIORITY_MAX=256
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_DEBUG=y
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_DEBUG_INIT=0
+CONFIG_RT_DEBUG_THREAD=0
+CONFIG_RT_USING_HOOK=y
+CONFIG_IDLE_THREAD_STACK_SIZE=512
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=10240
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+# CONFIG_RT_USING_SIGNALS is not set
+
+#
+# Memory Management
+#
+# CONFIG_RT_USING_MEMPOOL is not set
+CONFIG_RT_USING_MEMHEAP=y
+# CONFIG_RT_USING_NOHEAP is not set
+CONFIG_RT_USING_SMALL_MEM=y
+# CONFIG_RT_USING_SLAB is not set
+# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_INTERRUPT_INFO=y
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+
+#
+# C++ features
+#
+CONFIG_RT_USING_CPLUSPLUS=y
+
+#
+# Command shell
+#
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=4096
+CONFIG_FINSH_CMD_SIZE=80
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_USING_MSH_DEFAULT=y
+# CONFIG_FINSH_USING_MSH_ONLY is not set
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=9
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=9
+CONFIG_DFS_FD_MAX=16
+CONFIG_RT_USING_DFS_ELMFAT=y
+
+#
+# elm-chan's FatFs, Generic FAT Filesystem Module
+#
+CONFIG_RT_DFS_ELM_CODE_PAGE=437
+CONFIG_RT_DFS_ELM_WORD_ACCESS=y
+CONFIG_RT_DFS_ELM_USE_LFN_0=y
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+CONFIG_RT_DFS_ELM_USE_LFN=0
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=4096
+# CONFIG_RT_DFS_ELM_USE_ERASE is not set
+CONFIG_RT_DFS_ELM_REENTRANT=y
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_NET is not set
+# CONFIG_RT_USING_DFS_ROMFS is not set
+# CONFIG_RT_USING_DFS_RAMFS is not set
+# CONFIG_RT_USING_DFS_UFFS is not set
+CONFIG_RT_USING_DFS_JFFS2=y
+CONFIG_RT_USING_DFS_NFS=y
+CONFIG_RT_NFS_HOST_EXPORT="192.168.10.82:/"
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_HWTIMER is not set
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+CONFIG_RT_USING_I2C_BITOPS=y
+CONFIG_RT_USING_PIN=y
+CONFIG_RT_USING_MTD_NOR=y
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_RTC is not set
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_SFUD is not set
+# CONFIG_RT_USING_W25QXX is not set
+# CONFIG_RT_USING_GD is not set
+# CONFIG_RT_USING_ENC28J60 is not set
+# CONFIG_RT_USING_SPI_WIFI is not set
+CONFIG_RT_USING_WDT=y
+# CONFIG_RT_USING_WIFI is not set
+
+#
+# Using USB
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+
+#
+# POSIX layer and C standard library
+#
+CONFIG_RT_USING_LIBC=y
+CONFIG_RT_USING_PTHREADS=y
+# CONFIG_RT_USING_POSIX is not set
+
+#
+# Network stack
+#
+
+#
+# light weight TCP/IP stack
+#
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP141 is not set
+CONFIG_RT_USING_LWIP202=y
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_IGMP=y
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+# CONFIG_RT_LWIP_RAW is not set
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=64
+CONFIG_RT_LWIP_PBUF_NUM=16
+CONFIG_RT_LWIP_RAW_PCB_NUM=10
+CONFIG_RT_LWIP_UDP_PCB_NUM=64
+CONFIG_RT_LWIP_TCP_PCB_NUM=8
+CONFIG_RT_LWIP_TCP_SEG_NUM=256
+CONFIG_RT_LWIP_TCP_SND_BUF=12040
+CONFIG_RT_LWIP_TCP_WND=11680
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=100
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=32768
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=126
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=1024
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=32
+CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+
+#
+# Modbus master and slave stack
+#
+# CONFIG_RT_USING_MODBUS is not set
+CONFIG_LWIP_USING_DHCPD=y
+# CONFIG_RT_USING_NETUTILS is not set
+
+#
+# RT-Thread UI Engine
+#
+# CONFIG_RT_USING_GUIENGINE is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_LOGTRACE is not set
+# CONFIG_RT_USING_RYM is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_EZXML is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_libsodium is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+
+#
+# language packages
+#
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_IPERF is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+
+#
+# example package: hello
+#
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_SOC_GK7101 is not set
+# CONFIG_SOC_GK7102 is not set
+# CONFIG_SOC_GK7101S is not set
+# CONFIG_SOC_GK7102S is not set
+CONFIG_SOC_GK7102C=y
+CONFIG_BOARD_GK7102C_EVB=y
+CONFIG_SENSOR_TYPE_SC1135=y
+# CONFIG_SENSOR_TYPE_SC1145 is not set
+# CONFIG_SENSOR_TYPE_JXH65 is not set
+# CONFIG_SENSOR_TYPE_OV9750 is not set
+# CONFIG_SENSOR_TYPE_AR0130 is not set
+# CONFIG_SENSOR_TYPE_JXH42 is not set
+CONFIG_TUNNING_TOOL_SUPPORT=y
+CONFIG_RT_USING_DMA_MEM=y
+CONFIG_ARM1176_USE_VFP=y
+CONFIG_RT_USING_VFP=y
+CONFIG_RT_USING_CPU_FFS=y
+
+#
+# Goke Peripheral Device Config
+#
+CONFIG_RT_USING_ADC=y
+CONFIG_RT_USING_GMAC=y
+CONFIG_RT_USING_PWM=y
+CONFIG_RT_USING_GK_DMA=y
+CONFIG_RT_USING_LIBZ=y
+CONFIG_RT_USING_LOGCAPTURE=y
+CONFIG_RT_ALIGN_UC_SIZE=8
+CONFIG_RT_ALIGN_DSP_SIZE=32
+CONFIG_RT_DEBUG_UC_MEM=0
+CONFIG_RT_DEBUG_DSP_MEM=0

+ 14 - 0
bsp/gkipc/libraries/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+import os
+Import('rtconfig')
+from building import *
+
+objs = []
+cwd  = GetCurrentDir()
+list = os.listdir(cwd)
+
+objs += SConscript(os.path.join('drv', 'SConscript'))
+  
+Return('objs')
+
+

+ 15 - 0
bsp/gkipc/libraries/drv/7102C/SConscript

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

+ 18 - 0
bsp/gkipc/libraries/drv/7102C/gd/SConscript

@@ -0,0 +1,18 @@
+from building import *
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+path = [cwd + '/inc']
+
+libcwd = str(Dir('#'))
+libinspath = libcwd + '/libraries/lib'
+
+group = DefineGroup('gd', src, depend = [''], CPPPATH = path, LIBINSPATH = libinspath)
+
+list = os.listdir(cwd)
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        group = group + SConscript(os.path.join(d, 'SConscript'))
+        
+Return('group')

+ 164 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_adc.h

@@ -0,0 +1,164 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_adc.h
+**
+** \brief     ADC.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#ifndef _GD_ADC_H_
+#define _GD_ADC_H_
+
+#include "gmodids.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+#define GD_ADC_ERR_BASE             (GD_ADC_MODULE_ID << 16)
+#define GD_ADC_AUX_ATOP_INITIALIZE  0x0255
+#define GD_ADC_CONTROL_INITIALIZE   0x000A
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+/*!
+*******************************************************************************
+**
+** \brief ADC driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_ADC_TYPE_NOT_SUPPORTED = GD_ADC_ERR_BASE, //!< Device not supported.
+};
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+/*!
+*******************************************************************************
+**
+** \brief ADC channel number.
+**
+** \sa    GD_ADC_OPEN_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_ADC_ENABLE_DISABLE = 0,
+    GD_ADC_ENABLE_ENABLE,
+    GD_ADC_ENABLE_COUNT,
+}GD_ADC_ENABLE_E;
+
+typedef enum
+{
+    GD_ADC_CONTROL_CHANNEL_ONE = 0x5, //!< ADC pad_sar_key1.
+    GD_ADC_CONTROL_CHANNEL_TWO = 0x6, //!< ADC pad_sar_key2.
+    GD_ADC_CONTROL_CHANNEL_COUNT,
+}GD_ADC_CONTROL_CHANNEL_E;
+
+typedef enum
+{
+    GD_ADC_CHANNEL_ONE = 0, //!< ADC channel 1.
+    GD_ADC_CHANNEL_TWO,     //!< ADC channel 2.
+    GD_ADC_CHANNEL_COUNT,
+}GD_ADC_CHANNEL_E;
+
+enum
+{
+    GD_ADC_REQ_CHANNEL_ONE = 1, //!< ADC req channel 1.
+    GD_ADC_REQ_CHANNEL_TWO,     //!< ADC req channel 2.
+};
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+/*!
+*******************************************************************************
+**
+** \brief Init parameters.
+**
+** \sa    GD_ADC_Open() <BR>
+**
+******************************************************************************/
+typedef struct
+{
+    U32     val_lo : 10;
+    U32            :  5;
+    U32     val_hi : 10;
+    U32            :  5;
+    U32     en_lo  :  1;
+    U32     en_hi  :  1;
+} GD_ADC_CONTROL_S;
+typedef union
+{
+    U32                     data;
+    GD_ADC_CONTROL_S        control;
+}GD_ADC_CRYPTO_DATA_T;
+
+typedef struct
+{
+    GD_ADC_CHANNEL_E channel;
+    GD_ADC_CRYPTO_DATA_T control;
+} GD_ADC_OPEN_PARAMS_S;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ADC_Init(void);
+GERR GD_ADC_Exit(void);
+GERR GD_ADC_Open(GD_ADC_OPEN_PARAMS_S * openParamsP, GD_HANDLE* pHandle );
+GERR GD_ADC_Close(GD_HANDLE * pHandle);
+GERR GD_ADC_Read(GD_HANDLE *pHandle, U32* data);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ADC_H_ */
+
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 191 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_audio.h

@@ -0,0 +1,191 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_audio.h
+**
+** \brief     audio.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#ifndef _GD_AUDIO_H_
+#define _GD_AUDIO_H_
+
+#include "gmodids.h"
+
+#define GD_AUDIO_ERR_BASE   (GD_AUDIO_MODULE_ID << 16)
+
+
+/*!
+*******************************************************************************
+**
+** \brief I2S driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_AUDIO_NOT_SUPPORTED = GD_AUDIO_ERR_BASE, //!< Device not supported.
+    GD_ERR_AUDIO_NOT_OPEN,
+    GD_ERR_AUDIO_DEV_BUSY,
+    GD_ERR_AUDIO_DEV_WAIT,
+};
+
+typedef enum  /* 2dB per level */
+{
+    GAIN_LEVEL_0,
+    GAIN_LEVEL_1,
+    GAIN_LEVEL_2,
+    GAIN_LEVEL_3,
+    GAIN_LEVEL_4,
+    GAIN_LEVEL_5,
+    GAIN_LEVEL_6,
+    GAIN_LEVEL_7,
+    GAIN_LEVEL_8,
+    GAIN_LEVEL_9,
+    GAIN_LEVEL_10,
+    GAIN_LEVEL_11,
+    GAIN_LEVEL_12,
+    GAIN_LEVEL_13,
+    GAIN_LEVEL_14,
+    GAIN_LEVEL_15,
+    GAIN_LEVEL_MAX,
+}GD_AUDIO_GAIN_E;
+
+typedef enum
+{
+    VOL_LEVEL_0  = 0xaf,
+    VOL_LEVEL_1  = 0xad,
+    VOL_LEVEL_2  = 0xab,
+    VOL_LEVEL_3  = 0xa9,
+    VOL_LEVEL_4  = 0xa7,
+    VOL_LEVEL_5  = 0xa5,
+    VOL_LEVEL_6  = 0xa3,
+    VOL_LEVEL_7  = 0xa1,
+    VOL_LEVEL_8  = 0xa0,
+    VOL_LEVEL_9  = 0xbe,
+    VOL_LEVEL_10 = 0xb9,
+    VOL_LEVEL_11 = 0xb4,
+    VOL_LEVEL_12 = 0xb0,
+}GD_AUDIO_VOLUME_E;
+
+typedef enum
+{
+    AUDIO_SOUND_MODE_LEFT   = 0,
+    AUDIO_SOUND_MODE_RIGHT  = 1,
+    AUDIO_SOUND_MODE_STEREO = 2,
+    AUDIO_SOUND_MODE_MONO   = 3,
+    AUDIO_SOUND_MODE_SINGLE = 4,
+}GD_AUDIO_SOUND_MODE_E;
+
+typedef enum
+{
+    AUDIO_SAMPLE_RATE_8000  = 8000,
+    AUDIO_SAMPLE_RATE_11025 = 11025,
+    AUDIO_SAMPLE_RATE_12000 = 12000,
+    AUDIO_SAMPLE_RATE_16000 = 16000,
+    AUDIO_SAMPLE_RATE_22050 = 22050,
+    AUDIO_SAMPLE_RATE_24000 = 24000,
+    AUDIO_SAMPLE_RATE_32000 = 32000,
+    AUDIO_SAMPLE_RATE_44100 = 44100,
+    AUDIO_SAMPLE_RATE_48000 = 48000,
+}GD_AUDIO_SAMPLE_RATE_E;
+
+typedef enum
+{
+    AUDIO_BIT_WIDTH_16 = 16,
+}GD_AUDIO_BIT_WIDTH_E;
+
+enum
+{
+	AUDIO_EVENT_FRAME          = 1, /* received one audio frame or send finished one audio frame */
+    AUDIO_EVENT_WILL_OVERFLOW  = 2,
+	AUDIO_EVENT_WILL_UNDERFLOW = 3,	
+    AUDIO_EVENT_ALREADY_OVERFLOW  = 4,
+	AUDIO_EVENT_ALREADY_UNDERFLOW = 5,	
+	AUDIO_EVENT_UNDEFINED         = 6,
+};
+
+typedef void (*GD_AUDIO_Notifier)(U32 event);
+
+typedef struct
+{
+    GD_AUDIO_SAMPLE_RATE_E         sampleRate;
+    GD_AUDIO_SOUND_MODE_E          soundMode;
+}GD_AUDIO_ATTR_S;
+
+typedef struct
+{
+    GD_AUDIO_SAMPLE_RATE_E         sampleRate;
+    GD_AUDIO_BIT_WIDTH_E           bitWidth;
+    GD_AUDIO_SOUND_MODE_E          soundMode;
+    U32                            sampleNumber;
+	GD_AUDIO_Notifier              notifier;
+}GD_AUDIO_OPEN_PARAM_S;
+
+
+typedef struct
+{
+    GD_AUDIO_BIT_WIDTH_E      bitWidth;
+    GD_AUDIO_SOUND_MODE_E     soundMode;
+	GD_AUDIO_SAMPLE_RATE_E    sampleRate;
+    U32                       frameAddr;
+	U32                       frameSize;
+    U32                       timeStamp;
+    U32                       seqNumber;
+	U32                       aecSeq;     /* audio echo cancellation seque number */
+}GD_AUDIO_FRAME_S;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_AUDIO_Init(void);
+GERR GD_AUDIO_Exit(void);
+GERR GD_AUDIO_Bind_Ai2Ao(void);
+GERR GD_AUDIO_Unbind_Ai2Ao(void);
+GERR GD_AUDIO_AI_Open(GD_AUDIO_OPEN_PARAM_S *openParamPtr);
+GERR GD_AUDIO_AI_Close(void);
+GERR GD_AUDIO_AI_Enable(void);
+GERR GD_AUDIO_AI_Disable(void);
+GERR GD_AUDIO_AI_Read_Frame(GD_AUDIO_FRAME_S *frame);
+GERR GD_AUDIO_AI_Set_Attr(GD_AUDIO_ATTR_S *pattr);
+GERR GD_AUDIO_AI_Get_Attr(GD_AUDIO_ATTR_S *pattr);
+GERR GD_AUDIO_AI_Set_Gain(GD_AUDIO_GAIN_E gain);
+GD_AUDIO_GAIN_E GD_AUDIO_AI_Get_Gain(void);
+GERR GD_AUDIO_AO_Open(GD_AUDIO_OPEN_PARAM_S *openParamPtr);
+GERR GD_AUDIO_AO_Close(void);
+GERR GD_AUDIO_AO_Enable(void);
+GERR GD_AUDIO_AO_Disable(void);
+GERR GD_AUDIO_AO_Write_Frame(GD_AUDIO_FRAME_S *frame);
+GERR GD_AUDIO_AO_Set_Attr(GD_AUDIO_ATTR_S *pattr);
+GERR GD_AUDIO_AO_Get_Attr(GD_AUDIO_ATTR_S *pattr);
+GERR GD_AUDIO_AO_Set_Volume(GD_AUDIO_VOLUME_E volume);
+GD_AUDIO_VOLUME_E GD_AUDIO_AO_Get_Volume(void);
+GERR GD_AUDIO_AO_Mute(void);
+GERR GD_AUDIO_AO_Unmute(void);
+U32 GD_AUDIO_AI_Get_RecFrameNum(void);
+U32 GD_AUDIO_AO_Get_RecFrameNum(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_AUDIO_H_ */
+
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 165 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_crypto.h

@@ -0,0 +1,165 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/inc/crypto.h
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _CRYPTO_H_
+#define _CRYPTO_H_
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+/*!
+*******************************************************************************
+**
+** \brief CRYPTO mode.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+   GD_CRYPTO_DES    = 0,    // used DES
+   GD_CRYPTO_AES_128,       // used AES_128
+   GD_CRYPTO_AES_192,       // used AES_192
+   GD_CRYPTO_AES_256,       // used AES_256
+   GD_CRYPTO_MODE_MAX,      //
+}GD_CRYPTO_MODE_E;
+//GD_INT_AES_OUTPUT_READY_IRQ = (13 + 32),  //!< edge, AES output ready from Crypt block
+//GD_INT_DES_OUTPUT_READY_IRQ = (14 + 32),  //!< edge, DES output ready from Crypt block
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+typedef struct
+{
+    U32     key_hi;
+    U32     key_lo;
+}GD_CRYPTO_DES_KEY_T;
+
+typedef struct
+{
+    U32     key_127_96;
+    U32     key_95_64;
+    U32     key_63_32;
+    U32     key_31_0;
+}GD_CRYPTO_AES128_KEY_T;
+
+typedef struct
+{
+    U32     key_191_160;
+    U32     key_159_128;
+    U32     key_127_96;
+    U32     key_95_64;
+    U32     key_63_32;
+    U32     key_31_0;
+}GD_CRYPTO_AES192_KEY_T;
+
+typedef struct
+{
+    U32     key_255_224;
+    U32     key_223_192;
+    U32     key_191_160;
+    U32     key_159_128;
+    U32     key_127_96;
+    U32     key_95_64;
+    U32     key_63_32;
+    U32     key_31_0;
+}GD_CRYPTO_AES256_KEY_T;
+
+typedef union
+{
+    U32                     key[8];
+    GD_CRYPTO_DES_KEY_T     des_key;
+    GD_CRYPTO_AES128_KEY_T  aes128_key;
+    GD_CRYPTO_AES192_KEY_T  aes192_key;
+    GD_CRYPTO_AES256_KEY_T  aes256_key;
+}GD_CRYPTO_KEY_T;
+
+typedef struct
+{
+    U32     data_hi;
+    U32     data_lo;
+}GD_CRYPTO_DES_DATA_T;
+
+typedef struct
+{
+    U32     data_127_96;
+    U32     data_95_64;
+    U32     data_63_32;
+    U32     data_31_0;
+}GD_CRYPTO_AES_DATA_T;
+
+typedef union
+{
+    U32                     data[4];
+    GD_CRYPTO_DES_DATA_T    des_data;
+    GD_CRYPTO_AES_DATA_T    aes_data;
+}GD_CRYPTO_DATA_T;
+
+typedef struct
+{
+    GD_CRYPTO_MODE_E    mode;
+    GD_CRYPTO_KEY_T*    pkey;
+    GBOOL               useint;
+    GISR2               (*notifyFct)(void);
+}GD_CRYPTO_OpenParamsT;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+GERR GD_CRYPTO_Open(GD_CRYPTO_OpenParamsT* pOpenParams, GD_HANDLE* pHandle);
+GERR GD_CRYPTO_Close(GD_HANDLE* pHandle);
+GERR GD_CRYPTO_EncrptData(GD_HANDLE handle, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out);
+GERR GD_CRYPTO_DecrptData(GD_HANDLE handle, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out);
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _CRYPTO_H_ */
+

+ 178 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_dma.h

@@ -0,0 +1,178 @@
+/******************************************************************************
+**
+** \file      gd_dma.h
+**
+** \brief     DEMO test application.
+**
+**            (C) Goke Microelectronics China 2002 - 2007
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version   \$Id: gd_timer.h,v 1.8 2007/01/04 15:13:22 mneuma Exp $
+**
+******************************************************************************/
+
+#ifndef _GD_DMA_H_
+#define _GD_DMA_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+#ifdef GK710X
+    #define DMA_RX_REG (REG_I2S_RX_DMA-0x30000000)
+    #define DMA_TX_REG (REG_I2S_TX_LEFT_DMA-0x30000000)
+#else
+    #define DMA_RX_REG (REG_I2S_RX_DMA)
+    #define DMA_TX_REG (REG_I2S_TX_LEFT_DMA)
+#endif
+
+/****************************/
+/* DMA Channel Assignments  */
+/****************************/
+
+#define DMA_CHAN_MAX_NUM    4  
+#define DMA_CHAN_MAX_DESC   32 /* max descriptor per channel */
+#define DMA_BUFF_ADDR_ALIGN 8 
+
+
+/* General DMA instance channel */
+#define DMA_CHAN_NULL       0
+#define DMA_CHAN_I2S_RX     1
+#define DMA_CHAN_I2S_TX     2
+#define DMA_CHAN_AUDIO_RX   1
+#define DMA_CHAN_AUDIO_TX   2
+#define DMA_CHAN_USB        3
+
+
+#define DMA_MODE_NORMAL 	0
+#define DMA_MODE_DESCRIPTOR 1
+
+
+/* DMA_CHAN_CTRL_REG */
+#define DMA_CHAN_CTRL_EN        0x80000000
+#define DMA_CHAN_CTRL_D         0x40000000
+#define DMA_CHAN_CTRL_WM        0x20000000
+#define DMA_CHAN_CTRL_RM        0x10000000
+#define DMA_CHAN_CTRL_NI        0x08000000
+#define DMA_CHAN_CTRL_BLK_1024B 0x07000000
+#define DMA_CHAN_CTRL_BLK_512B  0x06000000
+#define DMA_CHAN_CTRL_BLK_256B  0x05000000
+#define DMA_CHAN_CTRL_BLK_128B  0x04000000
+#define DMA_CHAN_CTRL_BLK_64B   0x03000000
+#define DMA_CHAN_CTRL_BLK_32B   0x02000000
+#define DMA_CHAN_CTRL_BLK_16B   0x01000000
+#define DMA_CHAN_CTRL_BLK_8B    0x00000000
+#define DMA_CHAN_CTRL_TS_8B     0x00C00000
+#define DMA_CHAN_CTRL_TS_4B     0x00800000
+#define DMA_CHAN_CTRL_TS_2B     0x00400000
+#define DMA_CHAN_CTRL_TS_1B     0x00000000
+
+/* DMA descriptor bit fields */
+#define DMA_DESC_EOC            0x01000000
+#define DMA_DESC_WM             0x00800000
+#define DMA_DESC_RM             0x00400000
+#define DMA_DESC_NI             0x00200000
+#define DMA_DESC_TS_8B          0x00180000
+#define DMA_DESC_TS_4B          0x00100000
+#define DMA_DESC_TS_2B          0x00080000
+#define DMA_DESC_TS_1B          0x00000000
+#define DMA_DESC_BLK_1024B      0x00070000
+#define DMA_DESC_BLK_512B       0x00060000
+#define DMA_DESC_BLK_256B       0x00050000
+#define DMA_DESC_BLK_128B       0x00040000
+#define DMA_DESC_BLK_64B        0x00030000
+#define DMA_DESC_BLK_32B        0x00020000
+#define DMA_DESC_BLK_16B        0x00010000
+#define DMA_DESC_BLK_8B         0x00000000
+#define DMA_DESC_ID             0x00000004
+#define DMA_DESC_IE             0x00000002
+#define DMA_DESC_ST             0x00000001
+
+/* DMA_CHAN_STATE_REG */
+#define DMA_CHAN_STATE_DM        0x80000000
+#define DMA_CHAN_STATE_OE        0x40000000
+#define DMA_CHAN_STATE_DA        0x20000000
+#define DMA_CHAN_STATE_DD        0x10000000
+#define DMA_CHAN_STATE_OD        0x08000000
+#define DMA_CHAN_STATE_ME        0x04000000
+#define DMA_CHAN_STATE_BE        0x02000000
+#define DMA_CHAN_STATE_RWE       0x01000000
+#define DMA_CHAN_STATE_AE        0x00800000
+#define DMA_CHAN_STATE_DN        0x00400000
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+typedef void (*GD_DMA_NOTIFIER_F)(void);
+
+typedef struct dma_descriptor_s
+{
+    U32 srcAddr;        /*  Source address */
+    U32 dstAddr;        /* Destination address */
+    struct dma_descriptor_s *next; /* Pointing to next descriptor */
+    U32 reportAddr;     /* The physical address to store DMA hardware reporting status */
+    U32 dataLength;     /* Transfer byte count , max value = 2^22 */
+    U32 descAttr;       /* Descriptor 's attribute */
+}GD_DMA_DESCRIPTOR_S;
+
+typedef struct
+{
+    U32      channel;
+    U32      mode;
+	GD_DMA_NOTIFIER_F intNotifier;
+}GD_DMA_OPEN_PARAM_S;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_DMA_Init(void);
+GERR GD_DMA_Exit(void);
+GERR GD_DMA_Open(GD_DMA_OPEN_PARAM_S *openParam, GD_HANDLE *handle);
+GERR GD_DMA_Close(GD_HANDLE handle);
+GERR GD_DMA_AddDescriptor(GD_HANDLE handle, GD_DMA_DESCRIPTOR_S *descriptor);
+GERR GD_DMA_Start(GD_HANDLE handle, U32 desc);
+GERR GD_DMA_Stop(GD_HANDLE handle);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GD_DMA_H_ */
+

+ 408 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_ethernet.h

@@ -0,0 +1,408 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/inc/gd_ethernet.h
+**
+** \version     2.0
+**
+** \date        Sept 09, 2014
+**
+** \author      Steven Yu
+**
+** \brief       Ethernet Driver.
+**
+** This application allows testing of the ethernet function.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+** (C) Copyright 2002 - 2014 by Goke Microelectronics Shanghai WSC
+**
+*******************************************************************************
+*/
+//#define PRINT_ETH_LOG
+
+#ifndef _GD_ETHERNET_H_
+#define _GD_ETHERNET_H_
+#include "gtypes.h"
+#include <gmodids.h>
+#include "gd_gpio.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+/* Length of Ethernet Mac address in bytes (Do NOT change) */
+#define GD_ETH_MAC_ADDR_NUM        (6)
+typedef U8 GD_ETH_MacT[GD_ETH_MAC_ADDR_NUM];
+#define GD_ETH_IP_ADDR_NUM        (4)
+typedef U8 GD_ETH_IpT[GD_ETH_IP_ADDR_NUM];
+
+#define GD_ETH_ERR_BASE   (GD_ETH_MODULE_ID << 16)
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+enum
+{
+    GD_ERR_ETH_NOT_SUPPORTED = GD_ETH_ERR_BASE, //!< Device not supported.
+    GD_ERR_ETH_NOT_OPEN,
+    GD_ERR_ETH_PHY_NOT_EXIST,
+    GD_ERR_ETH_PHY_RW,
+    GD_ERR_ETH_PHY_OTHER,
+    GD_ERR_ETH_MAC_NOT_OK,
+    GD_ERR_ETH_LINK_DOWN,
+    GD_ERR_ETH_TB_OVER,
+    GD_ERR_ETH_NO_TD,
+};
+
+/*!
+*************************************************************************
+** \brief Version of Ethernet driver.
+**
+** This number consists of a \b major version number stored in bits
+** 16 to 31 (upper word) and a \b minor version number stored in bits
+** 0 to 15 (lower word).
+** - The \b major number has to be increased when a parameter change
+**   occurs for the existing driver's API after its first release.
+** - The \b minor number has to be increased when functions are added to
+**   the existing driver's API after its first release.
+**
+** \note This value has to be assigned to the \b version field of the
+**       GD_ETH_OpenParamsT structure.
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_VERSION = 0x00020000 //!< The current driver version
+}GD_ETH_VersionE;
+
+/*!
+*************************************************************************
+** \brief internal Or external PHY for Ethernet driver.
+**
+** Indicate speed setting.
+** Used on GD_ETH_Open() and GD_ETH_GetStat()
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_PHY_INTERNAL = 0,    //!<Enet MAC use internal PHY
+    GD_ETH_PHY_EXTERNAL_1,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_2,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_3,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_4,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_5,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_6,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_7,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_8,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_9,      //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_10,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_11,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_12,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_13,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_14,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_15,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_16,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_17,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_18,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_19,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_20,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_21,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_22,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_23,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_24,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_25,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_26,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_27,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_28,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_29,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_30,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_31,     //!<Enet MAC use external PHY
+    GD_ETH_PHY_EXTERNAL_AUTO,   //!<Enet MAC use external PHY
+}GD_ETH_PHY_AddrE;
+
+/*!
+*************************************************************************
+** \brief speed parameter for Ethernet driver.
+**
+** Indicate speed setting.
+** Used on GD_ETH_Open() and GD_ETH_GetStat()
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_SPEED_AUTO  =   0,   //!< Auto-negotiation
+    GD_ETH_SPEED_10M   =  10,   //!< 10Mbps
+    GD_ETH_SPEED_100M  = 100,   //!< 100Mbps
+    GD_ETH_SPEED_1000M = 1000,  //!< 1000Mbps
+}GD_ETH_SpeedE;
+
+/*!
+*************************************************************************
+** \brief duplex mode parameter for Ethernet driver.
+**
+** Indicate duplex mode setting.
+** Used on GD_ETH_Open() and GD_ETH_GetStat()
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_HALF_DUPLEX  = 0,//!< half-duplex mode
+    GD_ETH_FULL_DUPLEX  = 1 //!< full-duplex mode
+}GD_ETH_DuplexE;
+
+/*!
+*************************************************************************
+** \brief local ethWorkMode.loop mode parameter for Ethernet driver.
+**
+** Indicate local ethWorkMode.loop mode setting.
+** Used on GD_ETH_Open()
+**
+** \note local ethWorkMode.loop mode is for debug purpose. general applications
+**       should specify #GD_ETH_LOOP_OFF only.
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_LOOP_OFF     = 0,//!< ethWorkMode.loop off
+    GD_ETH_LOOP_ON_MAC  = 1,//!< ethWorkMode.loop on LAN(MAC) device
+    GD_ETH_LOOP_ON_PHY  = 2 //!< ethWorkMode.loop on PHY device
+}GD_ETH_LoopE;
+
+/*!
+*************************************************************************
+** \brief link status parameter for Ethernet driver.
+**
+** Indicate link status.
+** Used on GD_ETH_GetStat()
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_LINKDOWN    = 0, //!< link is down
+    GD_ETH_LINKUP      = 1, //!< link is up
+    GD_ETH_LINKUNKNOWN = 2  //!< link status is unknown
+}GD_ETH_LinkE;
+
+/*!
+*************************************************************************
+** \brief detailed error status for Ethernet driver.
+**
+** Indicate detailed error status.
+** Used on GD_ETH_GetStat()
+**
+** \note It depends on ethernet hardware. So other values may
+**       be added in future version.
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_ERR_NONE      = 0x00000000,//!< No error, normal running
+    GD_ETH_ERR_SW        = 0x00000001,//!< Fatal error by software(bug)
+    GD_ETH_ERR_FATAL     = 0x00000001,//!< Fatal error by software(bug)
+    GD_ETH_ERR_RX_BUS    = 0x00000002,//!< Bus error in receiving
+    GD_ETH_ERR_RWT_MAX   = 0x00000008,//!< Excessive Watchdog timeout error
+    GD_ETH_ERR_RX_BAND   = 0x00000020,//!< Overflow error in receiving
+    GD_ETH_ERR_RX_CONFIG = 0x00000080,//!< Feature not supported (Jumbo frames)
+
+    GD_ETH_ERR_TX_BUS    = 0x00000004,//!< Bus error in transmitting
+    GD_ETH_ERR_TJT_MAX   = 0x00000010,//!< Excessive Jabber timeout error
+    GD_ETH_ERR_TX_BAND   = 0x00000040,//!< Underflow error in transmitting
+    GD_ETH_ERR_TX_CONFIG = 0x00000100,//!< Feature not supported (Jumbo frames)
+    GD_ETH_ERR_LATE_COL  = 0x00000200,//!< Excessive late collision error
+
+}GD_ETH_ErrorE;
+
+
+typedef enum
+{
+    GD_ETH_UNINITIALIZE  = 0x00000000,
+    GD_ETH_FATAL_ERROR   = 0x00000001,
+    GD_ETH_UNKNOWN       = 0x00000002,
+    GD_ETH_RX_RUN        = 0x00000004,
+    GD_ETH_RX_SUSP_NOBUF = 0x00000008,
+    GD_ETH_RX_SUSP_HWERR = 0x00000010,
+    GD_ETH_RX_STOP       = 0x00000020,
+    GD_ETH_RX_STOP_HWERR = 0x00000040,
+    GD_ETH_TX_RUN        = 0x00000080,
+    GD_ETH_TX_SUSP_NODAT = 0x00000100,
+    GD_ETH_TX_SUSP_HWERR = 0x00000200,
+    GD_ETH_TX_STOP       = 0x00000400,
+    GD_ETH_TX_STOP_HWERR = 0x00000800,
+} GD_ETH_StatE;
+
+typedef enum
+{
+    GD_ETH_R  = 0x00000001,
+    GD_ETH_W  = 0x00000002,
+    GD_ETH_RW = 0x00000003
+} GD_ETH_RWE;
+
+/*!
+*************************************************************************
+** \brief Frame end flag for Ethernet driver.
+**
+** Indicate whether frame reaches to end or not. It is passed as an argument of
+** read/write to indicate a boundary of ethernet frame.
+** Used on GD_ETH_Write() and GD_ETH_Read().
+*************************************************************************
+*/
+typedef enum
+{
+    GD_ETH_FRAME_NOTEND   =  0x00000000,//!< frame does not end.
+    GD_ETH_FRAME_END      =  0x00000001,//!< frame ends.
+    GD_ETH_FRAME_TERM     =  0x00000002 //!< frame ends on error
+} GD_ETH_FrameEndE;
+
+typedef enum
+{
+    GD_ETH_PHY_IF_MODE_MII,
+    GD_ETH_PHY_IF_MODE_GMII,
+    GD_ETH_PHY_IF_MODE_SGMII,
+    GD_ETH_PHY_IF_MODE_TBI,
+    GD_ETH_PHY_IF_MODE_RMII,
+    GD_ETH_PHY_IF_MODE_RGMII,
+    GD_ETH_PHY_IF_MODE_RGMII_ID,
+    GD_ETH_PHY_IF_MODE_RGMII_RXID,
+    GD_ETH_PHY_IF_MODE_RGMII_TXID,
+    GD_ETH_PHY_IF_MODE_RTBI,
+    GD_ETH_PHY_IF_MODE_XGMII,
+    GD_ETH_PHY_IF_MODE_NONE /* Must be last */
+}GD_ETH_PHY_IF_E;   /* Phy Interface */
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+/*!
+*************************************************************************
+** \brief Status information about Ethernet driver and link status.
+**
+** This data structure contains information about the current ethernet
+** driver settings and link status.
+**
+** \sa GD_ETH_GetStat
+*************************************************************************
+*/
+typedef struct
+{
+    GBOOL           bEnAutoNeg;
+    GD_ETH_SpeedE   speed;          //!< speed setting
+    GD_ETH_DuplexE  duplex;         //!< duplex mode setting
+    GD_ETH_LoopE    loopback;       //!< local loopback mode setting
+    GD_ETH_PHY_IF_E mode;           //!<
+}GD_ETH_Work_ModeT;
+
+/*!
+*************************************************************************
+** \brief Status information about Ethernet driver and link status.
+**
+** This data structure contains information about the current ethernet
+** driver settings and link status.
+**
+** \sa GD_ETH_GetStat
+*************************************************************************
+*/
+typedef struct
+{
+    GD_ETH_SpeedE   speed;      //!< speed setting
+    GD_ETH_DuplexE  duplex;     //!< duplex mode setting
+    GD_ETH_LoopE    loopback;   //!< local loopback mode setting
+    GD_ETH_PHY_IF_E mode;       //!<
+    GD_ETH_LinkE    linkup;     //!< link is up or not
+    GD_ETH_ErrorE   error;      //!< error details (if available)
+}GD_ETH_StatParamsT;
+
+/*!
+ *************************************************************************
+ ** \brief Open parameters for Ethernet driver.
+ **
+ ** This data structure contains all the parameters for GD_ETH_Open().
+ **
+ ** \sa GD_ETH_Open
+ *************************************************************************
+ */
+typedef struct
+{
+    GBOOL               bHWReset;
+    GD_GPIO_PIN_E       phyreset;
+	U8                  phyType;
+} GD_ETH_InitParamsT;
+
+/*!
+ *************************************************************************
+ ** \brief Open parameters for Ethernet driver.
+ **
+ ** This data structure contains all the parameters for GD_ETH_Open().
+ **
+ ** \sa GD_ETH_Open
+ *************************************************************************
+ */
+typedef struct
+{
+    GD_ETH_PHY_AddrE    addr;
+    GD_ETH_Work_ModeT   workmode;
+    GD_ETH_MacT         macaddr;
+    GD_ETH_IpT          ipaddr;
+    GBOOL               supJumbo;  
+} GD_ETH_OpenParamsT;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ETH_Init(GD_ETH_InitParamsT* pInitParams);
+GERR GD_ETH_Exit(void);
+GERR GD_ETH_Open(GD_ETH_OpenParamsT* pOpenParams, GD_HANDLE* pHandle);
+GERR GD_ETH_Close(GD_HANDLE* pHandle);
+S32  GD_ETH_Read(GD_HANDLE handle, char *bufPtr, S32 size, GD_ETH_FrameEndE *pframe);
+S32  GD_ETH_Write(GD_HANDLE handle, const char* bufPtr, S32 size, GD_ETH_FrameEndE frame);
+S32  GD_ETH_Write_Enhance(GD_HANDLE handle, const char* bufPtr, S32 size, GD_ETH_FrameEndE frame);
+GERR GD_ETH_Write_HD(GD_HANDLE handle, const char* HbufPtr, S32 Hsize, const char* DbufPtr, S32 Dsize, GD_ETH_FrameEndE frame);
+GERR GD_ETH_Write_HD_Enhance(GD_HANDLE handle, const char* HbufPtr, S32 Hsize, const char* DbufPtr, S32 Dsize, GD_ETH_FrameEndE frame);
+GERR GD_ETH_SetEMACSpeed(GD_HANDLE handle, GD_ETH_SpeedE speed);
+GERR GD_ETH_SetMacAddress(GD_HANDLE handle, GD_ETH_MacT macAddress);
+GERR GD_ETH_GetMacAddress(GD_HANDLE handle, GD_ETH_MacT* pmacAddress);
+GERR GD_ETH_SetIPAddress(GD_HANDLE handle, GD_ETH_IpT ipAddress);
+GERR GD_ETH_GetIPAddress(GD_HANDLE handle, GD_ETH_IpT* pipAddress);
+GERR GD_ETH_GetPhyAddress(GD_HANDLE handle, U8* phy);
+GERR GD_ETH_GetStat(GD_HANDLE handle, GD_ETH_StatParamsT *statParamsPtr);
+GERR GD_ETH_CheckLink(GD_HANDLE handle);
+GERR GD_ETH_SleepTime(U32 ulTime);
+void GD_ETH_SetNetReceiveFuc(void (*eth_rcve)(volatile U8* recbuf,U16 len));
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GD_ETHERNET_H_ */
+

+ 610 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_gpio.h

@@ -0,0 +1,610 @@
+/*
+*******************************************************************************
+**
+** \file      gd_gpio.h
+**
+** \brief     General purpose input output driver.
+**
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+*******************************************************************************
+*/
+#ifndef _GD_GPIO_H_
+#define _GD_GPIO_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+//#include "gd_int.h"
+
+/*!
+*******************************************************************************
+**
+** \brief GPIO driver error codes.
+**
+*******************************************************************************
+*/
+#define GD_GPIO_ERR_BASE (GD_GPIO_MODULE_ID<<16) //!< The GPIO base error code.
+
+enum
+{
+    /*!
+    ** The GPIO is not of the right mode to to perform
+    ** a requested function, e.g. writing to a GPIO which was
+    ** configured as input.
+    */
+    GD_ERR_GPIO_INVALID_TYPE = GD_GPIO_ERR_BASE,
+    GD_ERR_GPIO_OPEN_FAILED,
+};
+
+/*!
+*******************************************************************************
+**
+** \brief All available GPIO pins named by number.
+**
+** \sa GD_GPIO_Open()
+** \sa GD_GPIO_OpenFunctionMode()
+** \sa GD_GPIO_SetType()
+**
+*******************************************************************************
+*/
+typedef enum
+{
+    GD_GPIO_0  =  0, //!< Value representing GPIO  0.
+    GD_GPIO_1  =  1, //!< Value representing GPIO  1.
+    GD_GPIO_2  =  2, //!< Value representing GPIO  2.
+    GD_GPIO_3  =  3, //!< Value representing GPIO  3.
+    GD_GPIO_4  =  4, //!< Value representing GPIO  4.
+    GD_GPIO_5  =  5, //!< Value representing GPIO  5.
+    GD_GPIO_6  =  6, //!< Value representing GPIO  6.
+    GD_GPIO_7  =  7, //!< Value representing GPIO  7.
+    GD_GPIO_8  =  8, //!< Value representing GPIO  8.
+    GD_GPIO_9  =  9, //!< Value representing GPIO  9.
+    GD_GPIO_10 = 10, //!< Value representing GPIO 10.
+    GD_GPIO_11 = 11, //!< Value representing GPIO 11.
+    GD_GPIO_12 = 12, //!< Value representing GPIO 12.
+    GD_GPIO_13 = 13, //!< Value representing GPIO 13.
+    GD_GPIO_14 = 14, //!< Value representing GPIO 14.
+    GD_GPIO_15 = 15, //!< Value representing GPIO 15.
+    GD_GPIO_16 = 16, //!< Value representing GPIO 16.
+    GD_GPIO_17 = 17, //!< Value representing GPIO 17.
+    GD_GPIO_18 = 18, //!< Value representing GPIO 18.
+    GD_GPIO_19 = 19, //!< Value representing GPIO 19.
+    GD_GPIO_20 = 20, //!< Value representing GPIO 20.
+    GD_GPIO_21 = 21, //!< Value representing GPIO 21.
+    GD_GPIO_22 = 22, //!< Value representing GPIO 22.
+    GD_GPIO_23 = 23, //!< Value representing GPIO 23.
+    GD_GPIO_24 = 24, //!< Value representing GPIO 24.
+    GD_GPIO_25 = 25, //!< Value representing GPIO 25.
+    GD_GPIO_26 = 26, //!< Value representing GPIO 26.
+    GD_GPIO_27 = 27, //!< Value representing GPIO 27.
+    GD_GPIO_28 = 28, //!< Value representing GPIO 28.
+    GD_GPIO_29 = 29, //!< Value representing GPIO 29.
+    GD_GPIO_30 = 30, //!< Value representing GPIO 30.
+    GD_GPIO_31 = 31, //!< Value representing GPIO 31.
+    GD_GPIO_32 = 32, //!< Value representing GPIO 32.
+    GD_GPIO_33 = 33, //!< Value representing GPIO 33.
+    GD_GPIO_34 = 34, //!< Value representing GPIO 34.
+    GD_GPIO_35 = 35, //!< Value representing GPIO 35.
+    GD_GPIO_36 = 36, //!< Value representing GPIO 36.
+    GD_GPIO_37 = 37, //!< Value representing GPIO 37.
+    GD_GPIO_38 = 38, //!< Value representing GPIO 38.
+    GD_GPIO_39 = 39, //!< Value representing GPIO 39.
+    GD_GPIO_40 = 40, //!< Value representing GPIO 40.
+    GD_GPIO_41 = 41, //!< Value representing GPIO 41.
+    GD_GPIO_42 = 42, //!< Value representing GPIO 42.
+    GD_GPIO_43 = 43, //!< Value representing GPIO 43.
+    GD_GPIO_44 = 44, //!< Value representing GPIO 44.
+    GD_GPIO_45 = 45, //!< Value representing GPIO 45.
+    GD_GPIO_46 = 46, //!< Value representing GPIO 46.
+    GD_GPIO_47 = 47, //!< Value representing GPIO 47.
+    GD_GPIO_48 = 48, //!< Value representing GPIO 48.
+    GD_GPIO_49 = 49, //!< Value representing GPIO 49.
+    GD_GPIO_50 = 50, //!< Value representing GPIO 50.
+    GD_GPIO_51 = 51, //!< Value representing GPIO 51.
+    GD_GPIO_52 = 52, //!< Value representing GPIO 52.
+    GD_GPIO_53 = 53, //!< Value representing GPIO 53.
+    GD_GPIO_54 = 54, //!< Value representing GPIO 54.
+    GD_GPIO_55 = 55, //!< Value representing GPIO 55.
+    GD_GPIO_56 = 56, //!< Value representing GPIO 56.
+    GD_GPIO_57 = 57, //!< Value representing GPIO 57.
+    GD_GPIO_58 = 58, //!< Value representing GPIO 58.
+    GD_GPIO_59 = 59, //!< Value representing GPIO 59.
+    GD_GPIO_60 = 60, //!< Value representing GPIO 60.
+    GD_GPIO_61 = 61, //!< Value representing GPIO 61.
+    GD_GPIO_62 = 62, //!< Value representing GPIO 62.
+    GD_GPIO_63 = 63, //!< Value representing GPIO 63.
+    GD_GPIO_NUM,
+}GD_GPIO_PIN_E;;
+
+/*!
+*******************************************************************************
+**
+** \brief GPIO types.
+** \high 30-31:00:unused; 01: in; 10:out; 11:in & out.
+** \[ 7: 0]: OUTPUT_CFG out_sel
+** \    0x00: tied to 1¡¯b0, always output 0
+** \    0x01: tied to 1¡¯b1, always output 1
+** \    0x02~0x3f: data inputs from internal modules
+** \[15: 8]: INPUT_CFG  in_sel
+** \    0x00: tied to 1¡¯b0, module¡¯s input is always 0
+** \    0x01: tied to 1¡¯b1, module¡¯s input is always 1
+** \    0x02~0x3f: mux selection(gpio_input[61:0])
+** \[21:16]: OUTPUT_CFG oen_sel
+** \    0x00: tied to 1¡¯b0, always output
+** \    0x01: tied to 1¡¯b1, always input
+** \    0x02~0x3f: oen inputs from internal modules
+** \[22:22]: out_invert
+** \[23:23]: oen_invert
+** \[29:24]: IOCTRL
+** \    [25:24]: 0=2mA,1=4mA,2=8mA,3=12mA
+** \    [29:28]: tied to 1¡¯b0, always output
+**
+** \sa GD_GPIO_SetType()
+** \sa GD_GPIO_Open()
+**
+*******************************************************************************
+*/
+#define GD_GPIO_OUT_SEL(n)      ((n))
+#define GD_GPIO_IN_SEL(n)       ((n)<<8)
+#define GD_GPIO_OEN_SEL(n)      ((n)<<16)
+#define GD_GPIO_OUT_INVERT(n)   ((n)<<22)
+#define GD_GPIO_OEN_INVERT(n)   ((n)<<23)
+#define GD_GPIO_IOCTRL(n)       ((n)<<24)
+#define GD_GPIO_FUNC(n)         ((n)<<30)
+
+#define GD_GPIO_GET_OUT_SEL(n)      (((n)&0x000000FF))
+#define GD_GPIO_GET_IN_SEL(n)       (((n)&0x0000FF00)>>8)
+#define GD_GPIO_GET_OEN_SEL(n)      (((n)&0x003F0000)>>16)
+#define GD_GPIO_GET_OUT_INVERT(n)   (((n)&0x00400000)>>22)
+#define GD_GPIO_GET_OEN_INVERT(n)   (((n)&0x00800000)>>23)
+#define GD_GPIO_GET_IOCTRL(n)       (((n)&0x3F000000)>>24)
+#define GD_GPIO_GET_FUNC(n)         (((n)&0xC0000000)>>30)
+
+#define GD_GPIO_FUNC_IN     1
+#define GD_GPIO_FUNC_OUT    2
+#define GD_GPIO_FUNC_INOUT  3
+
+
+#define IOCTRL_NORMAL       0x00    //!< Hi-z
+#define IOCTRL_PULL_UP      0x10    //!< PULL_UP
+#define IOCTRL_PULL_DOWN    0x20    //!< PULL_DOWN
+#define IOCTRL_REPEAT       0x30    //!< REPEAT
+
+#define IOCTRL_2MA          0x00    //!< 2mA
+#define IOCTRL_4MA          0x01    //!< 4mA
+#define IOCTRL_8MA          0x02    //!< 8mA
+#define IOCTRL_12MA         0x03    //!< 12mA
+
+#ifndef BOARD_FPGA
+typedef enum
+{
+    /* ----------------------------------- GPIO output function define ----------------------------------- */
+    GD_GPIO_TYPE_OUTPUT_0               = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 0),//!< Output type: value = 0
+    GD_GPIO_TYPE_OUTPUT_1               = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 1),//!< Output type: value = 1
+    GD_GPIO_TYPE_OUTPUT_SPI1_SO         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 2) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 2),//!< Output type: tssi_txd
+    GD_GPIO_TYPE_OUTPUT_SPI1_CS0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 3),//!< Output type: tssi_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SPI1_SCLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 4),//!< Output type: tssi_sclk_out
+    GD_GPIO_TYPE_OUTPUT_UART2_RTS_N     = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 5),//!< Output type: uart2_rts_n
+    GD_GPIO_TYPE_OUTPUT_UART2_DTR_N     = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 6),//!< Output type: uart2_dtr_n
+    GD_GPIO_TYPE_OUTPUT_UART2_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 7),//!< Output type: uart2_tx
+    GD_GPIO_TYPE_OUTPUT_UART1_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 8),//!< Output type: uart1_tx
+    GD_GPIO_TYPE_OUTPUT_UART0_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 9),//!< Output type: uart0_tx
+    GD_GPIO_TYPE_OUTPUT_PWM3_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(10),//!< Output type: pwm3_out
+    GD_GPIO_TYPE_OUTPUT_PWM2_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(11),//!< Output type: pwm2_out
+    GD_GPIO_TYPE_OUTPUT_PWM1_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(12),//!< Output type: pwm1_out
+    GD_GPIO_TYPE_OUTPUT_PWM0_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(13),//!< Output type: pwm0_out
+    GD_GPIO_TYPE_OUTPUT_SPI0_SO         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 7) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(14),//!< Output type: ssi_txd
+    GD_GPIO_TYPE_OUTPUT_SPI0_CS1        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(15),//!< Output type: ssi_cs1_n
+    GD_GPIO_TYPE_OUTPUT_SPI0_CS0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(16),//!< Output type: ssi_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SPI0_SCLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(17),//!< Output type: ssi_sclk_out
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                         GD_GPIO_OEN_SEL( 8)                          GD_GPIO_OUT_SEL(18)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                         GD_GPIO_OEN_SEL( 9)                          GD_GPIO_OUT_SEL(19)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                         GD_GPIO_OEN_SEL(10)                          GD_GPIO_OUT_SEL(20)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                         GD_GPIO_OEN_SEL(11)                          GD_GPIO_OUT_SEL(21)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                          GD_GPIO_OEN_SEL(12)                          GD_GPIO_OUT_SEL(22)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_0                                                                                                                                        GD_GPIO_OEN_SEL(13)                          GD_GPIO_OUT_SEL(26)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_1                                                                                                                                        GD_GPIO_OEN_SEL(14)                          GD_GPIO_OUT_SEL(27)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_2                                                                                                                                        GD_GPIO_OEN_SEL(15)                          GD_GPIO_OUT_SEL(28)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_3                                                                                                                                        GD_GPIO_OEN_SEL(16)                          GD_GPIO_OUT_SEL(29)
+    //GD_GPIO_TYPE_INOUT_SDIO1_CMD                                                                                                                                         GD_GPIO_OEN_SEL(17)                          GD_GPIO_OUT_SEL(30)
+    GD_GPIO_TYPE_OUTPUT_SDIO_CLK        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_4MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(23),    //!< Output type: sd_clk_sdcard
+    GD_GPIO_TYPE_OUTPUT_SF_CS0          = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(24),    //!< Output type: sf_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SF_CS1          = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(25),    //!< Output type: sf_cs1_n
+    GD_GPIO_TYPE_OUTPUT_SDIO1_CLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_4MA)     | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(31),    //!< Output type: sd2_clk_sdcard
+    GD_GPIO_TYPE_OUTPUT_JTAGE_TDO       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(32),    //!< Output type: jtag_tdout
+    GD_GPIO_TYPE_OUTPUT_VD_VSYNC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(33),    //!< Output type: lcd_vsync
+    GD_GPIO_TYPE_OUTPUT_VD_HSYNC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(34),    //!< Output type: lcd_hsync
+    GD_GPIO_TYPE_OUTPUT_VD_CLOCK        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(35),    //!< Output type: lcd_dclk
+    GD_GPIO_TYPE_OUTPUT_VD_HVLD         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(36),    //!< Output type: lcd_hvld
+    GD_GPIO_TYPE_OUTPUT_VD_DATA0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(37),    //!< Output type: lcd_data0
+    GD_GPIO_TYPE_OUTPUT_VD_DATA1        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(38),    //!< Output type: lcd_data1
+    GD_GPIO_TYPE_OUTPUT_VD_DATA2        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(39),    //!< Output type: lcd_data2
+    GD_GPIO_TYPE_OUTPUT_VD_DATA3        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(40),    //!< Output type: lcd_data3
+    GD_GPIO_TYPE_OUTPUT_VD_DATA4        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(41),    //!< Output type: lcd_data4
+    GD_GPIO_TYPE_OUTPUT_VD_DATA5        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(42),    //!< Output type: lcd_data5
+    GD_GPIO_TYPE_OUTPUT_VD_DATA6        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(43),    //!< Output type: lcd_data6
+    GD_GPIO_TYPE_OUTPUT_VD_DATA7        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(44),    //!< Output type: lcd_data7
+    GD_GPIO_TYPE_OUTPUT_VD_DATA8        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(45),    //!< Output type: lcd_data8
+    GD_GPIO_TYPE_OUTPUT_VD_DATA9        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(46),    //!< Output type: lcd_data9
+    GD_GPIO_TYPE_OUTPUT_VD_DATA10       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(47),    //!< Output type: lcd_data10
+    GD_GPIO_TYPE_OUTPUT_VD_DATA11       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(48),    //!< Output type: lcd_data11
+    GD_GPIO_TYPE_OUTPUT_VD_DATA12       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(49),    //!< Output type: lcd_data12
+    GD_GPIO_TYPE_OUTPUT_VD_DATA13       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(50),    //!< Output type: lcd_data13
+    GD_GPIO_TYPE_OUTPUT_VD_DATA14       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(51),    //!< Output type: lcd_data14
+    GD_GPIO_TYPE_OUTPUT_VD_DATA15       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(52),    //!< Output type: lcd_data15
+    GD_GPIO_TYPE_OUTPUT_RCT_CLK_OUT2    = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(53),    //!< Output type: rct_clk_out2
+    GD_GPIO_TYPE_OUTPUT_RCT_CLK_OUT1    = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(54),    //!< Output type: rct_clk_out1
+    //GD_GPIO_TYPE_OUTPUT_SF_WP                                                                                                                                            GD_GPIO_OEN_SEL(18)                        | GD_GPIO_OUT_SEL(55),//!< Output type: sf_wp
+    //GD_GPIO_TYPE_OUTPUT_SF_HOLD
+    GD_GPIO_TYPE_OUTPUT_RCT_XOSC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(57),    //!< Output type: rct_xosc
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_0      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(58),//!< Output type: ephy_led[0] hcd ok
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_1      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(59),//!< Output type: ephy_led[1] duplex
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_2      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(60),//!< Output type: ephy_led[2] 10M CRS out
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_3      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(61),//!< Output type: ephy_led[3] 100M CRS out
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_4      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(62),//!< Output type: ephy_led[4] clo gs
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_0  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(63),//!< Output type: enet_phy_txd[0]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_1  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(64),//!< Output type: enet_phy_txd[1]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_2  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(65),//!< Output type: enet_phy_txd[2]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_3  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(66),//!< Output type: enet_phy_txd[3]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXER   = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(67),//!< Output type: enet_phy_txer
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXEN   = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(68),//!< Output type: enet_phy_txen
+    // GD_GPIO_TYPE_INOUT_ETH_MDIO                                                                                                                                                                                       GD_GPIO_OUT_SEL(20)
+    GD_GPIO_TYPE_OUTPUT_ENET_GMII_MDC_O = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(70),//!< Output type: enet_gmii_mdc_o
+    GD_GPIO_TYPE_OUTPUT_PWM7_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(71),//!< Output type: pwm7_out
+    GD_GPIO_TYPE_OUTPUT_PWM6_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(72),//!< Output type: pwm6_out
+    GD_GPIO_TYPE_OUTPUT_PWM5_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(73),//!< Output type: pwm5_out
+    GD_GPIO_TYPE_OUTPUT_PWM4_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(74),//!< Output type: pwm4_out
+
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_RESET  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 0),//!< Output type: enet_phy_reset
+
+    /* ----------------------------------- GPIO input function define ----------------------------------------------------------------------------------------------------------- */
+    GD_GPIO_TYPE_INPUT_0                = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(   0) | GD_GPIO_OUT_SEL( 0),//!< Input type: normal input
+    GD_GPIO_TYPE_INPUT_1                = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(   1) | GD_GPIO_OUT_SEL( 0),//!< Input type: normal input
+    GD_GPIO_TYPE_INPUT_SPI1_SI          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 0) | GD_GPIO_OUT_SEL( 0),//!< Input type: tssi_rxd
+    //GD_GPIO_TYPE_INOUT_I2C_DATA                                                                                                                                                                GD_GPIO_IN_SEL(2+ 1)
+    //GD_GPIO_TYPE_INOUT_I2C_CLK                                                                                                                                                                 GD_GPIO_IN_SEL(2+ 2)
+    //GD_GPIO_TYPE_INOUT_I2C_DATA2                                                                                                                                                               GD_GPIO_IN_SEL(2+ 3)
+    //GD_GPIO_TYPE_INOUT_I2C_CLK2                                                                                                                                                                GD_GPIO_IN_SEL(2+ 4)
+    GD_GPIO_TYPE_INPUT_UART2_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 5) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart2_rx
+    GD_GPIO_TYPE_INPUT_UART1_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 6) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart1_rx
+    GD_GPIO_TYPE_INPUT_UART0_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 7) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart0_rx
+    GD_GPIO_TYPE_INPUT_SPI0_SI          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 8) | GD_GPIO_OUT_SEL( 0),//!< Input type: ssi_rxd
+    GD_GPIO_TYPE_INPUT_SD_WP_N          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 9) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd_wp_n
+    GD_GPIO_TYPE_INPUT_SD_CD_N          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+10) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd_cd_n
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                                               GD_GPIO_IN_SEL(2+11)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                                               GD_GPIO_IN_SEL(2+12)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                                               GD_GPIO_IN_SEL(2+13)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                                               GD_GPIO_IN_SEL(2+14)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                                                GD_GPIO_IN_SEL(2+15)
+    GD_GPIO_TYPE_INPUT_SD1_WP_N         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+16) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd2_wp_n
+    GD_GPIO_TYPE_INPUT_SD1_CD_N         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+17) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd2_cd_n
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                                               GD_GPIO_IN_SEL(2+18)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                                               GD_GPIO_IN_SEL(2+19)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                                               GD_GPIO_IN_SEL(2+20)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                                               GD_GPIO_IN_SEL(2+21)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                                                GD_GPIO_IN_SEL(2+22)
+    //GD_GPIO_TYPE_INPUT_SF_HOLD                                                                                                                                           GD_GPIO_OEN_SEL(18)                          GD_GPIO_OUT_SEL( 0),//!< Input type: sf_hold
+    //GD_GPIO_TYPE_INPUT_SF_WP                                                                                                                                             GD_GPIO_OEN_SEL(19)                          GD_GPIO_OUT_SEL( 0),//!< Input type: sf_wp
+    //NULL
+    GD_GPIO_TYPE_INPUT_JTAG_TRSTN       = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+26) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_trstn
+    GD_GPIO_TYPE_INPUT_JTAG_TCK         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+27) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tck
+    GD_GPIO_TYPE_INPUT_JTAG_TMS         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+28) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tms
+    GD_GPIO_TYPE_INPUT_JTAG_TDI         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+29) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tdi
+    GD_GPIO_TYPE_INPUT_SENSOR_IDSP      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+30) | GD_GPIO_OUT_SEL( 0),//!< Input type: sensor_idsp_field
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_0   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+31) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[0]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_1   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+32) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[1]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_2   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+33) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[2]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_3   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+34) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[3]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_COL     = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+35) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_col
+    GD_GPIO_TYPE_INPUT_ENET_PHY_CRS     = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+36) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_crs
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXER    = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+37) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxer
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXDV    = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+38) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxdv
+    // GD_GPIO_TYPE_INOUT_ETH_MDIO                                                                                                                                                                                                                                             GD_GPIO_OEN_SEL(20)     GD_GPIO_IN_SEL(2+39)
+    GD_GPIO_TYPE_INPUT_ENET_CLK_RX      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+40) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_clk_rx
+    GD_GPIO_TYPE_INPUT_ENET_CLK_TX      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+41) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_clk_tx
+
+    /* ----------------------------------- GPIO input&&output function define --------------------------------------------------------------------------------------------------- */
+    GD_GPIO_TYPE_INOUT_I2C_DATA         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 3) | GD_GPIO_IN_SEL(2+ 1) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_sda
+    GD_GPIO_TYPE_INOUT_I2C_CLK          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 4) | GD_GPIO_IN_SEL(2+ 2) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_scl
+    GD_GPIO_TYPE_INOUT_I2C_DATA2        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 5) | GD_GPIO_IN_SEL(2+ 3) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_sda2
+    GD_GPIO_TYPE_INOUT_I2C_CLK2         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 6) | GD_GPIO_IN_SEL(2+ 4) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_scl2
+
+    GD_GPIO_TYPE_INOUT_SD_DATA_0        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 8) | GD_GPIO_IN_SEL(2+11) | GD_GPIO_OUT_SEL(18),    //!< Input/Output type: sd_data_out[0]
+    GD_GPIO_TYPE_INOUT_SD_DATA_1        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 9) | GD_GPIO_IN_SEL(2+12) | GD_GPIO_OUT_SEL(19),    //!< Input/Output type: sd_data_out[1]
+    GD_GPIO_TYPE_INOUT_SD_DATA_2        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(10) | GD_GPIO_IN_SEL(2+13) | GD_GPIO_OUT_SEL(20),    //!< Input/Output type: sd_data_out[2]
+    GD_GPIO_TYPE_INOUT_SD_DATA_3        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(11) | GD_GPIO_IN_SEL(2+14) | GD_GPIO_OUT_SEL(21),    //!< Input/Output type: sd_data_out[3]
+    GD_GPIO_TYPE_INOUT_SD_CMD           = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(12) | GD_GPIO_IN_SEL(2+15) | GD_GPIO_OUT_SEL(22),    //!< Input/Output : sd_cmd
+    GD_GPIO_TYPE_INOUT_SF_HOLD          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(18) | GD_GPIO_IN_SEL(2+23) | GD_GPIO_OUT_SEL(56),//!< Input/Output type: sf_hold
+    GD_GPIO_TYPE_INOUT_SF_WP            = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(19) | GD_GPIO_IN_SEL(2+24) | GD_GPIO_OUT_SEL(55),//!< Input/Output type: sf_wp
+    GD_GPIO_TYPE_INOUT_SD1_DATA_0       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(13) | GD_GPIO_IN_SEL(2+18) | GD_GPIO_OUT_SEL(26),    //!< Input/Output type: sd2_data_out[0]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_1       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(14) | GD_GPIO_IN_SEL(2+19) | GD_GPIO_OUT_SEL(27),    //!< Input/Output type: sd2_data_out[1]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_2       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(15) | GD_GPIO_IN_SEL(2+20) | GD_GPIO_OUT_SEL(28),    //!< Input/Output type: sd2_data_out[2]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_3       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(16) | GD_GPIO_IN_SEL(2+21) | GD_GPIO_OUT_SEL(29),    //!< Input/Output type: sd2_data_out[3]
+    GD_GPIO_TYPE_INOUT_SD1_CMD          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(17) | GD_GPIO_IN_SEL(2+22) | GD_GPIO_OUT_SEL(30),    //!< Input/Output : sd2_cmd
+
+    GD_GPIO_TYPE_INOUT_ETH_MDIO         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA) | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(20) | GD_GPIO_IN_SEL(2+39) | GD_GPIO_OUT_SEL(69),//!< Input/Output type: enet_gmii_mdi/enet_gmii_mod_o
+
+    GD_GPIO_TYPE_UNDEFINED              = 0,
+
+    GD_GPIO_TYPE_OUTPUT_AOMCLK          = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_OUTPUT_AOBCLK          = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_OUTPUT_AOLRCLK         = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_OUTPUT_AO_DATA0        = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_INPUT_I2S_CLK          = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_INPUT_I2S_WS           = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_INPUT_I2S_SI           = GD_GPIO_TYPE_UNDEFINED,
+    GD_GPIO_TYPE_INPUT_CLK_AU           = GD_GPIO_TYPE_UNDEFINED,
+
+}GD_GPIO_TYPE_E;
+
+#else
+typedef enum
+{
+
+    /* ----------------------------------- GPIO output function define ----------------------------------- */
+    GD_GPIO_TYPE_OUTPUT_0               = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 0),//!< Output type: value = 0
+    GD_GPIO_TYPE_OUTPUT_1               = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 1),//!< Output type: value = 1
+    GD_GPIO_TYPE_OUTPUT_SPI1_SO         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 2) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 2),//!< Output type: tssi_txd
+    GD_GPIO_TYPE_OUTPUT_SPI1_CS0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 3),//!< Output type: tssi_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SPI1_SCLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 4),//!< Output type: tssi_sclk_out
+    GD_GPIO_TYPE_OUTPUT_UART2_RTS_N     = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 5),//!< Output type: uart2_rts_n
+    GD_GPIO_TYPE_OUTPUT_UART2_DTR_N     = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 6),//!< Output type: uart2_dtr_n
+    GD_GPIO_TYPE_OUTPUT_UART2_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 7),//!< Output type: uart2_tx
+    GD_GPIO_TYPE_OUTPUT_UART1_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 8),//!< Output type: uart1_tx
+    GD_GPIO_TYPE_OUTPUT_UART0_TX        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL( 9),//!< Output type: uart0_tx
+    GD_GPIO_TYPE_OUTPUT_PWM3_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(10),//!< Output type: pwm3_out
+    GD_GPIO_TYPE_OUTPUT_PWM2_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(11),//!< Output type: pwm2_out
+    GD_GPIO_TYPE_OUTPUT_PWM1_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(12),//!< Output type: pwm1_out
+    GD_GPIO_TYPE_OUTPUT_PWM0_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(13),//!< Output type: pwm0_out
+    GD_GPIO_TYPE_OUTPUT_SPI0_SO         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 7) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(14),//!< Output type: ssi_txd
+    GD_GPIO_TYPE_OUTPUT_SPI0_CS1        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(15),//!< Output type: ssi_cs1_n
+    GD_GPIO_TYPE_OUTPUT_SPI0_CS0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(16),//!< Output type: ssi_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SPI0_SCLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(17),//!< Output type: ssi_sclk_out
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                         GD_GPIO_OEN_SEL( 8)                          GD_GPIO_OUT_SEL(18)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                         GD_GPIO_OEN_SEL( 9)                          GD_GPIO_OUT_SEL(19)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                         GD_GPIO_OEN_SEL(10)                          GD_GPIO_OUT_SEL(20)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                         GD_GPIO_OEN_SEL(11)                          GD_GPIO_OUT_SEL(21)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                          GD_GPIO_OEN_SEL(12)                          GD_GPIO_OUT_SEL(22)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_0                                                                                                                                        GD_GPIO_OEN_SEL(13)                          GD_GPIO_OUT_SEL(26)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_1                                                                                                                                        GD_GPIO_OEN_SEL(14)                          GD_GPIO_OUT_SEL(27)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_2                                                                                                                                        GD_GPIO_OEN_SEL(15)                          GD_GPIO_OUT_SEL(28)
+    //GD_GPIO_TYPE_INOUT_SD1_DATA_3                                                                                                                                        GD_GPIO_OEN_SEL(16)                          GD_GPIO_OUT_SEL(29)
+    //GD_GPIO_TYPE_INOUT_SDIO1_CMD                                                                                                                                         GD_GPIO_OEN_SEL(17)                          GD_GPIO_OUT_SEL(30)
+    GD_GPIO_TYPE_OUTPUT_SDIO_CLK        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_4MA)     | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(23),    //!< Output type: sd_clk_sdcard
+    GD_GPIO_TYPE_OUTPUT_SF_CS0          = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(24),    //!< Output type: sf_cs0_n
+    GD_GPIO_TYPE_OUTPUT_SF_CS1          = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(25),    //!< Output type: sf_cs1_n
+    GD_GPIO_TYPE_OUTPUT_SDIO1_CLK       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_4MA)     | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(31),    //!< Output type: sd2_clk_sdcard
+    GD_GPIO_TYPE_OUTPUT_JTAGE_TDO       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(32),    //!< Output type: jtag_tdout
+    GD_GPIO_TYPE_OUTPUT_VD_VSYNC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(33),    //!< Output type: lcd_vsync
+    GD_GPIO_TYPE_OUTPUT_VD_HSYNC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(34),    //!< Output type: lcd_hsync
+    GD_GPIO_TYPE_OUTPUT_VD_CLOCK        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(35),    //!< Output type: lcd_dclk
+    GD_GPIO_TYPE_OUTPUT_VD_HVLD         = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(36),    //!< Output type: lcd_hvld
+    GD_GPIO_TYPE_OUTPUT_VD_DATA0        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(37),    //!< Output type: lcd_data0
+    GD_GPIO_TYPE_OUTPUT_VD_DATA1        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(38),    //!< Output type: lcd_data1
+    GD_GPIO_TYPE_OUTPUT_VD_DATA2        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(39),    //!< Output type: lcd_data2
+    GD_GPIO_TYPE_OUTPUT_VD_DATA3        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(40),    //!< Output type: lcd_data3
+    GD_GPIO_TYPE_OUTPUT_VD_DATA4        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(41),    //!< Output type: lcd_data4
+    GD_GPIO_TYPE_OUTPUT_VD_DATA5        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(42),    //!< Output type: lcd_data5
+    GD_GPIO_TYPE_OUTPUT_VD_DATA6        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(43),    //!< Output type: lcd_data6
+    GD_GPIO_TYPE_OUTPUT_VD_DATA7        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(44),    //!< Output type: lcd_data7
+    GD_GPIO_TYPE_OUTPUT_VD_DATA8        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(45),    //!< Output type: lcd_data8
+    GD_GPIO_TYPE_OUTPUT_VD_DATA9        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(46),    //!< Output type: lcd_data9
+    GD_GPIO_TYPE_OUTPUT_VD_DATA10       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(47),    //!< Output type: lcd_data10
+    GD_GPIO_TYPE_OUTPUT_VD_DATA11       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(48),    //!< Output type: lcd_data11
+    GD_GPIO_TYPE_OUTPUT_VD_DATA12       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(49),    //!< Output type: lcd_data12
+    GD_GPIO_TYPE_OUTPUT_VD_DATA13       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(50),    //!< Output type: lcd_data13
+    GD_GPIO_TYPE_OUTPUT_VD_DATA14       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(51),    //!< Output type: lcd_data14
+    GD_GPIO_TYPE_OUTPUT_VD_DATA15       = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(52),    //!< Output type: lcd_data15
+    GD_GPIO_TYPE_OUTPUT_RCT_CLK_OUT2    = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(53),    //!< Output type: rct_clk_out2
+    GD_GPIO_TYPE_OUTPUT_RCT_CLK_OUT1    = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(54),    //!< Output type: rct_clk_out1
+    //GD_GPIO_TYPE_OUTPUT_SF_WP                                                                                                                                            GD_GPIO_OEN_SEL(18)                        | GD_GPIO_OUT_SEL(55),//!< Output type: sf_wp
+    //GD_GPIO_TYPE_OUTPUT_SF_HOLD
+    GD_GPIO_TYPE_OUTPUT_RCT_XOSC        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(57),    //!< Output type: rct_xosc
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_0      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(58),//!< Output type: ephy_led[0] hcd ok
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_1      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(59),//!< Output type: ephy_led[1] duplex
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_2      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(60),//!< Output type: ephy_led[2] 10M CRS out
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_3      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(61),//!< Output type: ephy_led[3] 100M CRS out
+    GD_GPIO_TYPE_OUTPUT_EPHY_LED_4      = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(62),//!< Output type: ephy_led[4] clo gs
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_0  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(63),//!< Output type: enet_phy_txd[0]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_1  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(64),//!< Output type: enet_phy_txd[1]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_2  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(65),//!< Output type: enet_phy_txd[2]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXD_3  = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(66),//!< Output type: enet_phy_txd[3]
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXER   = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(67),//!< Output type: enet_phy_txer
+    GD_GPIO_TYPE_OUTPUT_ENET_PHY_TXEN   = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(68),//!< Output type: enet_phy_txen
+    // GD_GPIO_TYPE_INOUT_ETH_MDIO                                                                                                                                                                                       GD_GPIO_OUT_SEL(20)
+    GD_GPIO_TYPE_OUTPUT_ENET_GMII_MDC_O = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(70),//!< Output type: enet_gmii_mdc_o
+    GD_GPIO_TYPE_OUTPUT_PWM7_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(71),//!< Output type: pwm7_out
+    GD_GPIO_TYPE_OUTPUT_PWM6_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(72),//!< Output type: pwm6_out
+    GD_GPIO_TYPE_OUTPUT_PWM5_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(73),//!< Output type: pwm5_out
+    GD_GPIO_TYPE_OUTPUT_PWM4_OUT        = GD_GPIO_FUNC(GD_GPIO_FUNC_OUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 0) | GD_GPIO_IN_SEL( 0)   | GD_GPIO_OUT_SEL(74),//!< Output type: pwm4_out
+
+    /* ----------------------------------- GPIO input function define ----------------------------------------------------------------------------------------------------------- */
+    GD_GPIO_TYPE_INPUT_0                = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(   0) | GD_GPIO_OUT_SEL( 0),//!< Input type: normal input
+    GD_GPIO_TYPE_INPUT_1                = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(   1) | GD_GPIO_OUT_SEL( 0),//!< Input type: normal input
+    GD_GPIO_TYPE_INPUT_SPI1_SI          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 0) | GD_GPIO_OUT_SEL( 0),//!< Input type: tssi_rxd
+    //GD_GPIO_TYPE_INOUT_I2C_DATA                                                                                                                                                                GD_GPIO_IN_SEL(2+ 1)
+    //GD_GPIO_TYPE_INOUT_I2C_CLK                                                                                                                                                                 GD_GPIO_IN_SEL(2+ 2)
+    //GD_GPIO_TYPE_INOUT_I2C_DATA2                                                                                                                                                               GD_GPIO_IN_SEL(2+ 3)
+    //GD_GPIO_TYPE_INOUT_I2C_CLK2                                                                                                                                                                GD_GPIO_IN_SEL(2+ 4)
+    GD_GPIO_TYPE_INPUT_UART2_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 5) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart2_rx
+    GD_GPIO_TYPE_INPUT_UART1_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 6) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart1_rx
+    GD_GPIO_TYPE_INPUT_UART0_RX         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 7) | GD_GPIO_OUT_SEL( 0),//!< Input type: uart0_rx
+    GD_GPIO_TYPE_INPUT_SPI0_SI          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 8) | GD_GPIO_OUT_SEL( 0),//!< Input type: ssi_rxd
+    GD_GPIO_TYPE_INPUT_SD_WP_N          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+ 9) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd_wp_n
+    GD_GPIO_TYPE_INPUT_SD_CD_N          = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+10) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd_cd_n
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                                               GD_GPIO_IN_SEL(2+11)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                                               GD_GPIO_IN_SEL(2+12)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                                               GD_GPIO_IN_SEL(2+13)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                                               GD_GPIO_IN_SEL(2+14)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                                                GD_GPIO_IN_SEL(2+15)
+    GD_GPIO_TYPE_INPUT_SD1_WP_N         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+16) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd2_wp_n
+    GD_GPIO_TYPE_INPUT_SD1_CD_N         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)      | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+17) | GD_GPIO_OUT_SEL( 0),//!< Input type: sd2_cd_n
+    //GD_GPIO_TYPE_INOUT_SD_DATA_0                                                                                                                                                               GD_GPIO_IN_SEL(2+18)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_1                                                                                                                                                               GD_GPIO_IN_SEL(2+19)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_2                                                                                                                                                               GD_GPIO_IN_SEL(2+20)
+    //GD_GPIO_TYPE_INOUT_SD_DATA_3                                                                                                                                                               GD_GPIO_IN_SEL(2+21)
+    //GD_GPIO_TYPE_INOUT_SDIO_CMD                                                                                                                                                                GD_GPIO_IN_SEL(2+22)
+    //GD_GPIO_TYPE_INPUT_SF_HOLD                                                                                                                                           GD_GPIO_OEN_SEL(18)                          GD_GPIO_OUT_SEL( 0),//!< Input type: sf_hold
+    //GD_GPIO_TYPE_INPUT_SF_WP                                                                                                                                             GD_GPIO_OEN_SEL(19)                          GD_GPIO_OUT_SEL( 0),//!< Input type: sf_wp
+    //NULL
+    GD_GPIO_TYPE_INPUT_JTAG_TRSTN       = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+26) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_trstn
+    GD_GPIO_TYPE_INPUT_JTAG_TCK         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+27) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tck
+    GD_GPIO_TYPE_INPUT_JTAG_TMS         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+28) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tms
+    GD_GPIO_TYPE_INPUT_JTAG_TDI         = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+29) | GD_GPIO_OUT_SEL( 0),//!< Input type: jtag_tdi
+    GD_GPIO_TYPE_INPUT_SENSOR_IDSP      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT( 0)| GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+30) | GD_GPIO_OUT_SEL( 0),//!< Input type: sensor_idsp_field
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_0   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+31) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[0]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_1   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+32) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[1]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_2   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+33) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[2]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_3   = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+34) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxd[3]
+    GD_GPIO_TYPE_INPUT_ENET_PHY_COL     = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+35) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_col
+    GD_GPIO_TYPE_INPUT_ENET_PHY_CRS     = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+36) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_crs
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXER    = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+37) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxer
+    GD_GPIO_TYPE_INPUT_ENET_PHY_RXDV    = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+38) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_phy_rxdv
+    // GD_GPIO_TYPE_INOUT_ETH_MDIO                                                                                                                                                                                                                       GD_GPIO_OEN_SEL(20)     GD_GPIO_IN_SEL(2+39)
+    GD_GPIO_TYPE_INPUT_ENET_CLK_RX      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+40) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_clk_rx
+    GD_GPIO_TYPE_INPUT_ENET_CLK_TX      = GD_GPIO_FUNC(GD_GPIO_FUNC_IN) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA)    | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 1) | GD_GPIO_IN_SEL(2+41) | GD_GPIO_OUT_SEL( 0),//!< Input type: enet_clk_tx
+
+    /* ----------------------------------- GPIO input&&output function define --------------------------------------------------------------------------------------------------- */
+    GD_GPIO_TYPE_INOUT_I2C_DATA         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 3) | GD_GPIO_IN_SEL(2+ 1) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_sda
+    GD_GPIO_TYPE_INOUT_I2C_CLK          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 4) | GD_GPIO_IN_SEL(2+ 2) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_scl
+    GD_GPIO_TYPE_INOUT_I2C_DATA2        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 5) | GD_GPIO_IN_SEL(2+ 3) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_sda2
+    GD_GPIO_TYPE_INOUT_I2C_CLK2         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 6) | GD_GPIO_IN_SEL(2+ 4) | GD_GPIO_OUT_SEL( 0),//!< Input/Output type: i2c_scl2
+
+    GD_GPIO_TYPE_INOUT_SD_DATA_0        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 8) | GD_GPIO_IN_SEL(2+11) | GD_GPIO_OUT_SEL(18),    //!< Input/Output type: sd_data_out[0]
+    GD_GPIO_TYPE_INOUT_SD_DATA_1        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL( 9) | GD_GPIO_IN_SEL(2+12) | GD_GPIO_OUT_SEL(19),    //!< Input/Output type: sd_data_out[1]
+    GD_GPIO_TYPE_INOUT_SD_DATA_2        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(10) | GD_GPIO_IN_SEL(2+13) | GD_GPIO_OUT_SEL(20),    //!< Input/Output type: sd_data_out[2]
+    GD_GPIO_TYPE_INOUT_SD_DATA_3        = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(11) | GD_GPIO_IN_SEL(2+14) | GD_GPIO_OUT_SEL(21),    //!< Input/Output type: sd_data_out[3]
+    GD_GPIO_TYPE_INOUT_SD_CMD           = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(12) | GD_GPIO_IN_SEL(2+15) | GD_GPIO_OUT_SEL(22),    //!< Input/Output : sd_cmd
+
+    GD_GPIO_TYPE_INOUT_SF_HOLD          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(18) | GD_GPIO_IN_SEL(2+23) | GD_GPIO_OUT_SEL(56),//!< Input/Output type: sf_hold
+    GD_GPIO_TYPE_INOUT_SF_WP            = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(0) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(19) | GD_GPIO_IN_SEL(2+24) | GD_GPIO_OUT_SEL(55),//!< Input/Output type: sf_wp
+
+    GD_GPIO_TYPE_INOUT_SD1_DATA_0       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(13) | GD_GPIO_IN_SEL(2+18) | GD_GPIO_OUT_SEL(26),    //!< Input/Output type: sd2_data_out[0]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_1       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(14) | GD_GPIO_IN_SEL(2+19) | GD_GPIO_OUT_SEL(27),    //!< Input/Output type: sd2_data_out[1]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_2       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(15) | GD_GPIO_IN_SEL(2+20) | GD_GPIO_OUT_SEL(28),    //!< Input/Output type: sd2_data_out[2]
+    GD_GPIO_TYPE_INOUT_SD1_DATA_3       = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(16) | GD_GPIO_IN_SEL(2+21) | GD_GPIO_OUT_SEL(29),    //!< Input/Output type: sd2_data_out[3]
+    GD_GPIO_TYPE_INOUT_SD1_CMD          = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_UP|IOCTRL_2MA)   | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(17) | GD_GPIO_IN_SEL(2+22) | GD_GPIO_OUT_SEL(30),    //!< Input/Output : sd2_cmd
+
+    GD_GPIO_TYPE_INOUT_ETH_MDIO         = GD_GPIO_FUNC(GD_GPIO_FUNC_INOUT) | GD_GPIO_IOCTRL(IOCTRL_PULL_DOWN|IOCTRL_2MA) | GD_GPIO_OEN_INVERT(1) | GD_GPIO_OUT_INVERT(0) | GD_GPIO_OEN_SEL(20) | GD_GPIO_IN_SEL(2+39) | GD_GPIO_OUT_SEL(69),//!< Input/Output type: enet_gmii_mdi/enet_gmii_mod_o
+
+    GD_GPIO_TYPE_UNDEFINED              = 0,
+} GD_GPIO_TYPE_E;
+#endif
+/*!
+*******************************************************************************
+**
+** \brief Interrupt trigger types.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+    GD_GPIO_INT_TRIGGER_LOW_LEVEL,    //!< Interrupt trigger on low level.
+    GD_GPIO_INT_TRIGGER_HIGH_LEVEL,   //!< Interrupt trigger on high level.
+    GD_GPIO_INT_TRIGGER_RISING_EDGE,  //!< Interrupt trigger on rising edge.
+    GD_GPIO_INT_TRIGGER_FALLING_EDGE,  //!< Interrupt trigger on falling edge.
+    GD_GPIO_INT_TRIGGER_BOTH_EDGE    //!< Interrupt trigger on both edge.
+}GD_GPIO_INT_TRIGGER_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Interrupt configuration.
+**
+** \sa    GD_GPIO_Open()
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    /*!
+    ** The interrupt trigger type.
+    */
+    GD_GPIO_INT_TRIGGER_E trigger;
+
+    /*!
+    ** Flag to enable/disable the interrupt.
+    */
+    GBOOL enable;
+
+    /*!
+    ** The notification function which shall be called when an interrupt
+    ** occurs.
+    */
+    void (*notifyFct)();
+}GD_GPIO_INT_CONFIG_S;
+
+/*!
+*******************************************************************************
+**
+** \brief GPIO cross reference between GPIO pins and functions.
+**
+** \sa GD_GPIO_Init()
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    U8             pin;
+    GD_GPIO_TYPE_E type;
+}GD_GPIO_XREF_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Parameters for initialisation.
+**
+** \sa GD_GPIO_Init()
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    /*!
+    ** General interrupt priority for all GPIO interrupts,
+    ** either #GD_INT_LOW_PRIORITY or #GD_INT_MID_PRIORITY.
+    */
+    S8              irqPriority;
+    U8              phyType;
+    U8              Reserve;
+    U16             xrefTableCount;
+    GD_GPIO_XREF_S* xrefTable;
+}GD_GPIO_INIT_PARAMS_S;
+
+/*
+*******************************************************************************
+**
+** \brief Available API functions.
+**
+*******************************************************************************
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_GPIO_Init(GD_GPIO_INIT_PARAMS_S* pInitParams);
+GERR GD_GPIO_Exit(void);
+GERR GD_GPIO_Open(U8 number, GD_GPIO_TYPE_E type, GD_GPIO_INT_CONFIG_S* pIntConfig, GD_HANDLE* pHandle);
+GERR GD_GPIO_Close(GD_HANDLE* pHandle);
+GERR GD_GPIO_CloseWithType(U32 type);
+GERR GD_GPIO_Read(GD_HANDLE handle, U8 *pBit);
+GERR GD_GPIO_Write(GD_HANDLE handle, U8 bit);
+GERR GD_GPIO_SetType(GD_HANDLE handle, GD_GPIO_TYPE_E type);
+GERR GD_GPIO_DisableInterrupt(void);
+GERR GD_GPIO_EnableInterrupt(void);
+GERR GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_E type, GD_HANDLE* pHandle);
+GERR GD_GPIO_ControlInvertData(GD_HANDLE handle, U8 modeValue);
+GERR GD_GPIO_ControlInvertEnable(GD_HANDLE handle, U8 modeValue);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 219 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_i2c.h

@@ -0,0 +1,219 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_i2c.h
+**
+** \brief     I2C.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#ifndef _GD_I2C_H_
+#define _GD_I2C_H_
+
+#include "gmodids.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+#define GD_I2C_ERR_BASE   (GD_I2C_MODULE_ID << 16)
+
+
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+/*!
+*******************************************************************************
+**
+** \brief I2C driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_I2C_TYPE_NOT_SUPPORTED = GD_I2C_ERR_BASE, //!< Device not supported.
+    GD_ERR_I2C_INT_ERR,
+    GD_ERR_I2C_NOT_OPEN,
+    GD_ERR_I2C_NOACK,
+    GD_ERR_I2C_START_NOACK,
+    GD_ERR_I2C_RESTART_NOACK,
+    GD_ERR_I2C_ADDR_NOACK,
+    GD_ERR_I2C_DATA_NOACK,
+    GD_ERR_I2C_READ_NOACK,
+    GD_ERR_I2C_SL_NACK,
+    GD_ERR_I2C_BUSY,
+    GD_ERR_I2C_FIFO_OVERFLOW,
+};
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+/*!
+*******************************************************************************
+**
+** \brief I2C channel number.
+**
+** \sa    GD_I2C_OPEN_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2C_CHANNEL_ONE = 0, //!< I2C channel 1.
+    GD_I2C_CHANNEL_TWO,     //!< I2C channel 2.
+}GD_I2C_CHANNEL_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I2C operition modes.
+**
+** \sa    GD_I2C_INIT_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2C_GENERIC_MASTER_MODE, //!< Generic master mode.
+    GD_I2C_GENERIC_SLAVER_MODE, //!< Generic slave mode.
+    GD_I2C_AUTO_MASTER_MODE,    //!< Auto master mode.
+    GD_I2C_AUTO_SLAVER_MODE,    //!< Auto slave mode.
+    GD_I2C_DMA_MASTER_MODE,     //!< DMA master mode.
+    GD_I2C_DMA_SLAVER_MODE,     //!< DMA slave mode.
+}GD_I2C_OPEN_MODE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Protocol modes.
+**
+** \sa    GD_I2C_SetProtocol()
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2C_COMMON_PROTOCOL = 0,  //!< Common protocol.
+    GD_I2C_RESTART_PROTOCOL,     //!< Protocol with restart.
+} GD_I2C_PROTOCOL_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I2C datarate speed modes.
+**
+** \sa    GD_I2C_OPEN_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2C_100KBPS = 100000, //!< 100kHz datarate.
+    GD_I2C_400KBPS = 400000,     //!< 400kHz datarate.
+}GD_I2C_SPEED_E;
+
+
+/*!
+*******************************************************************************
+**
+** \brief I2C datarate speed modes.
+**
+** \sa    GD_I2C_OPEN_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2C_NORMAL = 0,
+    GD_I2C_TURBO_MODE,  // write operation only.
+    GD_I2C_INTERRUPT,
+}GD_I2C_MODE_E;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+/*!
+*******************************************************************************
+**
+** \brief Init parameters.
+**
+** \sa    GD_I2C_Init() <BR>
+**        GD_I2C_OPEN_MODE_E
+**
+******************************************************************************/
+typedef struct
+{
+    GD_I2C_OPEN_MODE_E  mode;     //!< Operation mode.
+    S8                  priority; //!< IRQ priority e.g. \c #GD_INT_LOW_PRIORITY.
+    S8                  gpioSdaPinCh1; //!< GPIO SDA pin assigmnet channel 1.
+    S8                  gpioSclPinCh1; //!< GPIO SCL pin assigmnet channel 1.
+    S8                  gpioSdaPinCh2; //!< For future use.
+    S8                  gpioSclPinCh2; //!< For future use.
+}GD_I2C_INIT_PARAMS_S;
+
+typedef struct
+{
+    GD_I2C_CHANNEL_E        channel;
+    GD_I2C_SPEED_E          speed;
+    GD_I2C_MODE_E           mode;
+} GD_I2C_OPEN_PARAMS_S;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_I2C_Init(GD_I2C_INIT_PARAMS_S* paramsP);
+GERR GD_I2C_Exit(void);
+GERR GD_I2C_Open(GD_I2C_OPEN_PARAMS_S * openParamsP, GD_HANDLE* pHandle );
+GERR GD_I2C_Close(GD_HANDLE * pHandle);
+GERR GD_I2C_Read(GD_HANDLE *pHandle,U8 address,U8* regbuffer,U32 regbytes,U8 * buffer,U32 bytes);
+GERR GD_I2C_Write(GD_HANDLE *pHandle,U8 address,U8 * buffer,U32 bytes);
+GERR GD_I2C_SetOperationMode(GD_I2C_CHANNEL_E channel,GD_I2C_OPEN_MODE_E operationMode);
+GERR GD_I2C_SetProtocol(GD_HANDLE *handleP,GD_I2C_PROTOCOL_E protocol);
+GERR GD_I2C_SetMode(GD_HANDLE *handleP,GD_I2C_MODE_E Mode);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_I2C_H_ */
+
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 203 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_i2s.h

@@ -0,0 +1,203 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_i2s.h
+**
+** \brief     I2S.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#ifndef _GD_I2S_H_
+#define _GD_I2S_H_
+
+#include <gtypes.h>
+#include "gmodids.h"
+#include "gd_int.h"
+#include "gd_uart.h"
+
+
+typedef     GD_INT_DATA_S* (*GD_I2S_ISR_T)(U8 channelIndex);
+
+/*!
+*******************************************************************************
+**
+** \brief I2S driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_I2S_TYPE_NOT_SUPPORTED = 0, //!< Device not supported.
+    GD_ERR_I2S_INT_ERR,
+    GD_ERR_I2S_NOT_OPEN,
+    GD_ERR_I2S_BUSY,
+	GD_ERR_I2S_WAIT,    
+};
+
+/*!
+*******************************************************************************
+**
+** \brief i2s channel.
+**
+*******************************************************************************
+*/
+
+typedef enum
+{
+    GD_I2S_CHANNEL_2 = 0,     //!< I2S  2 channel.
+    GD_I2S_CHANNEL_4 = 1,     //!< I2S  4 channel.
+    GD_I2S_CHANNEL_6 = 2,     //!< I2S  6 channel.
+}GD_I2S_CHANNEL_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I2S operition modes.
+**
+** \sa    GD_I2S_MODE_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2S_LEFT_MODE  = 0,   //!< Left justify mode.
+    GD_I2S_RIGHT_MODE = 1,  //!< Right justify  mode.
+    GD_I2S_MSB_MODE   = 2,    //!< MSB extend mode.
+    GD_I2S_I2S_MODE   = 4,    //!< I2S mode.
+    GD_I2S_DSP_MODE   = 6,    //!< DSP mode.
+}GD_I2S_MODE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I2S datarate speed modes.
+**
+** \sa    GD_I2S_SPEED_E
+**
+******************************************************************************/
+typedef enum
+{
+	GD_I2S_24000BPS = 24000,
+    GD_I2S_32000BPS = 32000,     //!< 32kHz datarate.
+    GD_I2S_44100BPS = 44100,
+    GD_I2S_48000BPS = 48000,       //!< 48kHz datarate.
+    GD_I2S_96000BPS = 96000,
+}GD_I2S_SPEED_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I2S datarate wlen modes.
+**
+** \sa    GD_I2S_WLEN_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2S_16BIT = 16,     //!< 32kHz datarate.
+    GD_I2S_24BIT = 24,        //!< 48kHz datarate.
+}GD_I2S_WLEN_E;
+
+
+
+/*!
+*******************************************************************************
+**
+** \brief I2S operition modes.
+**
+** \sa    GD_I2S_OPEN_MODE_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_I2S_GENERIC_MASTER_MODE, //!< Generic master mode.
+    GD_I2S_GENERIC_SLAVER_MODE, //!< Generic slave mode.
+    GD_I2S_AUTO_MASTER_MODE,    //!< Auto master mode.
+    GD_I2S_AUTO_SLAVER_MODE,    //!< Auto slave mode.
+    GD_I2S_DMA_MASTER_MODE,     //!< DMA master mode.
+    GD_I2S_DMA_SLAVER_MODE,     //!< DMA slave mode.
+}GD_I2S_OPEN_MODE_E;
+
+
+enum
+{
+	I2S_EVENT_FRAME          = 1, /* received one audio frame or send finished one audio frame */
+    I2S_EVENT_WILL_OVERFLOW  = 2,
+	I2S_EVENT_WILL_UNDERFLOW = 3,	
+    I2S_EVENT_ALREADY_OVERFLOW  = 4,
+	I2S_EVENT_ALREADY_UNDERFLOW = 5,	
+	I2S_EVENT_UNDEFINED         = 6,
+};
+
+typedef void (*GD_I2S_Notifier)(U32 event);
+
+
+/*!
+*******************************************************************************
+**
+** I2S INIT  parameter.
+**
+******************************************************************************/
+typedef struct
+{
+   GBOOL               master;   
+   GD_I2S_CHANNEL_E    channel;
+   GD_I2S_MODE_E       mode;
+   GD_I2S_SPEED_E      speed;
+   GD_I2S_WLEN_E       wlen; 
+} GD_I2S_INIT_PARAM_S;
+
+
+typedef struct
+{
+   U32      		   frameSize;
+   GD_I2S_Notifier     notifier; 
+} GD_I2S_OPEN_PARAM_S;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_I2S_RX_Open(GD_I2S_OPEN_PARAM_S *openParams);
+GERR GD_I2S_RX_Enable(void);
+GERR GD_I2S_RX_Disable(void);
+GERR GD_I2S_RX_Read_Frame(U8 *data, U32 *length);
+GERR GD_I2S_RX_Close(void);
+GERR GD_I2S_TX_Open(GD_I2S_OPEN_PARAM_S *openParams);
+GERR GD_I2S_TX_Enable(void);
+GERR GD_I2S_TX_Disable(void);
+GERR GD_I2S_TX_Mute(void);
+GERR GD_I2S_TX_Unmute(void);
+GERR GD_I2S_TX_Write_Frame(U8 *data, U32 length);
+GERR GD_I2S_TX_Close(void);
+GERR GD_I2S_SetClock(GD_I2S_SPEED_E speed);
+GERR GD_I2S_SetWlen(GD_I2S_WLEN_E wlen);
+GERR GD_I2S_SetMode(GD_I2S_MODE_E mode);
+GERR GD_I2S_SetChannel(GD_I2S_CHANNEL_E channel);
+GERR GD_I2S_Init(GD_I2S_INIT_PARAM_S *initParams);
+GERR GD_I2S_Bind_Rx2Tx(void);
+GERR GD_I2S_Unbind_Rx2Tx(void);
+GERR GD_I2S_Exit(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_I2C_H_ */
+
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 250 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_int.h

@@ -0,0 +1,250 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_int.h
+**
+** \brief     INT (interrupt) driver
+**
+**            This driver provides functions and structures required to
+**            access the GK6202 interrupt engine.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+******************************************************************************/
+#ifndef GD_INT_H
+#define GD_INT_H
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+#define GD_VIC_INSTANCES        2
+#define GD_INT_VEC_OFFSET       32
+/*---------------------------------------------------------------------------*/
+/* constants and macros                                                      */
+/*---------------------------------------------------------------------------*/
+#define GD_INT_ERR_BASE (GD_INT_MODULE_ID<<16) //!< The INT base error code.
+
+/*!
+*******************************************************************************
+**
+** \anchor int_defines
+** \name   interrupt driver specific macros
+**
+** This section defines various macros required to control interrupts.
+**
+******************************************************************************/
+/*@{*/
+#define GD_INT_NO_INVERT_IRQ    0 //!< The IRQ signal is not inverted.
+#define GD_INT_INVERT_IRQ       1 //!< The IRQ signal is inverted.
+
+#define GD_INT_LOW_PRIORITY     0 //!< Fast Interrupt Request (FIQ) for fast, low latency interrupt handling
+#define GD_INT_MID_PRIORITY     1 //!< Interrupt Request (IRQ) for more general interrupts
+
+#define GD_INT_DISABLED         0 //!< Interrupts are disabled.
+#define GD_INT_ENABLED          1 //!< Interrupts are enabled.
+/*@}*/
+#define GD_INT_RISING_EDGE      0
+#define GD_INT_FALLING_EDGE     1
+#define GD_INT_BOTH_EDGES       2
+#define GD_INT_LEVEL_LOW        3
+#define GD_INT_LEVEL_HIGH       4
+/*!
+*******************************************************************************
+**
+** \brief Interrupt vectors
+**
+** The list below describes all available interrupt sources,
+** a table containing the real interrupt service routines can
+** be stored in the ARC aux. register 0x0203.
+**
+** The first three interrupt vectors are non-maskable, their
+** priorty is high.
+** All other interrupts are maskable and the priority can be set
+** either to medium (1) or low (2).
+**
+******************************************************************************/
+enum
+{
+    GD_INT_RESERVED1_00_IRQ   =  0,  //!<
+    GD_INT_ETH_IRQ            =  1,  //!< level, Ethernet 1
+    GD_INT_IDSP_ERROR_IRQ     =  2,  //!< edge, iDSP error
+	  GD_INT_XIU_TIMEOUT_IRQ		=  3,  //!< edge
+    GD_INT_RESERVED1_04_IRQ   =  4,  //!<
+    GD_INT_RESERVED1_05_IRQ   =  5,  //!<	
+    GD_INT_RESERVED1_06_IRQ   =  6,  //!<
+	  GD_INT_CODING_ORC_VOUT1_IRQ =7,  //!< edge, Coding Orc VOUT1
+    GD_INT_SD_CONTROLLER_IRQ  =  8,  //!< level, SD controller
+    GD_INT_IDC_IRQ            =  9,  //!< level, i2c read/write, I2C0
+    GD_INT_SSI_SPI_IRQ        = 10,  //!< level, Synchronous Serial Interface (SSI, SPI)    
+    GD_INT_WDT_IRQ            = 11,  //!< edge, Watchdog (WDT)
+    GD_INT_RESERVED1_12_IRQ   = 12,  //!<
+    GD_INT_SD2_CARD_DETECT_IRQ   = 13,  //!<
+    GD_INT_SD_CARD_DETECT_IRQ = 14,  //!< Both edges, SD card detect (state of SMIO5 pin)
+    GD_INT_UART1_IRQ          = 15,  //!< level, uart read/write, UART1
+    GD_INT_GPIO0_IRQ          = 16,  //!< level, GPIO0
+    GD_INT_RESERVED1_17_IRQ   = 17,  //!< level, UART2
+    GD_INT_TIMER1_IRQ         = 18,  //!< edge, timer#1
+    GD_INT_TIMER2_IRQ         = 19,  //!< edge, timer#2
+    GD_INT_TIMER3_IRQ         = 20,  //!< edge, timer#3
+    GD_INT_DMA_IRQ            = 21,  //!< level, DMA
+    GD_INT_SD2_CONTROLLER_IRQ = 22,  //!< level, SD2 controller
+    GD_INT_RESERVED1_23_IRQ   = 23,  //!<
+    GD_INT_CODING_ORC_VIN_IRQ = 24,  //!< edge, Coding Orc VIN
+    GD_INT_CORDING_ORC_VDSP_IRQ   = 25,  //!< edge, Cording Orc vDSP
+    GD_INT_USB_IRQ            = 26,  //!< level, USB
+    GD_INT_UART2_IRQ          = 27,  //!<
+    GD_INT_RESERVED1_28_IRQ   = 28,  //!<
+    GD_INT_AUDIO_I2S_TX_IRQ 	= 29,  //!< level, Audio (I2S) TX    
+    GD_INT_AUDIO_I2S_RX_IRQ 	= 30,  //!< level, Audio (I2S) RX
+    GD_INT_UART_IRQ           = 31,  //!< level, UART0
+#if (GD_VIC_INSTANCES >= 2)
+    GD_INT_RESERVED2_00_IRQ   = ( 0 + 32),  //!<
+    GD_INT_RESERVED2_01_IRQ   = ( 1 + 32),  //!<
+    GD_INT_RESERVED2_02_IRQ   = ( 2 + 32),  //!<
+    GD_INT_RESERVED2_03_IRQ   = ( 3 + 32),  //!<
+    GD_INT_RESERVED2_04_IRQ   = ( 4 + 32),  //!<
+    GD_INT_RESERVED2_05_IRQ   = ( 5 + 32),  //!<
+    GD_INT_RESERVED2_06_IRQ   = ( 6 + 32),  //!<
+    GD_INT_RESERVED2_07_IRQ   = ( 7 + 32),  //!<
+    GD_INT_AUDIO_PHY_TX_IRQ   = ( 8 + 32),  //!<level, Audio PHY TX INT
+    GD_INT_AUDIO_PHY_RX_IRQ   = ( 9 + 32),  //!<level, Audio PHY RX INT 
+    GD_INT_RESERVED2_10_IRQ   = (10 + 32),  //!<
+    GD_INT_RESERVED2_11_IRQ   = (11 + 32),  //!<
+    GD_INT_RESERVED2_12_IRQ   = (12 + 32),  //!<
+    GD_INT_RESERVED2_13_IRQ   = (13 + 32),  //!<
+    GD_INT_RESERVED2_14_IRQ   = (14 + 32),  //!<
+    GD_INT_RESERVED2_15_IRQ   = (15 + 32),  //!<
+    GD_INT_RESERVED2_16_IRQ   = (16 + 32),  //!<
+    GD_INT_RESERVED2_17_IRQ   = (17 + 32),  //!<*/
+    GD_INT_CODING_ORC_VOUT0_IRQ=(18 + 32),  //!< edge, Coding Orc VOUT0	 
+    GD_INT_CRYPTO_OUTPUT_READY_IRQ=(19 + 32),  //!< edge, AES/DES output ready from Crypt block--AES/DES finished
+    GD_INT_PERFORMANCE_MONITOR_IRQ=(20 + 32),  //!< 
+    GD_INT_RESERVED2_21_IRQ    = (21 + 32),  //!< 
+    GD_INT_GDMA_COMPLETION_IRQ = (22 + 32),  //!<edge, GDMA Completion
+    GD_INT_RESERVED2_23_IRQ   = (23 + 32),  //!<
+    GD_INT_ADC_LEVEL_CHANGE_IRQ=(24 + 32),  //!< level, ADC level change
+    GD_INT_RESERVED2_25_IRQ   = (25 + 32),  //!<
+    GD_INT_IDC2_IRQ           = (26 + 32),  //!< level, IDC2
+    GD_INT_IDSP_LAST_PIXEL_IRQ= (27 + 32),  //!< edge, iDSP last pixel
+    GD_INT_IDSP_VSYNC_IRQ     = (28 + 32),  //!< edge, iDSP Vsync (VIN on master mode)  
+    GD_INT_IDSP_SENSOR_VSYNC_IRQ=(29+ 32),  //!< edge, iDSP sensor Vsync (VIN on slave mode)
+    GD_INT_PMU_IRQ            = (30 + 32),  //!< level, PMU
+    GD_INT_SSI2_IRQ           = (31 + 32),  //!< level, SSI2
+#endif
+
+};
+
+// modify for rtos
+#define GD_INT_LAST_IRQ         (31 + 32)
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+/*!
+*******************************************************************************
+**
+** \brief Interrupt initialization parameter structure.
+**
+** \sa    GD_INT_Init()
+**
+******************************************************************************/
+typedef struct
+{
+    void (*resetFct)(void);         //!< The reset handler.
+    void (*memExceptionFct)(void);  //!< The memory exception handler.
+    void (*instructErrorFct)(void); //!< The Instruction Error handler.
+} GD_INT_INIT_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Interrupt driver open parameter structure.
+**
+** \sa    GD_INT_Open()
+**
+******************************************************************************/
+typedef struct
+{
+    S8 type;        //!< the interrupt vector to access
+    S8 active;      //!< activation, either GD_INT_INVERT_IRQ or GD_INT_NO_INVERT_IRQ
+    S8 sensitivity; //!< sensitivity, GD_INT_RISING_EDGE or GD_INT_FALLING_EDGE
+                    //!<    or GD_INT_BOTH_EDGES or GD_INT_LEVEL_LOW or GD_INT_LEVEL_HIGH
+    S8 priority;    //!< priority, either GD_INT_MID_PRIORITY or GD_INT_LOW_PRIORITY
+    union
+    {
+        GISR1 (*lowPrio)(void);
+        GISR2 (*midPrio)(void);
+    }isrFct;   //!< the interrupt service function
+} GD_INT_OPEN_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Interrupt processor function type.
+**
+******************************************************************************/
+/*! Pointer to the interrupt handler function of the driver. */
+typedef GISR1(*GD_ARM_INTR_IsrFuncT)(void);
+/*! //!< Pointer to the processing function of the driver. */
+typedef void(*GD_INT_PROCESSOR_F)(void* data);
+
+/*!
+*******************************************************************************
+**
+** \brief Interrupt driver data structure
+**
+******************************************************************************/
+typedef struct
+{
+    U32                     length;    //!< The length of the driver data in bytes.
+    void*                   data;      //!< Pointer to driver specific data structure.
+    GD_INT_PROCESSOR_F      processor; //!< Pointer to interrupt processing function.
+} GD_INT_DATA_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Interrupt handler function type
+**
+******************************************************************************/
+/*! Pointer to the interrupt handler function of the driver. */
+typedef GD_INT_DATA_S*(*GD_INT_HANDLER_F)(void);
+
+
+/*---------------------------------------------------------------------------*/
+/* function prototypes                                                       */
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GD_INT_Close(GD_HANDLE *handleP);
+GERR GD_INT_Init(GD_INT_INIT_PARAMS_S *initParams);
+GERR GD_INT_Open(GD_INT_OPEN_PARAMS_S *openParams, GD_HANDLE *handle);
+void GD_INT_GetIrqSettings(S8 type, S8 *prio, S8 *act, S8 *sens, S8 *mask);
+U32  GD_INT_GetUsedIrqs(void);
+void GD_INT_SetInterruptTrigger(S8 vec);
+void GD_INT_SetVector(S8 vector, void (*target)());
+void GD_INT_SetHandler(S8 vector, GD_INT_HANDLER_F handler);
+GD_INT_HANDLER_F GD_INT_GetHandler(S8 vector);
+void GD_INT_InvalidateDataCache(void);
+void GD_INT_InvalidateInstructionCache(void);
+void GD_INT_Enable(GD_HANDLE *handleP,U8 enable);
+
+void GD_INT_DisableAllInterrupts(void);
+void GD_INT_EnableAllInterrupts(void);
+
+void GD_IRQ_ISR(void);
+void GD_FIQ_ISR(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of gd_int.h */

+ 285 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_ir.h

@@ -0,0 +1,285 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_ir.h
+**
+** \brief     Infrared driver.
+**
+**            The infrared driver is designed for GOKE decoder and
+**            supports two functions:
+**            - IR Receiver
+**            - IR Transmitter
+**
+**            The first one is to receive the remote controller signal and
+**            decode it. The other function is to generate the infrared signal
+**            and transmit it to other devices. The transmitter can be used to
+**            control external devices for example a VCR or TV set.
+**            The driver supports only the access to the hardware layer and
+**            does not handle any IR protocols like RC5, RC6 or Kaseikyou.
+**            These protocols have to be implemented on the top of this driver.
+**
+**            The IR receiver is a pulse-width counter and is clocked by the
+**            output of a 54MHz clocked pre-scaler.
+**            Every time the pre-scaler generates an enable signal the IR
+**            receiver checks if an edge on the input signal has occurred.
+**            The edge sensitivity of the IR receiver is programmable.
+**            After the time value is received, the upper level application
+**            should analyse the stored data and parse them.
+**
+**            The IR transmitter is a pulse generator. It consists of two
+**            32bit registers to hold the data to be sent and
+**            a send_clock, a shift_clock, a compare and a mode register.
+**            Each time the sent clock counter counts to 0, the phase of the
+**            shift clock is inverted. The shift clock counter defines how
+**            many shift clocks are needed before shifting the data by one bit.
+**            The total number of 54MHz cycles per bit is therefore:
+**            2 x (prescaler +1) x (shift_clock_count + 1).
+**
+**            In IRDA mode the compare register defines how many of the
+**            sent clocks are output. When starting
+**            the module the data of the first register are sent (MSB first).
+**            When a data word (32bit) is finished the module checks if data
+**            is available in the second register. If yes, this register is
+**            copied into the first register and sent afterwards.
+**            At the same time, an IRQ is generated to tell the system that
+**            new data are required.
+**            All data have to be written to register1 except the first 32bit
+**            to be sent.
+**
+**            Following are the IR sending out signal:
+**
+**            \image html gd_ir_timings.gif
+**
+**            - T1 = 2 x 1/54MHz x ( prescaler + 1 )
+**            - T2 = T1 x ( shift_clock_count + 1 )
+**            - T3 = T1 x ( comp_val + 1 )
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+******************************************************************************/
+#ifndef _GD_IR_H_
+#define _GD_IR_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+/*---------------------------------------------------------------------------*/
+/* constants and macros                                                      */
+/*---------------------------------------------------------------------------*/
+#ifdef BOARD_FPGA
+#define IR_INPUT_CLK                24000000    // for 27MHZ Crystal
+#else
+#define IR_INPUT_CLK                24000000    // for 24MHZ Crystal
+#endif
+
+#define IR_FREQ                     38          // for NEC unit:MHz
+
+/********************************/
+/*     IRQ_EN_MASK Register              */
+/********************************/
+#define     IRQ_EN_RTC      (1<<0)
+#define     IRQ_EN_IRR      (1<<1)
+#define     IRQ_EN_GPIO     (1<<3)
+#define     IRQ_EN_IRT      (1<<6)
+
+
+#define GD_IR_ERR_BASE              (GD_IR_MODULE_ID<<16)    //!< Error base value.
+
+#define GD_IR_EDGE_FLAG             0x0100
+#define GD_IR_VAL_BIT_MASK          0x00FF
+#define GD_IR_TRANSFER_MAX_DATA     32
+
+/*!
+*******************************************************************************
+**
+** \brief IR driver error codes.
+**
+******************************************************************************/
+enum
+{
+    GD_ERR_IR_NO_SEQUENCE = GD_IR_ERR_BASE, //!< No sequence stored in IR buffer.
+    GD_ERR_IR_TRANSMIT_INPROCESS,   //!< IR transmission not finished yet.
+    GD_ERR_IR_TRANSMIT_FAILURE,     //!< IR transmission failed.
+};
+
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+/*!
+*******************************************************************************
+**
+** \brief IR type definitions.
+**
+******************************************************************************/
+typedef enum
+{
+    GD_IR_RECEIVER = 1,   //!< Receiver function.
+    GD_IR_TRANSMITTER,    //!< Transmitter function.
+} GD_IR_TYPE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief IR driver status.
+**
+******************************************************************************/
+typedef enum
+{
+    GD_IR_RECEIVER_OPENED    = 1,   //!< IR receiver is open.
+    GD_IR_TRANSMITTER_OPENED = 2,   //!< IR transmitter is open.
+} GD_IR_STATUS_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Transmitter configuration parameters.
+**
+******************************************************************************/
+typedef struct
+{
+    U8  programming;     //!< Programming register configuration.
+    U16 prescaler;       //!< IRDA clock register configuration.
+    U8  shift_counter;   //!< IRDA shift clock register configuration.
+    U8  compare_value;   //!< Compare value register configuration.
+    S8  gpioIrtPin;      //!< GPIO Pin to be assigned for IRT function.
+} GD_IR_TRANS_CONFIG_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Receiver configuration parameters.
+**
+******************************************************************************/
+typedef struct
+{
+    U16 prescaler;       //!< Prescaler for IR receiver.
+    S8  gpioIrrPin;      //!< GPIO Pin to be assigned for IRR function.
+} GD_IR_RECEV_CONFIG_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Driver init parameters.
+**
+** \sa    GD_IR_Init()
+**
+******************************************************************************/
+typedef struct
+{
+    void (*notifyFunction)(); //!< Pointer to notification function.
+} GD_IR_INIT_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Open parameters.
+**
+** \sa    GD_IR_Open()
+**
+******************************************************************************/
+typedef struct
+{
+    GD_IR_TYPE_E         type;         //!< Receiver or transmitter.
+    GD_IR_TRANS_CONFIG_S irt_config_s; //!< Configuration of transmitter.
+    GD_IR_RECEV_CONFIG_S irr_config_s; //!< Configuration of receiver.
+} GD_IR_OPEN_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Data property for IR transmitter.
+**
+**        This structure defines the property of the transmitting
+**        data, the width for logic 1 and logic 0
+**        and the valid bits of the value of width.
+**
+** \sa    GD_IR_SetParams()
+**
+******************************************************************************/
+typedef struct
+{
+    U16 nValidbit0;   //!< Valid bits of the value for logic 0.
+    U16 bitvalue0;    //!< Value for logic 0.
+    U16 nValidbit1;   //!< Valid bits of the value for logic 1.
+    U16 bitvalue1;    //!< Value for logic 1.
+} GD_IR_DATA_PROPERTY_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Insert data structure for IR transmitter.
+**
+**        This structure defines the header and footer or some other parts
+**        for the transmitter to insert the logic 0 or logic 1 into the
+**        output buffer.
+**
+** \sa    GD_IR_SetParams()
+**
+******************************************************************************/
+typedef struct
+{
+    U16 number;       //!< Number of logic bit to be inserted.
+    U8  bit;          //!< Logic 0 or logic 1.
+} GD_IR_INSERT_S;
+
+/*!
+*******************************************************************************
+**
+** \brief Output data structure for IR transmitter.
+**
+**        This structure defines the data value and the valid bits of this
+**        data.
+**
+** \sa    GD_IR_SetParams()
+**
+******************************************************************************/
+typedef struct
+{
+    U8 value;         //!< Data value in byte.
+    U8 validbit;      //!< Valid bit of this data.
+} GD_IR_DATA_S;
+
+/*---------------------------------------------------------------------------*/
+/* function prototypes                                                       */
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_IR_Close(GD_HANDLE *pHandle);
+GERR GD_IR_Init(GD_IR_INIT_PARAMS_S *pInitParams);
+GERR GD_IR_IrtOpen(GD_IR_OPEN_PARAMS_S *pOpenParams, GD_HANDLE *pHandle);
+GERR GD_IR_IrrOpen(GD_IR_OPEN_PARAMS_S *pOpenParams, GD_HANDLE *pHandle);
+
+GERR GD_IR_Receive(GD_HANDLE handle, U16 *pData, U16 num);
+void GD_IR_SetNotifyFunction(void(*nfyFunc)());
+
+GERR GD_IR_SetParams(GD_HANDLE             handle,
+                     GD_IR_INSERT_S        *header,
+                     U8                    nheader,
+                     GD_IR_DATA_S          *data,
+                     U8                    ndata,
+                     GD_IR_DATA_PROPERTY_S *dataproperty,
+                     GD_IR_INSERT_S*       footer,
+                     U8                    nfooter,
+                     U32                   *pSendBuffer,
+                     U16                   *pSendNumber);
+
+GERR GD_IR_Status(GD_HANDLE handle, U16* pNum);
+GERR GD_IR_Transmit(GD_HANDLE handle, U32 *pData, U16 num);
+typedef void (*GD_RTC_NOTIFY)(void);
+void  GD_RTC_RegisterNotify(GD_RTC_NOTIFY rtcNotifyFunc,U32 preCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GD_IR_H_ */
+/* end of gd_ir.h */

+ 84 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_pwm.h

@@ -0,0 +1,84 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_pwm.h
+**
+** \brief     pwm driver.
+**
+**            The driver provides functions to use the GK7101's PWM
+**            interface.
+**
+**           Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+******************************************************************************/
+#ifndef _GD_PWM_H_
+#define _GD_PWM_H_
+#endif
+#include <gtypes.h>
+#include <gmodids.h>
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+/*!
+*******************************************************************************
+**
+** \brief PWM channel number.
+**
+**
+******************************************************************************/
+#define GD_PWM_COUNT       8
+/*!
+*******************************************************************************
+**
+** \brief PWM operition modes.
+**
+** \sa    GD_PWM_INIT_PARAMS_S
+**
+******************************************************************************/
+typedef enum
+{
+    GD_NORMAL_SPEED,
+    GD_SYNC_SPEED,
+}GD_PWM_MODE_E;
+
+typedef struct
+{
+    U8   channel;    /* 0 ~ 3 */
+    U16  xon;        /* 0x00 ~ 0xffff */
+    U16  xoff;       /* 0x00 ~ 0xffff */
+}GD_PWM_DUTY_S;
+
+typedef enum
+{
+    GD_PWM_NO_ERR = 0,
+    GD_PWM_ERR_NOT_SUPPORTED_CHANNEL,
+    GD_PWM_ERR_NOT_SUPPORTED_FREQUENCY,
+    GD_PWM_ERR_NOT_SUPPORTED_RANGE,
+    GD_PWM_ERR_WRONG_DUTY_CONFIGURATION,
+    GD_PWM_ERR_RANGE_EXCEED_LIMIT,
+}GD_PWM_ERROR_CODE_E;
+
+GERR GD_PWM_Init();
+GERR GD_PWM_Cycle(U8 channel, U32 highLevelCnt, U32 lowLevelCnt);
+GERR GD_PWM_Set_Mode(U8 channel, U8 mode);
+GERR GD_PWM_Get_Mode(U8 channel, GD_PWM_MODE_E *mode);
+GERR GD_PwmOnOff(U8 channel,U32 on);
+GERR GD_PWM_Open(U8 channel,U32 iomode);
+GERR GD_PWM_Close(U8 channel);
+GD_PWM_ERROR_CODE_E GD_PWM_Set_Param(U8 channel, U32 frequency, U32 range, U32 duty);
+GERR GD_PWM_Get_Param(U8 channel, U32 *frequency, U32 *duty);
+GERR GD_PWM_Get_Status(U8 channel, U32 *status);
+GERR GD_PWM_Set_Clock_Divider(U8 channel, U8 divider);
+GERR GD_PWM_Set_Speed(U8 channel, U16 speed);
+GERR GD_PWM_Get_Speed(U8 channel, U16 *speed);
+GERR GD_PWM_Set_Duty(GD_PWM_DUTY_S *pwm_duty);
+GERR GD_PWM_Get_Duty(GD_PWM_DUTY_S *pwm_duty);
+
+

+ 244 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_sdio.h

@@ -0,0 +1,244 @@
+#ifndef _GD_SDIO_H_
+#define _GD_SDIO_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+#define GD_SDIO0                0
+#define GD_SDIO1                1
+
+
+/*!
+*******************************************************************************
+**
+** SDIO OPEN  parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    U32    isConnected;
+    U32    sectorSize;
+    U32    sectorCount;
+    U32    mediaType;
+    U32    manufacturerID;
+    U32    applicationID;
+    U32    productRevision;
+    U32    serialNumber;
+    U32    dataIoNumber;
+    U8     productName[5];
+}GD_SDIO_VolumeInfoT;
+
+
+/*!
+*************************************************************************
+** \brief Version of the SDIO driver.
+**
+** This number consists of a \b major version number stored in bits
+** 16 to 31 (upper word) and a \b minor version number stored in bits
+** 0 to 15 (lower word).
+** - The \b major number has to be increased when a parameter change
+**   occurs for the existing driver's API after its first release.
+** - The \b minor number has to be increased when functions are added to
+**   the existing driver's API after its first release.
+**
+** \note This value has to be assigend to the \b version field of the
+**       GAPI_SDIO_OpenParamsT structure.
+**
+*************************************************************************
+*/
+
+typedef enum {
+    GAPI_SDIO_VERSION = (S32)0x00010000 //!< The current driver version
+} GD_SDIO_VersionEnumT;
+
+
+ typedef enum {
+    GAPI_SDIO_TRANSFER_TYPE_NORMAL = 0,     //!< Normal transfer type for SD/SDHC/MMC cards (default)
+    GAPI_SDIO_TRANSFER_TYPE_DIRECT,         //!< Direct transfer mode special for SDIO cards
+    GAPI_SDIO_TRANSFER_TYPE_SECURE,         //!< Spezial secure transfer mode for SD-Cards
+    GAPI_SDIO_TRANSFER_TYPE_WIFI
+} GD_SDIO_TransferTypeEnumT;
+
+typedef enum
+{
+    CARDTYPE_NONE = 0,
+    CARDTYPE_MMC,
+    CARDTYPE_SD10,
+    CARDTYPE_SD11,
+    CARDTYPE_SD20
+}GD_SDIO_Card_Type;
+
+ /*!
+****************************************************************************
+**
+** \brief SDIO callback function signature
+**
+** This is the callback function signature required by the SDIO driver
+** for internally notification functions.
+**
+** \param comState  Comunication status.
+** \param optArgPtr Optional arg pointer.
+**
+****************************************************************************
+*/
+typedef void (*GD_SDIO_NotifyFuncT)(U32 index, U32 comState, void* optArgPtr);
+
+typedef void (*GD_SDIO_IRQFuncT)();
+typedef void (*GD_SDIO_RESETFuncT)(U32 index);
+
+
+/*!
+*************************************************************************
+** \brief Open parameters for the SDIO driver.
+**
+** This data structure covers all parameters which need to be specified
+** when an instance of the driver is opened.
+**
+*************************************************************************
+*/
+typedef struct {
+    /*!
+       The version of the driver.
+       \ref GAPI_SDIO_VersionEnumT "GAPI_SDIO_VERSION".
+    */
+    GD_SDIO_VersionEnumT version;
+	GD_SDIO_TransferTypeEnumT type;
+    /*!
+    ** The handle specific notification function.
+    */
+    GD_SDIO_NotifyFuncT  notifyFunc;
+
+	GD_SDIO_IRQFuncT	irqFunc;
+
+	GD_SDIO_RESETFuncT resetFunc;
+    /*!
+    ** Optional data pointer for the notification function.
+    */
+    void*                notifyFuncOptPtr;
+    /*!
+       Flag to request DMA for read/write transfer operation.
+    */
+    U32       			isUseDmaWay;
+} GD_SDIO_OpenParamsT;
+
+/*cid info */
+typedef struct
+{
+    U8    MID;        /*Manufacturer ID            width:8[127:120]*/
+    U16   OID;        /*OEM/Application ID       width:16[119:104]*/
+    U8    PNM[5];     /*Product name               width:40[103:64]*/
+    U8    PRV;        /*Product revision            width:8[63:56]*/
+    U32   PSN;        /*Product serial number    width:32[55:24]*/
+    U16   MDT;        /*Manufacturing date        width:12[19:8]*/
+}sdioCidInfo;
+
+/*I just care about usefull info of CSD*/
+typedef struct
+{
+    U8    csdStructure;        /*csd revision*/
+    U32   classes;            /*Describes the card command classes  CCC*/
+    U32   tranSpeed;           /*transfer speed*/
+    U8    eraseBlkEn;          /*erase block enable*/
+    U8    permWriteProtect;    /*write protect*/
+    U8    tmpWriteProtect;     /*write protect*/
+}sdiocsdInfo;
+
+/*I just case ablot usefull info of SCR*/
+typedef struct
+{
+    U32    scrStructure;        // SCR Register Structure Version
+    U32    sdSpec;              // Describes the Physical Layer Specification Version supported by the card.
+    U32    stateaftererase;     // Defines the data status after erase, whether it is 0 or 1.
+    U32    sdSecurity;          // Describes the Security Specification Version supported by the card.
+    U32    sdBusWith;           // Describes all the DAT bus widths that are supported by this card.
+}sdioScrInfo;
+
+/*Card capacity classification*/
+typedef enum 
+{
+    CARDCAPACITY_SDSC = 0,
+    CARDCAPACITY_SDHC_OR_SDXC
+}GD_SDIO_Card_Capacity;
+
+typedef struct
+{
+    U32    index;                /*index of handle array*/
+    U32    ocr;                  /*card volage info*/
+    U32    csd[4];               /*csd info (invert)*/
+    U32    read_bl_len;
+    U32    write_bl_len;
+    U64    capacity_user;
+    U32    sectorcount;
+    U32    inhighspeed;
+    U32    maxTransferBlk;
+    U32    eraseGrpSize;
+    sdioScrInfo    scr;
+    sdiocsdInfo    csdInfo;
+    U32    tran_speed;              /*max transfer speed*/
+    U32    rca;                     /*card address*/
+    U32    cid[4];                  /*card  cid info*/
+    GD_SDIO_Card_Type    type;      /*card type*/
+    GD_SDIO_Card_Capacity capacity; /*card capacity*/
+    U32    highCapacity;            /*is high capacity*/
+    sdioCidInfo    cidInfo;
+}sdioBlockT;
+
+/* SDIO specific handle */
+typedef struct
+ {
+     U32                   inUse;        /* specifies if handle is in use */
+     U32                   index;        /*index of handle array*/
+     GD_SDIO_OpenParamsT openParams;   /* open params of the handle */
+     sdioBlockT            devicePtr;    /* pointer to hardware device */
+ } sdioHandleT;
+
+typedef struct
+{
+    U32    IRQStatus;  /*!< content of IRQ status register.*/
+}SDIO_DATA_S;
+
+#define    GD_SDIO_ERR_BASE    (GD_SDIO_MODULE_ID<<16)
+//#define    SDIO_INT_MODE
+enum
+{
+    GD_ERR_SDIO_CARD_INIT_FAILED = GD_SDIO_ERR_BASE,
+    GD_ERR_SDIO_INT_ERR,
+    GD_ERR_SDIO_NO_CARD,
+    GD_ERR_SDIO_CARD_BUSY,
+    GD_ERR_SDIO_READ_FAILED,
+    GD_ERR_SDIO_WRITE_FAILED,
+    GD_ERR_SDIO_ERASE_FAILED,
+    GD_ERR_SDIO_CMD_NO_SUPPORTED,
+    GD_ERR_SDIO_SET_BLOCK_SIZE,
+    GD_ERR_SDIO_CMD_FAILED,
+    GD_ERR_SDIO_CARD_LOCKED
+};
+
+
+
+/*!
+*******************************************************************************
+**
+** SDIO API functions.
+**
+******************************************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_SDIO_Init(GD_SDIO_OpenParamsT* openParamsP, U32 index);
+GERR GD_SDIO_Exit(sdioHandleT *sdiohandle, U32 index);
+GERR GD_SDIO_Rsponse(void);
+GERR GD_SDIO_Open(GD_SDIO_OpenParamsT *openParamsP,sdioHandleT *pHandle, U32 index);
+GERR GD_SDIO_Close(sdioHandleT *sdiohandle, U32 index);
+GERR GD_SDIO_ReadSector(sdioHandleT * sdiohandle, U32 startblk, void* buffer, U32 blkcount);
+GERR GD_SDIO_WriteSector(sdioHandleT * sdiohandle, U32 startblk, void* buffer, U32 blkcount);
+GERR GD_SDIO_EraseSector(sdioHandleT * sdiohandle, U32 start, U32 blkcnt);
+GERR GD_SDIO_GetCardInfo(sdioHandleT * sdiohandle, GD_SDIO_VolumeInfoT *info,U32 index);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 375 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_sflash.h

@@ -0,0 +1,375 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_sflash.h
+**
+** \brief     Serail Flash memory driver.
+**
+**            (C) Goke Microelectronics China 2002 - 2007
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+*******************************************************************************
+*/
+#ifndef GD_SFLASH_H
+#define GD_SFLASH_H
+
+#include <gtypes.h>
+#include <gmodids.h>
+#include "gd_spi.h"
+
+#define SFLASH_NOT_SUPPORT      0x00000000
+
+#define SPANSION_MID            0x01
+#define EON_MID                 0x1C
+#define XMC_MID                 EON_MID
+#define NUMONYX_MID             0x20
+#define ATO_MID                 0x9B
+#define ISSI_MID                0x9D
+#define SST_MID                 0xBF
+#define MXIC_MID                0xC2
+#define GIGA_MID                0xC8
+#define ESMT_MID                0xC8
+#define WINBOND_MID             0xEF
+#define FIDELIX_MID             0xF8
+/*!
+*******************************************************************************
+**
+** \brief Flash channel number.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+    GD_SFLASH_CHANNEL_0 = 0x00,     // used sflash module, channel 0
+    GD_SFLASH_CHANNEL_1,            // used sflash module, channel 1
+    GD_SFLASH_SPI_CHANNEL_0_0,      // used spi module, spi 0, channel 0
+    GD_SFLASH_SPI_CHANNEL_0_1,      // used spi module, spi 0, channel 1
+    GD_SFLASH_SPI_CHANNEL_0_2,      // not used
+    GD_SFLASH_SPI_CHANNEL_0_3,      // not used
+    GD_SFLASH_SPI_CHANNEL_0_4,      // used spi module, spi 0, channel 4
+    GD_SFLASH_SPI_CHANNEL_0_5,      // used spi module, spi 0, channel 5
+    GD_SFLASH_SPI_CHANNEL_0_6,      // used spi module, spi 0, channel 6
+    GD_SFLASH_SPI_CHANNEL_0_7,      // used spi module, spi 0, channel 7
+    GD_SFLASH_SPI_CHANNEL_1_0,      // used spi module, spi 1, channel 0
+    GD_SFLASH_CHANNEL_0_DIE1 = 0x10,// used sflash module, channel 0, die 1
+    GD_SFLASH_CHANNEL_1_DIE1,       // used sflash module, channel 1, die 1
+    GD_SFLASH_SPI_CHANNEL_0_0_DIE1, // used spi module, spi 0, channel 0
+    GD_SFLASH_SPI_CHANNEL_0_1_DIE1, // used spi module, spi 0, channel 1
+    GD_SFLASH_SPI_CHANNEL_0_2_DIE1, // not used
+    GD_SFLASH_SPI_CHANNEL_0_3_DIE1, // not used
+    GD_SFLASH_SPI_CHANNEL_0_4_DIE1, // used spi module, spi 0, channel 4
+    GD_SFLASH_SPI_CHANNEL_0_5_DIE1, // used spi module, spi 0, channel 5
+    GD_SFLASH_SPI_CHANNEL_0_6_DIE1, // used spi module, spi 0, channel 6
+    GD_SFLASH_SPI_CHANNEL_0_7_DIE1, // used spi module, spi 0, channel 7
+    GD_SFLASH_SPI_CHANNEL_1_0_DIE1, // used spi module, spi 1, channel 0
+    GD_SFLASH_CHANNEL_NUM
+}GD_SFLASH_CHANNEL_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Flash IOx Mode.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+   GD_SFLASH_IO1_MODE = 1,
+   GD_SFLASH_IO2_MODE = 2,
+   GD_SFLASH_IO4_MODE = 4
+}GD_SFLASH_IO_MODE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Flash read or write.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+   GD_SFLASH_READ = 0,
+   GD_SFLASH_WRITE
+}GD_SFLASH_RW_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Flash Type.
+**
+*******************************************************************************
+*/
+typedef enum
+{
+   GD_SPI_NOR = 0,     // normal SPI nor-flash
+   GD_SPI_NAND         // SPI nand-flash
+}GD_SFLASH_TYPE_E;
+
+/*
+*******************************************************************************
+**
+** serial flash specific commands and statis register bit definitions
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    U32 read_ID;            // command to read the chip identification
+    U32 write_enable;       // command to enable a write/erase sequence
+    U32 write_disable;      // command to disable a write/erase sequence
+    U32 read_status;        // command to read from status register
+    U32 read_status2;       // command to read from status register
+    U32 write_status;       // command to write to status register
+    U32 read_data;          // command to read data
+    U32 read_io2;           // command to read data by IO2
+    U32 read_io4;           // command to read data by IO4
+    U32 program_page;       // command to program a sector page
+    U32 program_page2;      // command to program a sector page by IO2
+    U32 program_page4;      // command to program a sector page by IO4
+    U32 erase_sector;       // command to erase a single sector
+    U32 erase_chip;         // command to erase the entire chip
+    U32 read_ext_addr;      // command to read_ext_addr
+    U32 write_ext_addr;     // command to write_ext_addr
+    U32 die_sel;            // command to die_sel
+    U32 status_mask_wip;    // status register mask for bit write-in-progress
+    U32 status_mask_wel;    // status register mask for bit write-enable-latch
+    U32 page_read;          // command to read page to cache,                 new added for spi-nand
+    U32 program_execute;    // command to execute program from cache to page, new added for spi-nand
+    U32 reset;              // command to reset chip                          new added for spi-nand
+}GD_SFLASH_CMD_S;
+
+
+/*
+*******************************************************************************
+**
+** serial flash specific geometry and information data structure
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    U8               manufacture_ID;    // Manufacture identification
+    U8               commbo;            //
+    U32              device_ID;         // Device identification (memory type/capacity)
+    char*            manufacture_name;  // Pointer to manufacture name
+    char*            device_name;       // Pointer to device name
+    U32              device_bytes;      // Size of flash device in bytes
+    U32              sector_count;      // Number of sectors
+    U32              sector_bytes;      // Size of a single flash sector in bytes
+    U32              sector_pages;      // Number of pages per sector
+    U32              page_bytes;        // Size of a programmable page in bytes
+    GD_SFLASH_CMD_S* commands;          // Device specific access commands
+    U32              feature;           // bit[0:3] for read, bit[4:7] for write
+    U16              lock_mask;         // status register mask for bit write-protect
+    U16              io4_mask;          // status register mask for bit enable io4
+    GD_SFLASH_TYPE_E type;              // SPI nor flash or nand flash
+}GD_SFLASH_DEV_S;
+
+typedef struct
+{
+    void (*GH_SFLASH_set_Handle)(GD_SPI_STATUS_PARAMS_S*);
+    void (*GH_SFLASH_set_Command)(U32);
+    void (*GH_SFLASH_set_Data)(U32);
+    U32  (*GH_SFLASH_get_Data)(void);
+    void (*GH_SFLASH_set_CE)(U32);
+    U32  (*GH_SFLASH_get_CE)(void);
+    U8   (*GH_SFLASH_get_CE_CHSELECT)(void);
+    void (*GH_SFLASH_set_Speed)(U32);
+    void (*GH_SFLASH_set_CE_CHSELECT)(U8);
+}GD_SFLASH_FUNC_S;
+
+typedef struct
+{
+    GD_SFLASH_DEV_S*    dev;
+    GD_SFLASH_FUNC_S    func;
+    U32                 feature;
+    U32                 channel;
+    U32                 devicechannel;
+}GD_SFLASH_HANDLE_S;
+
+/*!
+*******************************************************************************
+**
+** \anchor gd_sflash_error_base
+** \brief he base error code for the serial flash device driver.
+**
+*******************************************************************************
+*/
+#define GD_SFLASH_ERR_BASE (GD_SFLASH_MODULE_ID<<16)
+
+/*!
+*******************************************************************************
+**
+** \brief Flash driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_SFLASH_TYPE_NOT_SUPPORTED = GD_SFLASH_ERR_BASE, //!< Device not supported.
+    GD_ERR_SFLASH_IN_USE,                                  //!< Read error.
+    GD_ERR_SFLASH_READ,                                    //!< Read error.
+    GD_ERR_SFLASH_WRITE,                                   //!< Write error.
+    GD_ERR_SFLASH_ERASE,
+    GD_ERR_UNLOCK_FAIL
+};
+
+// TODO: to be confirmed for each clock value
+// FPGA: SCLK = 40MHz
+// EVM: SCLK = 135MHz
+// 000: SCLK/2
+// 001: SCLK/4
+// 010: SCLK/6
+// 011: SCLK/8
+// 100: SCLK/10
+typedef enum
+{
+   GD_SFLASH_FREQ_DIV2 = 0,
+   GD_SFLASH_FREQ_DIV4,
+   GD_SFLASH_FREQ_DIV6,
+   GD_SFLASH_FREQ_DIV8,
+   GD_SFLASH_FREQ_DIV10,
+}GD_SFLASH_SPEED_MODE;
+
+
+/*-------------------------------------------------------------------------------*/
+/* \brief Flash I/O feature.                                                     */
+/*-------------------------------------------------------------------------------*/
+
+typedef enum
+{
+   GD_SFLASH_FEATURE_IO1 = 0,
+   GD_SFLASH_FEATURE_IO2,
+   GD_SFLASH_FEATURE_IO4
+}GD_SFLASH_FEATURE;
+
+
+
+
+/*-------------------------------------------------------------------------------*/
+/* sflash cmd attribute                                                          */
+/* sflash cmd register bit definition                                            */
+/*  bit  31   30   29   28   27   26   25   24   23   22   21   20   19               18   17
+       |   rsrd  |hold time|  transfer data bytes   |data cycle|adr and dummy cycle |cmd cycle|
+                  00-100ns    11111 -- 4 bytes                                        00 -x1
+                  01-3us      other -- n bytes        0-3 cycle     0-3 cycle         01 -x2
+                  10-100us                                                            10 -x4
+
+    bit  16   15   14     13     12   11   10    9    8   [7: 0]
+       |   RWN   |dummy cycle number| adr byte num |    |cmd to DF|
+        00 - rd data for SF 0 - 7 bytes cycle        1 - send cmd
+        01 - wr data to SF              0-7 bytes    0 - no send cmd
+        11 - nothing to do                                see specific flash cmd */
+/*-------------------------------------------------------------------------------*/
+/* send cmd or not [ 8]*/
+#define SFLASH_SEND_CMD                 0x00000100
+#define SFLASH_NO_SEND_CMD              0x00000000
+
+/* byte number of address to send [11:9]*/
+#define SFLASH_SEND_ADDR_BYTE_NUM_0     0x00000000
+#define SFLASH_SEND_ADDR_BYTE_NUM_1     0x00000200
+#define SFLASH_SEND_ADDR_BYTE_NUM_2     0x00000400
+#define SFLASH_SEND_ADDR_BYTE_NUM_3     0x00000600
+#define SFLASH_SEND_ADDR_BYTE_NUM_4     0x00000800  // 4bytes
+#define SFLASH_SEND_ADDR_BYTE_NUM_5     0x00000a00  // 4bytes
+#define SFLASH_SEND_ADDR_BYTE_NUM_6     0x00000c00  // 4bytes
+#define SFLASH_SEND_ADDR_BYTE_NUM_7     0x00000e00  // 4bytes
+
+/* byte number of dummy cycle to send [14:12] */
+#define SFLASH_SEND_DUMMY_BYTE_NUM_0    0x000000000
+#define SFLASH_SEND_DUMMY_BYTE_NUM_1    0x000001000
+#define SFLASH_SEND_DUMMY_BYTE_NUM_2    0x000002000
+#define SFLASH_SEND_DUMMY_BYTE_NUM_3    0x000003000
+#define SFLASH_SEND_DUMMY_BYTE_NUM_4    0x000004000  // 4bytes
+#define SFLASH_SEND_DUMMY_BYTE_NUM_5    0x000005000  // 4bytes
+#define SFLASH_SEND_DUMMY_BYTE_NUM_6    0x000006000  // 4bytes
+#define SFLASH_SEND_DUMMY_BYTE_NUM_7    0x000007000  // 4bytes
+
+/* command operation[16:15]: 00 for read data from SF; 01 for write data to SF; 11 for nothing to do */
+#define SFLASH_RWN_READ                 0x00000000
+#define SFLASH_RWN_WRITE                0x00008000
+#define SFLASH_RWN_NOTHING              0x00018000
+
+/* I/O mode of command cycle to SF[18:17]: 00 for x1; 01 for x2; 10 for x4 */
+#define SFLASH_CMD_MODE_1X              0x00000000
+#define SFLASH_CMD_MODE_2X              0x00020000
+#define SFLASH_CMD_MODE_4X              0x00040000
+
+/* I/O mode of address and dummy cycle to SF[20:19] */
+#define SFLASH_ADDR_MODE_1X             0x00000000
+#define SFLASH_ADDR_MODE_2X             0x00080000
+#define SFLASH_ADDR_MODE_4X             0x00100000
+//#define SFLASH_ADDR_DUMMY_CYCLE_NUM_3   0x00180000
+
+/* I/O mode of data cycle to or from SF [22:21] */
+#define SFLASH_DATA_MODE_1X             0x00000000
+#define SFLASH_DATA_MODE_2X             0x00200000
+#define SFLASH_DATA_MODE_4X             0x00400000
+//#define SFLASH_DATA_CYCLE_NUM_3         0x00600000
+
+/* transfer data byte number to or from SF[27:23]. For 11111 case, transfer 4bytes per request */
+/* for other case, transfer number bytes */
+#define SFLASH_TRANSFER_BYTE_NUM_1      0x00800000
+#define SFLASH_TRANSFER_BYTE_NUM_2      0x01000000
+#define SFLASH_TRANSFER_BYTE_NUM_3      0x01800000
+#define SFLASH_TRANSFER_BYTE_NUM_4      0x0f800000
+#define SFLASH_TRANSFER_BYTE_LOC        23
+
+#define SFLASH_HOLD_TIME_100ns          0x00000000
+#define SFLASH_HOLD_TIME_3us            0x10000000
+#define SFLASH_HOLD_TIME_100us          0x20000000
+
+#define GD_SFLASH_1X_READ               0x01
+#define GD_SFLASH_2X_READ               0x02
+#define GD_SFLASH_4X_READ               0x04
+#define GD_SFLASH_1X_WRITE              0x10
+#define GD_SFLASH_2X_WRITE              0x20
+#define GD_SFLASH_4X_WRITE              0x40
+
+#define GD_SFLASH_16M_SIZE              0x1000000
+
+/*
+*******************************************************************************
+*******************************************************************************
+**
+** Generic serial flash specific API functions
+**
+*******************************************************************************
+*******************************************************************************
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_SFLASH_Init(void);
+GERR GD_SFLASH_Exit(void);
+GERR GD_SFLASH_Open(GD_HANDLE* pHandle, GD_SFLASH_SPEED_MODE speed_mode, GD_SFLASH_CHANNEL_E channel);
+GERR GD_SFLASH_Close(GD_HANDLE* pHandle);
+GERR GD_SFLASH_Read(GD_HANDLE handle, U32 address, U32* buffer, U32 words);
+GERR GD_SFLASH_Write(GD_HANDLE handle, U32 address, U32* buffer, U32 words);
+GERR GD_SFLASH_Program(GD_HANDLE handle, U32 address, U32* buffer, U32 words);
+GERR GD_SFLASH_EraseChip(GD_HANDLE handle);
+GERR GD_SFLASH_EraseSector(GD_HANDLE handle, U16 sector);
+GERR GD_SFLASH_GetCodes(GD_HANDLE handle, U8* manufactureCode, U16* deviceCode);
+GERR GD_SFLASH_GetNames(GD_HANDLE handle, char** manufacture_name, char** deviceName);
+GERR GD_SFLASH_GetNumberOfSectors(GD_HANDLE handle, U16* numberOfSectors);
+GERR GD_SFLASH_GetSectorAddress(GD_HANDLE handle, U16 sector, U32* address);
+GERR GD_SFLASH_GetSize(GD_HANDLE handle, U32* deviceWords);
+GERR GD_SFLASH_GetSectorSize(GD_HANDLE handle, U16 sector, U32* deviceWords);
+GERR GD_SFLASH_GetSector(GD_HANDLE handle, U32 address, U16* sector);
+GERR GD_SFLASH_IsChipEmpty(GD_HANDLE handle, GBOOL* isEmpty);
+GERR GD_SFLASH_IsSectorEmpty(GD_HANDLE handle, U16 sector, GBOOL* isSectorEmpty);
+GERR GD_SFLASH_Unlock(GD_HANDLE handle);
+GERR GD_SFLASH_Lock(GD_HANDLE handle);
+GERR GD_SFLASH_IsChipLocked(GD_HANDLE handle, GBOOL* isChipLocked);
+GERR GD_SFLASH_Getfeature(GD_HANDLE handle, GD_SFLASH_RW_E op, GD_SFLASH_IO_MODE_E* feature);
+GERR GD_SFLASH_Setfeature(GD_HANDLE handle, GD_SFLASH_RW_E op, GD_SFLASH_IO_MODE_E feature);
+GERR GD_SFLASH_SetResetMode(GD_HANDLE handle, GBOOL mode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 315 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_spi.h

@@ -0,0 +1,315 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_spi.h
+**
+** \brief     Serail Peripheral Interface driver.
+**
+**            (C) Goke Microelectronics China 2007 - 2010
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. HUNAN GOFORTUNE SEMICONDUCTOR
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version   \$Id: gd_spi.h,v 1.1 2013/11/21 01:27:52
+**
+*******************************************************************************
+*/
+#ifndef GD_SPI_H
+#define GD_SPI_H
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+
+/*!
+*******************************************************************************
+**
+** \anchor gd_spi_error_base
+** \brief The base error code for the serial peripheral interface driver.
+**
+*******************************************************************************
+*/
+/*@{*/
+#define  GD_SPI_ERR_BASE  ( GD_SPI_MODULE_ID << 16)
+/*@}*/
+
+typedef enum
+{
+    GD_SPI_CHANNEL_0 = 0,
+    GD_SPI_CHANNEL_1,
+    GD_SPI_CHANNEL_NUM
+}GD_SPI_CHANNEL_E;
+
+typedef enum
+{
+    GD_SPI_SLAVE0 = 0,
+    GD_SPI_SLAVE1,
+    GD_SPI_SLAVE2,
+    GD_SPI_SLAVE3,
+    GD_SPI_SLAVE4,
+    GD_SPI_SLAVE5,
+    GD_SPI_SLAVE_NUM
+}GD_SPI_SLAVE_E;
+
+// TODO: to be confirmed for each clock value
+typedef enum
+{
+   GD_SPI_FREQ_81M = 81000000,
+   GD_SPI_FREQ_40M = 40000000,
+   GD_SPI_FREQ_30M = 30000000,
+   GD_SPI_FREQ_27M = 27000000,
+   GD_SPI_FREQ_20M = 20000000,
+   GD_SPI_FREQ_16M = 16000000,
+   GD_SPI_FREQ_13M = 13500000,
+   GD_SPI_FREQ_10M = 10000000,
+   GD_SPI_FREQ_9M  =  9000000,
+   GD_SPI_FREQ_6M  =  6000000,
+   GD_SPI_FREQ_3M  =  3000000,
+   GD_SPI_FREQ_1M  =  1000000,
+}GD_SPI_SPEED_MODE;
+
+typedef enum
+{
+    SPI_POLARITY_MODE0 = 0,//!< Sclk low level,fisrt edge get data.
+    SPI_POLARITY_MODE1,//!< Sclk low level,second edge get data.
+    SPI_POLARITY_MODE2,//!< Sclk high level,first edge get data. 
+    SPI_POLARITY_MODE3,//!< Sclk high level,second edge get data.
+}GD_SPI_POLARITY_MODE;
+/*!
+*******************************************************************************
+**
+** \brief SPI driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_SPI_TYPE_NOT_SUPPORTED = GD_SPI_ERR_BASE, //!< Device not supported.
+    GD_ERR_SPI_IN_USE,                                  //!< Read error.
+    GD_ERR_SPI_NOT_OPEN,
+    GD_ERR_SPI_READ,                                    //!< Read error.
+    GD_ERR_SPI_WRITE,                                   //!< Write error.
+    GD_ERR_SPI_ERASE,
+    GD_ERR_SPI_UNLOCK_FAIL,
+    GD_ERR_SPI_INI_ERR,
+    GD_ERR_SPI_BUSY,
+};
+
+/*!
+*******************************************************************************
+**
+** \brief SPI open parameter.
+**
+******************************************************************************/
+typedef enum
+{
+    GD_SPI_UNUSED,
+    GD_SPI_WRITE_ONLY,
+    GD_SPI_READ_ONLY,
+    GD_SPI_WRITE_READ,
+}GD_SPI_RW;
+
+typedef struct
+{
+    /*! The connection parameters to be applied when open an instance of the
+        driver.
+     */
+    U8              spi;
+    U8              slave;
+    U8              csgpio;
+    U8              polarity;    //!< send and recive data mode
+    U32             baudrate;
+    GBOOL           used_irq;
+} GD_SPI_OPEN_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief SPI ISR parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The connection parameters to be applied when used irq mode for the
+        driver.
+     */
+    U8              spi;
+    U32              write_len;
+    U32              read_len;
+    U32              all_len;
+    U32              wf_len;
+    U32              rf_len;
+    U32              w_xfer;
+    U32              r_xfer;
+    U8              bitpw;
+    U8              finished;
+    GD_SPI_RW       rwmode;
+    void*           wbuf;
+    void*           rbuf;
+    GD_HANDLE       spihandle;
+    GD_HANDLE       spiIrqHandle;
+} GD_SPI_ISR_PARAMS_S;
+
+
+/*!
+*******************************************************************************
+**
+** \brief SPI global parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    U8          spi;
+    U8          slave;
+    U8          using;
+    U8          polarity;      //!< send and recive data mode
+    U32         baudrate;
+    GD_HANDLE   cs;
+    U8          datwidth;
+    GBOOL       used_irq;
+} GD_SPI_STATUS_PARAMS_S;
+
+
+/*!
+*******************************************************************************
+**
+** \brief SPI write parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    U32         wBitSet;
+    U32         sBitSet;
+    U32         eBitSet;
+    U32         wipMask;
+    U32         address;
+} GD_SPI_WR_PARAMS_S;
+
+
+typedef struct
+{
+    U8  readID;        // command to read the chip identification
+    U8  writeEnable;   // command to enable a write/erase sequence
+    U8  writeDisable;  // command to disable a write/erase sequence
+    U8  readStatus;    // command to read from status register
+    U8  writeStatus;   // command to write to status register
+    U8  readData;      // command to read data
+    U8  readDataFast;  // command to read data in fast mode
+    U8  eraseSector;   // command to erase a single sector
+    U8  eraseChip;     // command to erase the entire chip
+    U8  programPage;   // command to program a sector page
+    U32 statusMaskWIP; // status register mask for bit write-in-progress
+    U32 statusMaskWEL; // status register mask for bit write-enable-latch
+    U8  readIO2;       // command to read data by IO2
+    U8  readIO4;       // command to read data by IO4
+    U8  programPage2;  // command to program a sector page by IO2
+    U8  programPage4;  // command to program a sector page by IO4
+}
+GD_SPI_CMD_S;
+
+
+
+/*
+*******************************************************************
+*   sflash cmd attribute
+*   sflash cmd register bit definition
+*   bit 31    30    29    28    27    26    25    24    23    22    21         20        19           18    17
+        | rsrd    | hold time | transfer data bytes       |data cycle|adr and dummy cycle | cmd cycle |
+                      00-100ns   11111 -- 4 bytes                                                           00 -x1
+                      01-3us      other(e.g.,n) -- n bytes   0-3 cycle        0-3 cycle              01 -x2
+                      10-100us                                                                                      10 -x4
+
+    bit       16           15          14        13        12        11     10     9            8                      [7: 0]
+        |         RWN            |  dummy cycle number   |  adr byte num    |                        |      cmd to DF                 |
+          00 - rd data for SF     0 - 7 bytes cycle            0-7 bytes          1 - send cmd
+          01 - wr data to SF                                                                0 - no send cmd        see specific flash cmd
+          11 - nothing to do
+
+********************************************************************
+*/
+/* send cmd or not [8]*/
+#define SPI_SEND_CMD                    0x00000100
+#define SPI_NO_SEND_CMD                 0x00000000
+
+/* byte number of address to send [11:9]*/
+#define SPI_SEND_ADDR_BYTE_NUM_0        0x00000000
+#define SPI_SEND_ADDR_BYTE_NUM_1        0x00000200
+#define SPI_SEND_ADDR_BYTE_NUM_2        0x00000400
+#define SPI_SEND_ADDR_BYTE_NUM_3        0x00000600
+#define SPI_SEND_ADDR_BYTE_NUM_4        0x00000800
+#define SPI_SEND_ADDR_BYTE_NUM_5        0x00000a00
+#define SPI_SEND_ADDR_BYTE_NUM_6        0x00000c00
+#define SPI_SEND_ADDR_BYTE_NUM_7        0x00000e00
+
+/*Byte number of dummy cycle to send [14:12]*/
+#define SPI_SEND_DUMMY_BYTE_NUM_0       0x00000000
+#define SPI_SEND_DUMMY_BYTE_NUM_1       0x00001000
+#define SPI_SEND_DUMMY_BYTE_NUM_2       0x00002000
+#define SPI_SEND_DUMMY_BYTE_NUM_3       0x00003000
+#define SPI_SEND_DUMMY_BYTE_NUM_4       0x00004000
+#define SPI_SEND_DUMMY_BYTE_NUM_5       0x00005000
+#define SPI_SEND_DUMMY_BYTE_NUM_6       0x00006000
+#define SPI_SEND_DUMMY_BYTE_NUM_7       0x00007000
+
+/* Command operation[16:15]: 00 for read data from SPI; 01 for write data to SPI; 11 for nothing to do */
+#define SPI_RWN_READ                    0x00000000
+#define SPI_RWN_WRITE                   0x00008000
+#define SPI_RWN_NOTHING                 0x00018000
+
+/*I/O mode of command cycle to SF[18:17]: 00 for x1; 01 for x2; 10 for x4*/
+#define SPI_CMD_MODE_1X                 0x00000000
+#define SPI_CMD_MODE_2X                 0x00020000
+#define SPI_CMD_MODE_4X                 0x00040000
+
+/* I/O mode of address and dummy cycle to SF[20:19]*/
+#define SPI_ADDR_DUMMY_CYCLE_NUM_0      0x00000000
+#define SPI_ADDR_DUMMY_CYCLE_NUM_1      0x00080000
+#define SPI_ADDR_DUMMY_CYCLE_NUM_2      0x00100000
+#define SPI_ADDR_DUMMY_CYCLE_NUM_3      0x00180000
+
+/*I/O mode of data cycle to or from SF [22:21] */
+#define SPI_DATA_CYCLE_NUM_0            0x00000000
+#define SPI_DATA_CYCLE_NUM_1            0x00200000
+#define SPI_DATA_CYCLE_NUM_2            0x00400000
+#define SPI_DATA_CYCLE_NUM_3            0x00600000
+
+/*Transfer data byte number to or from SF[27:23]. For 11111 case, transfer 4bytes per request. For other case, transfer number bytes.*/
+#define SPI_TRANSFER_BYTE_NUM_4         0x0f800000
+#define SPI_TRANSFER_BYTE_LOC           23
+
+#define SPI_HOLD_TIME_100ns             0x00000000
+#define SPI_HOLD_TIME_3us               0x10000000
+#define SPI_HOLD_TIME_100us             0x20000000
+
+
+/*
+*******************************************************************************
+*******************************************************************************
+**
+** Generic serial flash specific API functions
+**
+*******************************************************************************
+*******************************************************************************
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_SPI_Init( void );
+GERR GD_SPI_Exit( void );
+GERR GD_SPI_Open( GD_SPI_OPEN_PARAMS_S *openParamsP, GD_HANDLE* pHandle );
+GERR GD_SPI_Close( GD_HANDLE* pHandle );
+GERR GD_SPI_WriteWords( GD_HANDLE handle, U16* wbuffer, U32 w_words );
+GERR GD_SPI_WriteThenReadWords( GD_HANDLE handle, U16* wbuffer, U32 w_words, U16* rbuffer, U32 r_words );
+GERR GD_SPI_WriteBytes( GD_HANDLE handle, U8* wbuffer, U32 w_size );
+GERR GD_SPI_WriteThenReadBytes( GD_HANDLE handle, U8* wbuffer, U32 w_size, U8* rbuffer, U32 r_size );
+GERR GD_SPI_GetDevice(GD_HANDLE handle);
+GERR GD_SPI_ReleaseDevice(GD_HANDLE handle);
+GERR GD_SPI_SetDatFormat(GD_HANDLE handle, U8 dat_width);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 176 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_spieeprom.h

@@ -0,0 +1,176 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/inc/gd_spieeprom.h
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_SPIEEPROM_H_
+#define _GD_SPIEEPROM_H_
+
+
+#include <gtypes.h>
+#include <gmodids.h>
+#include "gd_gpio.h"
+#include "gd_spi.h"
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+typedef enum
+{
+    GD_SPI_EEPROM_AT25320B = 0,
+    GD_SPI_EEPROM_AT25640B,
+    GD_SPI_EEPROM_NUM
+}GD_SPI_EEPROM_E;
+
+/*!
+*******************************************************************************
+**
+** \anchor
+** \brief he base error code for the serial spi eeprom device driver.
+**
+*******************************************************************************
+*/
+#define GD_SPI_EEPROM_ERR_BASE (GD_SPI_EEPROM_MODULE_ID<<16)
+
+/*!
+*******************************************************************************
+**
+** \brief Flash driver error codes.
+**
+*******************************************************************************
+*/
+enum
+{
+    GD_ERR_SPI_EEPROM_TYPE_NOT_SUPPORTED = GD_SPI_EEPROM_ERR_BASE, //!< Device not supported.
+    GD_ERR_SPI_EEPROM_IN_USE,                                  //!< Read error.
+    GD_ERR_SPI_EEPROM_READ,                                    //!< Read error.
+    GD_ERR_SPI_EEPROM_WRITE,                                   //!< Write error.
+};
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+/*
+*******************************************************************************
+**
+** serial spi eeprom specific commands and statis register bit definitions
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    U8  writeEnable;   // command to WREN  Set Write Enable Latch
+    U8  writeDisable;  // command to WRDI  Reset Write Enable Latch
+    U8  readStatus;    // command to RDSR  Read Status Register
+    U8  writeStatus;   // command to WRSR  Write Status Register
+    U8  readData;      // command to READ  Read Data from Memory Array
+    U8  WriteData;     // command to WRITE Write Data to Memory Array
+}GD_SPI_EEPROM_CMD_S;
+
+/*
+*******************************************************************************
+**
+** serial spi eeprom specific geometry and information data structure
+**
+*******************************************************************************
+*/
+typedef struct
+{
+    char*            manufactureName; // Pointer to manufacture name
+    char*            deviceName;      // Pointer to device name
+    U32              deviceBytes;     // Size of spi eeprom device in bytes
+    U32              sectorCount;     // Number of sectors
+    U32              sectorBytes;     // Size of a single sector in bytes
+    GD_SPI_EEPROM_CMD_S* commands;    // Device specific access commands
+    GBOOL            wptoporbottom;
+    GD_SPI_EEPROM_E  device;
+    GD_HANDLE        spi;
+    GD_HANDLE        wp;
+    GD_HANDLE        hold;
+}GD_SPI_EEPROM_DEV_S;
+
+typedef struct
+{
+    GD_SPI_EEPROM_E         device;
+    GD_SPI_CHANNEL_E        channel;
+    GD_SPI_SLAVE_E          slave;
+    GD_SPI_SPEED_MODE       speed;
+    GD_SPI_POLARITY_MODE    polarity;
+    GBOOL                   used_irq;
+    GD_GPIO_PIN_E           csgpiopin;
+    GD_GPIO_TYPE_E          csgpiotype;
+    GD_GPIO_PIN_E           wpgpiopin;
+    GD_GPIO_TYPE_E          wpgpiotype;
+    GD_GPIO_PIN_E           holdgpiopin;
+    GD_GPIO_TYPE_E          holdgpiotype;
+} GD_SPI_EEPROM_OPEN_PARAMS_S;
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_SPI_EEPROM_Init(void);
+GERR GD_SPI_EEPROM_Exit(void);
+GERR GD_SPI_EEPROM_Open(GD_SPI_EEPROM_OPEN_PARAMS_S *openParamsP, GD_HANDLE* pHandle);
+GERR GD_SPI_EEPROM_Close(GD_HANDLE* pHandle);
+GERR GD_SPI_EEPROM_Read(GD_HANDLE handle, U32 address, U8* buffer, U32 bytes);
+GERR GD_SPI_EEPROM_Write(GD_HANDLE handle, U32 address, U8* buffer, U32 bytes);
+GERR GD_SPI_EEPROM_GetNames(GD_HANDLE handle, char** manufactureName, char** deviceName);
+GERR GD_SPI_EEPROM_GetNumberOfSectors(GD_HANDLE handle, U16* numberOfSectors);
+GERR GD_SPI_EEPROM_GetSectorAddress(GD_HANDLE handle, U16 sector, U32* address);
+GERR GD_SPI_EEPROM_GetSize(GD_HANDLE handle, U32* deviceBytes);
+GERR GD_SPI_EEPROM_GetSectorSize(GD_HANDLE handle, U16 sector, U32* deviceBytes);
+GERR GD_SPI_EEPROM_GetSector(GD_HANDLE handle, U32 address, U16* sector);
+GERR GD_SPI_EEPROM_Unlock(GD_HANDLE handle);
+GERR GD_SPI_EEPROM_Lock(GD_HANDLE handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_SPIEEPROM_H_ */
+

+ 165 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_timer.h

@@ -0,0 +1,165 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_timer.h
+**
+** \brief     TIMER driver.
+**
+**            The driver provides functions for timer management.
+**            It enables an application to make use of 8 soft timers, 1 hard
+**            timer and 1 timestamp timer as a system clock.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+******************************************************************************/
+#ifndef _GD_TIMER_H_
+#define _GD_TIMER_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+/*---------------------------------------------------------------------------*/
+/* constants and macros                                                      */
+/*---------------------------------------------------------------------------*/
+#define GD_TIMER_ERR_BASE (GD_TIMER_MODULE_ID<<16) //!< The timer base error code.
+
+/* Note: Pre-scaler define hardcoded to avoid calculation in ISR! */
+#define GD_TIMER_RESOLUTION_1_USEC   1UL          //!< timer resolution 1 usec
+#define GD_TIMER_RESOLUTION_10_USEC  10UL         //!< timer resolution 10 usec
+#define GD_TIMER_RESOLUTION_100_USEC 100UL        //!< timer resolution 100 usec
+#define GD_TIMER_RESOLUTION_1_MSEC   1000UL       //!< timer resolution 1 msec
+#define GD_TIMER_RESOLUTION_10_MSEC  10000UL      //!< timer resolution 10 msec
+#define GD_TIMER_RESOLUTION_100_MSEC 100000UL     //!< timer resolution 100 msec
+#define GD_TIMER_RESOLUTION_1_SEC    1000000UL    //!< timer resolution 1 sec
+#define GD_TIMER_RESOLUTION_1_MIN    60000000UL   //!< timer resolution 1 minute
+#define GD_TIMER_RESOLUTION_1_HOUR   3600000000UL //!< timer resolution 1 hour
+#define GD_TIMER_RESOLUTION_1_HOUR   3600000000UL //!< timer resolution 1 hour
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+
+/*!
+*******************************************************************************
+**
+** \brief TIMER driver error codes.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Indicates all soft timer are  in use. */
+    GD_ERR_TIMER_NO_FREE_SOFT_TIME = GD_TIMER_ERR_BASE,
+    /*! Indicates all  hard  timer are in use */
+    GD_ERR_TIMER_NO_FREE_HARD_TIME,
+    /*! Indicates all time stamps are in use. */
+    GD_ERR_TIMER_NO_FREE_GPREG_TIME,
+    /*! */
+    GD_ERR_TIMER_OUTOF_RANG,
+}GD_TIMER_ERR_E;
+
+/*!
+*******************************************************************************
+**
+** \brief Allowed ARC timer settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Reference to TIMER1 */
+    GD_REG_TIMER1 = 0,
+    /*! Reference to TIMER2 */
+    GD_REG_TIMER2 = 1,
+    /*! Reference to TIMER3 */
+    GD_REG_TIMER3 = 2,
+}GD_TIMER_REG_E;
+
+typedef enum
+{
+    /*! Reference to  */
+    GD_REG_SOFT_TIMER_IRQ   = 0,
+    /*! Reference to  */
+    GD_REG_HARD_TIMER_IRQ   = 1,
+    /*! Reference to  */
+    GD_REG_GPREG_TIMER_IRQ  = 2,
+}GD_TIMER_IRQ_E;
+
+/*!
+*******************************************************************************
+**
+** \brief TIMER driver's initialization parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The ARC core timer register to be used for soft timer. */
+    S8            softTimerReg;
+    /*! The priority of the soft timer interrupt. */
+    S8            softTimerpriority;
+    /*! The ARC core timer register to be used for hard timer. */
+    S8            hardTimerReg;
+    /*! The priority of the hard timer interrupt. */
+    S8            hardTimerpriority;
+    /*! The ARC timestamp timer register to be used for gpreg IRQ. */
+    S8            gpregTimerReg;
+    /*! The priority of the gpreg timer interrupt. */
+    S8            gpregTimerpriority;
+}GD_TIMER_INIT_PARAMS_S;
+
+
+
+/*---------------------------------------------------------------------------*/
+/* function prototypes                                                       */
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+U8  *GD_TIMER_GetRevisionString(void);
+GERR GD_TIMER_Init(GD_TIMER_INIT_PARAMS_S* initParams);
+GERR GD_TIMER_Exit(void);
+
+GERR GD_TIMER_TimerOpen(GD_HANDLE* pHandle,GD_TIMER_IRQ_E timerIRQ);
+GERR GD_TIMER_TimerSet(GD_HANDLE* pHandle, U32 timeValue, GBOOL* flag, void(*fp)());
+GERR GD_TIMER_TimerClose(GD_HANDLE* handle);
+
+GERR GD_TIMER_HardTimerOpen(GD_HANDLE* pHandle);
+GERR GD_TIMER_HardTimerSet(GD_HANDLE* pHandle, U32 timeValue, GBOOL* flag,void(*fp)());
+GERR GD_TIMER_HardTimerClose(GD_HANDLE* pHandle);
+
+GERR GD_TIMER_GpregTimerOpen(GD_HANDLE* pHandle);
+GERR GD_TIMER_GpregTimerClose(GD_HANDLE* pHandle);
+GERR GD_TIMER_GpregTimerSet(GD_HANDLE* pHandle, U32 timeValue, GBOOL* flag, void(*fp)());
+
+
+U32  GD_TIMER_ReadTimerStamp(void);
+
+GERR GD_TIMER_SoftTimerOpen(GD_HANDLE* pHandle);
+GERR GD_TIMER_SoftTimerClose(GD_HANDLE* pHandle);
+GERR GD_TIMER_SoftTimerSet(GD_HANDLE* pHandle, U32 timeValue, GBOOL* flag, void(*fp)());
+GERR GD_TIMER_StopSoftTimer(GD_HANDLE* pHandle);
+GERR GD_TIMER_ContinueSoftTimer(GD_HANDLE* pHandle);
+
+GERR GD_TIMER_Delay(U32 msecs);
+U32 GD_GET_ARM_ClkHz(void);
+U32 GD_GET_AHB_ClkHz(void);
+U32 GD_GET_APB_ClkHz(void);
+U32 GD_GET_UART_ClkHz(void);
+U32 GD_GET_IDSP_ClkHz(void);
+U32 GD_GET_CORE_ClkHz(void);
+U32 GD_GET_DRAM_ClkHz(void);
+U32 GD_GET_I2S_ClkHz(void);
+U32 GD_GET_SD_ClkHz(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GD_TIMER_H_ */
+/* end of gd_timer.h */

+ 313 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_uart.h

@@ -0,0 +1,313 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_uart.h
+**
+** \brief     UART driver.
+**
+**            The driver provides functions to use the GK6202's UART
+**            interface.
+**
+**           Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+******************************************************************************/
+#ifndef _GD_UART_H_
+#define _GD_UART_H_
+
+#include <gtypes.h>
+#include <gmodids.h>
+
+/*---------------------------------------------------------------------------*/
+/* constants and macros                                                      */
+/*---------------------------------------------------------------------------*/
+
+
+#define GD_UART_ERR_BASE (GD_UART_MODULE_ID<<16)  //!< Error base value
+#define GD_UART_COUNT        3
+
+#define UART0_RX_BUF_SIZE    1024   /* size of uart0 receive ring buffer */
+#define UART0_TX_BUF_SIZE    1024   /* size of uart0 trasmit ring buffer */
+#define UART1_RX_BUF_SIZE    1024  /* size of uart1 receive ring buffer */
+#define UART1_TX_BUF_SIZE    1024  /* size of uart1 trasmit ring buffer */
+#define UART2_RX_BUF_SIZE    1024  /* size of uart2 receive ring buffer */
+#define UART2_TX_BUF_SIZE    1024  /* size of uart2 trasmit ring buffer */
+#define UART_FIFO_SIZE       16   /* size of uart FIFO in bytes */
+
+/*---------------------------------------------------------------------------*/
+/* types, enums and structures                                               */
+/*---------------------------------------------------------------------------*/
+
+/*!
+*******************************************************************************
+**
+** \brief UART parity settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Specifies \b NONE parity. */
+    GD_UART_NO_PARITY   = 0,
+    /*! Specifies \b EVEN parity. */
+    GD_UART_EVEN_PARITY = 1,
+    /*! Specifies \b ODD parity. */
+    GD_UART_ODD_PARITY  = 2
+} GD_UART_PARITY_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART data bit settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Specifies \b 5 data bits. */
+    GD_UART_5_DATATBITS = 4,
+    /*! Specifies \b 6 data bits. */
+    GD_UART_6_DATATBITS = 5,
+    /*! Specifies \b 7 data bits. */
+    GD_UART_7_DATATBITS = 6,
+    /*! Specifies \b 8 data bits. */
+    GD_UART_8_DATATBITS = 7
+} GD_UART_DATABITS_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART stop bit settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Specifies \b 1 stop bit. */
+    GD_UART_10_STOPBITS = 0,
+    /*! Specifies \b 2 stop bits. */
+    GD_UART_20_STOPBITS = 1
+} GD_UART_STOPBITS_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART protocol settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Specifies \b NO protocol usage. */
+    GD_UART_NO_PROTOCOL         = 0,
+    /*! Specifies \b FLOW-CONTROL protocol of DTR mode */
+    GD_UART_FLOWCTRL_DTR        = 0x00000001,
+    /*! Specifies \b FLOW-CONTROL protocol of RTS mode */
+    GD_UART_FLOWCTRL_RTS        = 0x00000002,
+    GD_UART_FLOWCTRL_OUT1       = 0x00000004,
+    GD_UART_FLOWCTRL_OUT2       = 0x00000008,
+    GD_UART_FLOWCTRL_LOOPBACK   = 0x00000010,
+    GD_UART_FLOWCTRL_AFCE       = 0x00000020,
+    GD_UART_FLOWCTRL_SIRE       = 0x00000040,
+} GD_UART_PROTOCOL_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART baud rate settings.
+**
+******************************************************************************/
+typedef enum
+{
+    /*! Specifies \b 110 baud. */
+    GD_UART_BAUD_RATE110    = 110,
+    /*! Specifies \b 300 baud. */
+    GD_UART_BAUD_RATE300    = 300,
+    /*! Specifies \b 1200 baud. */
+    GD_UART_BAUD_RATE1200   = 1200,
+    /*! Specifies \b 2400 baud. */
+    GD_UART_BAUD_RATE2400   = 2400,
+    /*! Specifies \b 4800 baud. */
+    GD_UART_BAUD_RATE4800   = 4800,
+    /*! Specifies \b 9600 baud. */
+    GD_UART_BAUD_RATE9600   = 9600,
+    /*! Specifies \b 9600 baud. */
+    GD_UART_BAUD_RATE14400  = 14400,
+    /*! Specifies \b 14400 baud. */
+    GD_UART_BAUD_RATE19200  = 19200,
+    /*! Specifies \b 38400 baud. */
+    GD_UART_BAUD_RATE38400  = 38400,
+    /*! Specifies \b 57600 baud. */
+    GD_UART_BAUD_RATE57600  = 57600,
+    /*! Specifies \b 115200 baud. */
+    GD_UART_BAUD_RATE115200 = 115200,
+
+    /*! Specifies \b 230400 baud.
+     *  \attention May cause possible clock error of more than 10%.
+     */
+    GD_UART_BAUD_RATE230400 = 230400,
+    /*! Specifies \b 460800 baud.
+     *  \attention May cause possible clock error of more than 10%.
+     */
+    GD_UART_BAUD_RATE460800 = 460800,
+    /*! Specifies \b 921600 baud.
+     *  \attention May cause possible clock error of more than 10%.
+     */
+    GD_UART_BAUD_RATE921600 = 921600
+} GD_UART_BAUDRATE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART RX/TX buffer state.
+**
+******************************************************************************/
+typedef enum
+{
+    RX_BUFFER_STATE_EMPTY    = 0,
+    RX_BUFFER_STATE_NORMAL   = 1,
+    RX_BUFFER_STATE_OVERFLOW = 2,
+    RX_BUFFER_STATE_ABNORMAL = 3,
+    TX_BUFFER_STATE_EMPTY    = 4,
+    TX_BUFFER_STATE_NORMAL   = 5,
+    TX_BUFFER_STATE_OVERFLOW = 6,
+    TX_BUFFER_STATE_ABNORMAL = 7
+}GD_UART_BUFFER_STATE_E;
+
+/*!
+*******************************************************************************
+**
+** \brief UART connection paramter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The data rate of the connection. */
+    GD_UART_BAUDRATE_E dataRate;
+    /*! The data bit setting to be applied. */
+    GD_UART_DATABITS_E numDataBits;
+    /*! The stop bit setting to be applied. */
+    GD_UART_STOPBITS_E numStopBits;
+    /*! The protocol setting to be applied. */
+    GD_UART_PROTOCOL_E protocol;
+    /*! The parity setting to be applied. */
+    GD_UART_PARITY_E   parity;
+} GD_UART_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief UART driver's initialization parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The default connection parameters to be applied. */
+    GD_UART_PARAMS_S  *defaultParamsP;
+    /*! The CPU  frequency */
+    U32               cpuFreq;
+    /*! interrupt mode enable/disable*/
+    GBOOL         interruptEnable;
+    /*! The priority of the UART interrupt. */
+    S8                irqPriority;
+    /*! The function to be called when new data were received. */
+    void              (*notifyFunction)(U32);
+} GD_UART_INIT_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief UART open parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The connection parameters to be applied when open an instance of the
+        driver.
+     */
+    GD_UART_PARAMS_S  *paramsP;
+    S8          gpioRxPin;
+    S8          gpioTxPin;
+    S8          gpioRtsPin;
+    S8          gpioCtsPin;
+    U8          channel;
+    void (*NotifyFunction)(U32);
+	GBOOL       interruptEnable;
+} GD_UART_OPEN_PARAMS_S;
+
+/*!
+*******************************************************************************
+**
+** \brief UART statistic parameter.
+**
+******************************************************************************/
+typedef struct
+{
+    /*! The number of transmitted characters. */
+    U32 numTransmittedChar;
+    /*! The number of received characters. */
+    U32 numReceivedChar;
+    /*! The number  of parity  errors. */
+    U32 numParityError;
+} GD_UART_STATISTICS;
+
+/*!
+*******************************************************************************
+**
+** \brief UART state machine parameters.
+**
+******************************************************************************/
+typedef volatile struct
+{
+    GBOOL               inUse;          /* specifies if block is in use */
+    U8                  channel;
+    U32                 RealBaudRate;
+    GD_UART_PARAMS_S    SetParamsData;
+    GD_UART_STATISTICS  UartStatics;
+
+    void (*NotifyFunction)(U32);
+    volatile U8 *RxBuffer;
+    volatile U32 RxBufWrite; /* start and stop pointer of RX buffer */
+    volatile U32 RxBufRead;
+    volatile U32 RxBufCounter;
+    volatile U32 RxBufSize;
+    volatile U8 *TxBuffer;
+    volatile U32 TxBufWrite; /* start and stop pointer of TX buffer */
+    volatile U32 TxBufRead;
+    volatile U32 TxBufCounter;
+    volatile U32 TxBufSize;
+    GBOOL    interruptEnable;
+}GD_UART_STATE_MACHINE_S;
+
+
+/*---------------------------------------------------------------------------*/
+/* function prototypes                                                       */
+/*---------------------------------------------------------------------------*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef USE_RT_DRIVER_FRAMEWORK
+
+GERR GD_UART_CheckRxBuffer(GD_HANDLE handle, GBOOL *dataAvailable);
+GERR GD_UART_Close(GD_HANDLE *handleP);
+GERR GD_UART_Flush(GD_HANDLE handle);
+GERR GD_UART_GetRealBaudRate(GD_HANDLE handle, U32 *rateP);
+U8  *GD_UART_GetRevisionString(void);
+GERR GD_UART_GetParams(GD_HANDLE handle, GD_UART_PARAMS_S *paramsP);
+GERR GD_UART_GetStatistics(GD_HANDLE handle, GD_UART_STATISTICS *statisticsP);
+GERR GD_UART_Init(GD_UART_INIT_PARAMS_S *initParamsP);
+GERR GD_UART_Open(GD_UART_OPEN_PARAMS_S *openParamsP, GD_HANDLE *handleP);
+GERR GD_UART_Read(GD_HANDLE handle, U8 *bufferP, U16 desiredReadBytes, U16 *actualReceivedBytesP);
+GERR GD_UART_SetParams(GD_HANDLE handle, GD_UART_PARAMS_S *paramsP);
+GERR GD_UART_Write(GD_HANDLE handle, U8 *bufferP, U16 bufferSize);
+GERR GD_UART_SetInterruptMode(GD_HANDLE handle, GBOOL enable);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GD_UART_H_ */
+/* end of gd_uart.h */

+ 126 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_usb.h

@@ -0,0 +1,126 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/inc/gd_usb.h
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_USB_H_
+#define _GD_USB_H_
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+#define     HS_MSC_TEST
+//#define     FS_MSC_TEST
+
+//Switch of DMA FIFO CLR BUG Test 
+//#define DMA_FIFO_CLR_TEST
+
+//USB data transfer mode choose
+//#define  USB_DATA_TRAN_MODE_PIO   // about 5.9MB ws, 4.4M rs;
+#define  USB_DATA_TRAN_MODE_DMA
+//#define  USB_DATA_TRAN_MODE_INT
+
+
+#define TBLK_SZ_BYTES_8   8
+#define TBLK_SZ_BYTES_16  16
+#define TBLK_SZ_BYTES_32  32
+#define TBLK_SZ_BYTES_64  64
+
+#define DMA_TBLK_SZ_BYTES_8     0
+#define DMA_TBLK_SZ_BYTES_16    1
+#define DMA_TBLK_SZ_BYTES_32    2
+#define DMA_TBLK_SZ_BYTES_64    3
+// DMA transfer mode. The maximum of USB DMA Tx transfer is limited by USB PHY ahb general Reg(0x90020E08) to 64 Bytes.
+#define USB_DMA_TBLK_SZ   TBLK_SZ_BYTES_32
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void gd_clk_disable_usb();
+extern void gd_clk_enable_usb();
+extern void gd_clk_disable_all();
+extern GERR GD_USB_PHY_FPGA_Init(void);
+extern GERR GD_USB_PHY_Init(U8 GpioNumber);
+extern GERR GD_USB_Init(void);
+extern void GD_USB_In_tranTx(U8 *p, U32 len);
+extern void GD_USB_Control_in(const U8 *p, U32 *length, U32 len0_flag);
+extern void GD_USB_Init_msc_pipe(void);
+extern GERR GD_USB_Set_EP_Index(U8 idx);
+extern GERR GD_USB_Set_CSR0L(U8 data);
+extern GERR GD_USB_Get_CSR0L(U8 *pdata);
+extern GERR GD_USB_Set_FADDR(U8 data);
+extern GERR GD_USB_Set_RXCSRL(U8 data);
+extern GERR GD_USB_Get_RXCSRL(U8 *data);
+extern GERR GD_USB_Set_TXCSRH(U8 data);
+extern GERR GD_USB_Get_POWER(U8 *data);
+extern GERR GD_USB_Read_Rx_Count(U8 cntType, U32 *data);
+extern GERR GD_USB_Read_EP_FIFOx(U8 aryData[], U32 reqBytesNum, U8 epIdx);
+extern GERR GD_USB_DMA_In_TranRx(U32 host_write_addr, U32 host_write_len);
+extern GERR GD_USB_DMA_Out_TranTx(U32 read_addr, U32 read_len);
+extern GERR GD_USB_DMA_Out_TranTx_Fix_BugDMA(U32 read_addr, U32 read_len);
+
+#ifdef GK710X
+extern GERR GD_USB_Read_Clear_IntrRx(U16 *pINT);
+extern GERR GD_USB_Read_Clear_IntrTx(U16 *pINT);
+#else
+extern GERR GD_USB_IRQ_In_TranRx_Set(U32 host_write_addr, U32 host_write_len);
+extern GERR GD_USB_IRQ_Out_TranTx_Set(U32 hs_read_addr, U32 hs_read_len);
+extern GERR GD_USB_Read_Clear_IntrTx_L(U8 *pINT);
+extern GERR GD_USB_Read_Clear_IntrRx_L(U8 *pINT);
+extern void GD_USB_PIO_In_tran_tx(U32 *p, U32 len);
+extern void GD_USB_PIO_In_tran_rx(U32 *p, U32 len);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_USB_H_ */
+

+ 334 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_vo_i80.h

@@ -0,0 +1,334 @@
+/*!
+*******************************************************************************
+**
+** \file      gd_i80.h
+**
+** \brief     I80
+**
+**            Copyright:   2012 - 2015 (C) GoKe Microelectronics Chengdu Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      
+**
+******************************************************************************/
+#ifndef _GD_VO_I80_H_
+#define _GD_VO_I80_H_
+
+#include <gtypes.h>
+#include "gmodids.h"
+#include "gd_int.h"
+#include "gd_uart.h"
+
+#define DEAD_LOOP_CHECK
+
+#define I80_DESIGN_REF_CLK_FREQ 200//MHz    GK7101S-->200MHz GK8601-->300MHz   
+
+#define I80_CLK_FREQ			200//MHz   GK7101S: FPGA-->100MHz   IC-->200MHz
+//#define I80_CLK_PERIOD			(1000/I80_CLK_FREQ)//   5ns/Cycle
+#define TIMING_PARA_CEIL_NS(x)	(((x)*I80_CLK_FREQ+999)/1000)
+
+#define I80_1ST_H_L_COUNTER     (10*I80_DESIGN_REF_CLK_FREQ)
+#define I80_2ND_H_COUNTER       (100*I80_DESIGN_REF_CLK_FREQ)
+#define I80_HW_DELAY_COUNTER    (100*I80_DESIGN_REF_CLK_FREQ)
+//#define I80_RST_1ST_UNIT        (I80_1ST_H_L_COUNTER/I80_CLK_FREQ)//us  10
+//#define I80_RST_2ND_UNIT        (I80_2ND_H_COUNTER/I80_CLK_FREQ)//us  100
+
+#define TIMING_PARA_FIRST_H_CEIL_MS(x)  ((1000*I80_CLK_FREQ*(x)+I80_1ST_H_L_COUNTER-1)/I80_1ST_H_L_COUNTER)
+#define TIMING_PARA_FIRST_L_CEIL_MS(x)  ((1000*I80_CLK_FREQ*(x)+I80_1ST_H_L_COUNTER-1)/I80_1ST_H_L_COUNTER)
+#define TIMING_PARA_SECOND_H_CEIL_MS(x) ((1000*I80_CLK_FREQ*(x)+I80_2ND_H_COUNTER-1)/I80_2ND_H_COUNTER)
+#define TIMING_PARA_HW_DELAY_CEIL_MS(x) ((1000*I80_CLK_FREQ*(x)+I80_HW_DELAY_COUNTER-1)/I80_HW_DELAY_COUNTER)
+//#define I80_CLK_10US_CYCLE	(10*I80_CLK_FREQ)//2000     //(10000/(1000/200))cycles     
+//#define I80_CLK_100US_CYCLE	(100*I80_CLK_FREQ)//20000 //(100000/(1000/200))cycles
+//#define TIMING_PARA_FIRST_H_CEIL_MS(x)	(((x)*1000*I80_CLK_FREQ+I80_CLK_10US_CYCLE-1)/I80_CLK_10US_CYCLE)//1ms*(200/2000*(10^6)
+//#define TIMING_PARA_FIRST_L_CEIL_MS(x) 	(((x)*1000*I80_CLK_FREQ+I80_CLK_10US_CYCLE-1)/I80_CLK_10US_CYCLE)
+//#define TIMING_PARA_SECOND_H_CEIL_MS(x)	(((x)*1000*I80_CLK_FREQ+I80_CLK_100US_CYCLE-1)/I80_CLK_100US_CYCLE)
+
+#define I80READ     0
+#define I80WRITE    1
+#define I80COMMAND  0
+#define I80PARA     1
+#define LCD_WRITE_CMD(x)    ((I80COMMAND<<17)   |   (I80WRITE<<16)  |   (x))
+#define LCD_WRITE_PARA(x)   ((I80PARA<<17)      |   (I80WRITE<<16)  |   (x))
+#define LCD_READ_CMD(x)     ((I80COMMAND<<17)   |   (I80WRITE<<16)  |   (x))
+#define LCD_READ_PARA       ((I80PARA<<17)      |   (I80READ <<16)  |   (0))
+#define I80_DELAY_CMD       ((I80COMMAND<<17)   |   (I80WRITE<<16)  |   (0xFFFF))//never conflict with the command of driver ic!!!!
+
+#define MAX_CMDPARA_NUM     128
+#define MAX_READINFO_NUM    10
+
+#define GD_VO_I80_ERR_BASE   (26 << 16)//(GD_ETH_MODULE_ID << 16)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+enum
+{
+    GD_ERR_I80_NOT_SUPPORTED    = GD_VO_I80_ERR_BASE, //!< Device not supported.
+    GD_ERR_I80_CMD_ERROR        = GD_VO_I80_ERR_BASE+1,
+    GD_ERR_I80_SRAM_OVER_FLOW   = GD_VO_I80_ERR_BASE+2,
+    GD_ERR_I80_FRAME_HEAD_ERROR = GD_VO_I80_ERR_BASE+4,
+    GD_ERR_I80_CHECK_TIME_OUT   = GD_VO_I80_ERR_BASE+8,
+};
+
+#define DCn_LOW_CMD     (0<<5)
+#define DCn_HIGH_CMD    (1<<5)
+#define CSn_RISING      (0<<4)
+#define CSn_FALLING     (1<<4)
+#define VSYNC_LOW       (0<<3)
+#define VSYNC_HIGH      (1<<3)
+#define LCDRST_LOW      (0<<2)
+#define LCDRST_HIGH     (1<<2)
+#define RD_RISING       (0<<1)
+#define RD_FALLING      (1<<1)
+#define WR_RISING       (0<<0)
+#define WR_FALLING      (1<<0)
+
+//typedef     GD_INT_DATA_S* (*GD_I2S_ISR_T)(U8 channelIndex);
+
+typedef enum
+{
+    GD_VO_I80_OFF=0,  //!< disable. 
+    GD_VO_I80_ON=1,  //!< enable.
+
+}GD_VO_I80_ONOFF_E;
+
+
+/*!
+*******************************************************************************
+**
+** \brief I80 data width modes.
+**
+** \sa    GD_VO_I80_DATA_WIDTH_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_VO_I80_8BIT=0,  //!< 8 BIT.
+    GD_VO_I80_9BIT=1,  //!< 9 BIT.
+    GD_VO_I80_16BIT=2, //!< 16 BIT.
+    GD_VO_I80_18BIT=3, //!< 18 BIT.
+    GD_VO_I80_24BIT=4, //!< 24 BIT.
+}GD_VO_I80_DATA_WIDTH_E;
+
+
+/*!
+*******************************************************************************
+**
+** \brief I2S operition modes.
+**
+** \sa    GD_VO_I80_COLOR_FORMAT_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_VO_I80_PIXEL_16BIT=0, //!< 16 BIT.
+    GD_VO_I80_PIXEL_18BIT=1, //!< 18 BIT.
+    GD_VO_I80_PIXEL_24BIT=2, //!< 24 BIT.
+    GD_VO_I80_PIXEL_12BIT=3, //!< 12 BIT.
+}GD_VO_I80_COLOR_FORMAT_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I80 trans data format.
+**
+** \sa    GD_VO_I80_TRANS_FORMAT_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_VO_I80_18BIT_TWICE_1PIXEL = 0,     //!< 1PIXEL/TWICE
+    GD_VO_I80_18BIT_TRICE_2PIXEL = 1,     //!< 2PIXEL/TRICE
+}GD_VO_I80_TRANS_FORMAT_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I80 command width.
+**
+** \sa    GD_VO_I80_CMD_WIDTH_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_VO_I80_CMD_8BIT =0 ,     //!< 8BIT.
+    GD_VO_I80_CMD_16BIT =1 ,    //!< 16BIT.
+}GD_VO_I80_CMD_WIDTH_E;
+
+/*!
+*******************************************************************************
+**
+** \brief I80 command endian.
+**
+** \sa    GD_VO_I80_CMD_ENDIAN_E
+**
+******************************************************************************/
+typedef enum
+{
+    GD_VO_I80_CMD_LITTLE_ENDIAN = 0 ,//!< low byte first.
+    GD_VO_I80_CMD_BIG_ENDIAN =1 ,    //!< high byte first.  
+}GD_VO_I80_CMD_ENDIAN_E;
+
+
+/*!
+*******************************************************************************
+**
+** \brief the struct of picture resolution.
+**
+** \sa    GD_VO_I80_PIC_RESOLUTION_S
+**
+******************************************************************************/
+typedef struct
+{
+    U16 width;
+    U16 height; 
+}GD_VO_I80_PIC_RESOLUTION_S;
+
+
+typedef struct
+{
+    U16 firstHTime;//11bits,10us/unit
+    U16 firstLTime;//11bits,10us/unit
+    U16 secondHTime;//11bits,100us/unit
+}GD_VO_I80_RST_TIMING_S;
+
+typedef struct
+{
+    U16 twrh;//9bit
+    U16 twrl;//9bit
+    U16 trdh;//9bit
+    U16 trdl;//9bit
+    U8  csref;//0--wr/rd as reference   1--cs as reference
+    U16 tas;//9bit
+    U16 pwcsh_wt;//9bit when cs_ref=1
+    U16 pwcsl_wt;//9bit when cs_ref=1
+    U16 pwcsh_rd;//9bit when cs_ref=1
+    U16 pwcsl_rd;//9bit when cs_ref=1
+    U16 todh;//9bit
+}GD_VO_I80_TRANS_TIMING_S;
+
+
+typedef struct
+{
+    U16 rdstatecmd;//read command--write to driver ic of lcd
+    U8  rdnum;//state number including dummy
+    U8  rddummynum;//dummy number
+    U16 *plcdinfo;//array for lcd state, dummy state will not be put into plcdinfo
+}GD_VO_I80_READ_STATE_S;//only one read command
+
+typedef struct
+{
+//  GBOOL bcmdwr;//1--include reading command
+//  GBOOL bcmdrd;//1--include writing command
+    U8    cmdparanum;//1--total number of command and parameter
+    U8    rdnum;//state number including dummy
+    U32  *plcdcmdpara;//array of command and parameter 
+    U16  *plcdinfo;//array of lcd state, dummy state will be put into plcdinfo
+}GD_VO_I80_TRANS_STATE_S;
+
+///*!
+//*******************************************************************************
+//**
+//** I80 OPEN  parameter.
+//**
+//******************************************************************************/
+typedef struct
+{
+    /*!
+    Flag to request DMA for read/write transfer operation.
+    */
+//	U32                 	using;
+	GD_VO_I80_DATA_WIDTH_E 	datawidth;
+	GD_VO_I80_COLOR_FORMAT_E   colorformat;
+	GD_VO_I80_TRANS_FORMAT_E   datatransformat;	
+	U16						wrcmd;/*write pixel command*/
+	U16						rdcmd;/*read pixel command*/
+	GD_VO_I80_CMD_WIDTH_E		cmdwidth;
+	GD_VO_I80_CMD_ENDIAN_E		cmdformat;
+	U32						polarctrl;
+	GD_VO_I80_PIC_RESOLUTION_S picresolution;	
+	GD_VO_I80_TRANS_TIMING_S	transtiming;
+	U32						isUseHWDelay;
+	U16						delayms;
+	U16						delaycmd;
+//	GBOOL 					isCfgValidImmediately;
+} GD_VO_I80_OPEN_PARAMS_S;
+
+typedef struct
+{
+    U32                         using;
+    GD_VO_I80_DATA_WIDTH_E      datawidth;
+    GD_VO_I80_COLOR_FORMAT_E    colorformat;
+    GD_VO_I80_TRANS_FORMAT_E    datatransformat;
+    U16                         wrcmd;/*write command*/
+    U16                         rdcmd;/*read command*/
+    GD_VO_I80_CMD_WIDTH_E       cmdwidth;
+    GD_VO_I80_CMD_ENDIAN_E      cmdformat;
+    U32                         polarctrl;
+    GD_VO_I80_PIC_RESOLUTION_S  picresolution;
+    GD_VO_I80_RST_TIMING_S      rstlcmtiming;
+    GD_VO_I80_TRANS_TIMING_S    transtiming;
+    U32                         isUseHWDelay;
+    U16                         delayms;
+    U16                         delaycmd;
+    GBOOL                       isCfgValidImmediately;
+//    GD_HANDLE           i80Handle;      /* INT handle */
+//    GD_I2S_ISR_T        i2sIsrRx;       /* ISR of the block */
+//    GD_I2S_ISR_T        i2sIsrTx;       /* ISR of the block */
+} GD_VO_I80_STATE_MACHINE_S;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_VO_I80_Exit(void);
+GERR GD_VO_I80_Init(void);
+GERR GD_VO_I80_Open(GD_VO_I80_OPEN_PARAMS_S * openParamsP,GD_HANDLE * pHandle);
+GERR GD_VO_I80_Close(GD_HANDLE *pHandle);
+GERR GD_VO_I80_OnOff(GD_HANDLE *pHandle,GD_VO_I80_ONOFF_E onoff);
+GERR GD_VO_I80_SetTransWidth(GD_HANDLE* pHandle,GD_VO_I80_DATA_WIDTH_E data_width);
+GERR GD_VO_I80_SetPixelTransCmd(GD_HANDLE* pHandle, U16 pixelwrcmd,U16 pixelrdcmd);
+GERR GD_VO_I80_SetPixelBits(GD_HANDLE* pHandle,GD_VO_I80_COLOR_FORMAT_E color_format);
+GERR GD_VO_I80_SetMultiTransSeq(GD_HANDLE* pHandle,GD_VO_I80_TRANS_FORMAT_E datatransformat);
+GERR GD_VO_I80_SetPicResolution(GD_HANDLE* pHandle, GD_VO_I80_PIC_RESOLUTION_S picresolution);
+GERR GD_VO_I80_SetCmdFormat(GD_HANDLE* pHandle,GD_VO_I80_CMD_WIDTH_E cmdwidth,GD_VO_I80_CMD_ENDIAN_E cmdformat);
+GERR GD_VO_I80_SetTransTiming(GD_HANDLE* pHandle,GD_VO_I80_TRANS_TIMING_S *pTranstiming);
+GERR GD_VO_I80_SetCfgValidImmediately(GD_HANDLE* pHandle,GBOOL bValidimmediately);
+GERR GD_VO_I80_CfgInvalid(void);
+GERR GD_VO_I80_CfgValid(void);
+GERR GD_VO_I80_CmdParaInvalid(void);
+GERR GD_VO_I80_CmdParaValid(void);
+GERR GD_VO_I80_SetPolarCtrl(GD_HANDLE* pHandle, U32 polarctrl);
+GERR GD_VO_I80_HWResetLCM(GD_HANDLE* pHandle,GD_VO_I80_RST_TIMING_S *pRrstlcmtiming);
+GERR GD_VO_I80_DelayEnable(GD_HANDLE* pHandle,U16 delayms,U16 delaycmd);
+GERR GD_VO_I80_DelayDisable(GD_HANDLE* pHandle);
+GBOOL GD_VO_I80_CheckNoCmdParaTrans(void);
+GBOOL GD_VO_I80_CheckRdCmdParaReady(void);
+GBOOL GD_VO_I80_ClearRdCmdParaReady(void);
+GERR GD_VO_I80_CheckCmdErr(void);
+GERR GD_VO_I80_CheckSramOverFlowErr(void);
+GERR GD_VO_I80_CheckFramErr(void);
+U16 GD_VO_I80_GetLcdState(U8 indexreg);
+GERR GD_VO_I80_ReadLcdInfo(GD_HANDLE* pHandle,GD_VO_I80_READ_STATE_S *pLcdrdstate);
+//GERR GD_VO_I80_WriteCmdPara(GD_HANDLE * pHandle,U32 lcdcmdpara[],U8 cmdparanum);
+GERR GD_VO_I80_TransCmdPara(GD_HANDLE* pHandle,GD_VO_I80_TRANS_STATE_S *pLcdtransstate);
+GERR GD_VO_I80_EnterPixelWrite(GD_HANDLE* pHandle);
+GERR GD_VO_I80_EnterPixelReading(GD_HANDLE* pHandle);
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_VO_I80_H_ */
+
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 56 - 0
bsp/gkipc/libraries/drv/7102C/gd/inc/gd_wdog.h

@@ -0,0 +1,56 @@
+/******************************************************************************
+**
+** \file      gd_wdog.h
+**
+** \brief     DEMO test application.
+**
+**            (C) Goke Microelectronics China 2002 - 2007
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version   \$Id: gd_wdog.h,v 1.8 2007/01/04 15:13:22 mneuma Exp $
+**
+******************************************************************************/
+
+#ifndef _GD_WDOG_H_
+#define _GD_WDOG_H_
+#include <gtypes.h>
+#include <gmodids.h>
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+#define GD_WDOG_INTENABLE  0x05
+#define GD_WDOG_RSTENABLE  0x03
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+GERR GD_Wdog_Init(void);
+GERR GD_Wdog_Enable(U32 index);
+GERR GD_Wdog_En_Enable(void);
+GERR GD_Wdog_Int_Enable(void);
+GERR GD_Wdog_Rest_Enable(void);
+GERR GD_Wdog_Disable(void);
+GERR GD_Wdog_En_Disable(void);
+GERR GD_Wdog_Int_Disable(void);
+GERR GD_Wdog_Rest_Disable(void);
+GERR GD_Wdog_ClrTimeout(void);
+GERR GD_Wdog_GetTimeout(void);
+GERR GD_Wdog_GetValue(void);
+GERR GD_Wdog_LoadValue(U32 index);
+GERR GD_Wdog_Enable_Reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_WDOG_H_ */
+

+ 44 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/SConscript

@@ -0,0 +1,44 @@
+# for module compiling
+import os
+from building import *
+
+cwd = GetCurrentDir()
+src	= Glob('*.c')
+
+src	+= ['adc/gd_adc.c']
+src	+= ['audio/gd_audio.c']
+src	+= ['crypto/gd_crypto.c']
+src	+= ['dma/gd_dma.c']
+
+src	+= ['emac/gd_eth_emac.c']
+src	+= ['emac/gd_eth_ephy.c']
+src	+= ['emac/gd_eth_phy.c']
+src	+= ['emac/gd_eth_phy_ar8032.c']
+src	+= ['emac/gd_eth_phy_lan8700.c']
+src	+= ['emac/gd_eth_phy_rtl8201.c']
+src	+= ['emac/gd_ethernet.c']
+
+src	+= ['gpio/gd_gpio.c']
+src	+= ['i2c/gd_i2c.c']
+src	+= ['i2s/gd_i2s.c']
+src	+= ['vo_i80/gd_vo_i80.c']
+src	+= ['int/gd_int.c']
+src	+= ['int/gd_int_handler.c']
+src	+= ['int/gd_int_priv.c']
+src	+= ['ir/gd_ir.c']
+src	+= ['pwm/gd_pwm.c']
+src	+= ['sdio/gd_sdio.c']
+src	+= ['sflash/gd_sflash.c']
+src	+= ['sflash/gd_spi_sflash.c']
+src	+= ['spi/gd_spi.c']
+src	+= ['spieeprom/gd_spieeprom.c']
+src	+= ['timer/gd_timer.c']
+src	+= ['uart/gd_uart.c']
+src	+= ['usb/gd_usb.c']
+src	+= ['wdog/gd_wdog.c']
+
+path = [cwd, cwd + '/../inc']
+
+group = DefineGroup('gd', src, depend = [''], CPPPATH = path)
+
+Return('group')

+ 203 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/adc/gd_adc.c

@@ -0,0 +1,203 @@
+/******************************************************************************
+**
+** \file      gh_adc.c
+**
+** \brief     ADC.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+#include <gtypes.h>
+
+#include "gd_adc.h"
+#include "gd_int.h"
+#include "gd_timer.h"
+#include "gh_adc.h"
+
+#ifdef GD_ADC_DEBUG
+#define GD_ADC_PRINTF(args...) printf(args)
+#else
+#define GD_ADC_PRINTF(args...)
+#endif
+
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+typedef struct
+{
+    GD_ADC_CHANNEL_E channel;
+    GD_ADC_CRYPTO_DATA_T control;
+    GBOOL            using;
+    GD_HANDLE        adcHandle;      /* INT handle */
+    //GD_ADC_ISR_T        ADCIsr;         /* ISR of the block */
+} GD_ADC_STATE_MACHINE_S;
+
+volatile GD_ADC_STATE_MACHINE_S ADC_state_machine_data[GD_ADC_CHANNEL_COUNT] = {0};
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+static U8                       ADCInitDone = 0;  //is or not already initialized
+
+static GISR1 gd_ADC_isr(void)
+{
+    printf("I--->ADC0:0x%08x\n", GH_ADC_get_ReadData(GD_ADC_CHANNEL_ONE));
+    printf("I--->ADC1:0x%08x\n", GH_ADC_get_ReadData(GD_ADC_CHANNEL_TWO));
+}
+
+static GERR ADCHandleCheck( GD_HANDLE pHandle )
+{
+    U32                ii;
+    /* check if handle is valid */
+    for (ii = 0; ii < GD_ADC_CHANNEL_COUNT; ii++)
+    {
+        if ((pHandle == (GD_HANDLE)(&ADC_state_machine_data[ii])) && (ADC_state_machine_data[ii].using))
+        {
+            return GD_OK;
+        }
+    }
+    if (ii >= GD_ADC_CHANNEL_COUNT)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    return GD_OK;
+}
+
+GERR GD_ADC_Init( void )
+{
+    U32     i;
+    GERR    ret;
+    GD_INT_OPEN_PARAMS_S    paramsInt;
+    GD_HANDLE               adcHandle  = 0;
+
+    /* check if already initialized */
+    if(ADCInitDone != 0)
+    {
+        return GD_ERR_ALREADY_INITIALIZED;
+    }
+
+    for (i = 0; i < GD_ADC_CHANNEL_COUNT; i++)
+    {
+        ADC_state_machine_data[i].channel       = GD_ADC_CHANNEL_ONE;
+        ADC_state_machine_data[i].using         = GFALSE;
+    }
+
+    /* Open the ADC interrupt */
+    paramsInt.active      = GD_INT_NO_INVERT_IRQ;
+    //paramsInt.priority    = paramsP->priority;
+    paramsInt.sensitivity = GD_INT_BOTH_EDGES;
+
+    paramsInt.type        = GD_INT_ADC_LEVEL_CHANGE_IRQ;
+    paramsInt.isrFct.lowPrio = gd_ADC_isr;
+    ret = GD_INT_Open(&paramsInt, &adcHandle);
+    ADC_state_machine_data[GD_ADC_CHANNEL_ONE].adcHandle = adcHandle;
+    ADC_state_machine_data[GD_ADC_CHANNEL_TWO].adcHandle = adcHandle;
+
+    GH_ADC_set_Enable(GD_ADC_ENABLE_ENABLE);
+    // 0 000 00 1 0 0101 101 0
+    GH_ADC_set_AUX_ATOP_REG0(GD_ADC_AUX_ATOP_INITIALIZE);
+    GH_ADC_set_AUX_ATOP_REG2(0x0075);
+    // 001 0 1 0
+    GH_ADC_set_Control(GD_ADC_CONTROL_INITIALIZE);
+    ADCInitDone = 1;
+
+    return GD_OK;
+}
+
+
+GERR GD_ADC_Exit( void )
+{
+    U32            ii;
+
+    if( ADCInitDone == 0 )
+        return( GD_ERR_NOT_INITIALIZED );
+
+    for (ii = 0; ii < GD_ADC_CHANNEL_COUNT; ii++)
+    {
+        ADC_state_machine_data[ii].using    = GFALSE;
+    }
+    ADCInitDone = 0;
+
+    GH_ADC_set_Enable(GD_ADC_ENABLE_DISABLE);
+    return( GD_OK );
+}
+
+GERR GD_ADC_Open( GD_ADC_OPEN_PARAMS_S *openParamsP, GD_HANDLE* pHandle  )
+{
+    U16             prescale;
+    GD_HANDLE       Gpiohandle;
+    /* Open the ADC interrupt */
+    if((openParamsP == NULL) || (openParamsP->channel >= GD_ADC_CHANNEL_COUNT))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    GH_ADC_set_IntControl(openParamsP->channel, openParamsP->control.data);
+    *pHandle = (GD_HANDLE)(&ADC_state_machine_data[openParamsP->channel]);
+    if(openParamsP->channel == GD_ADC_CHANNEL_ONE)
+    {
+        GH_ADC_set_AUX_ATOP_REG0_sar_maxsel(GD_ADC_CONTROL_CHANNEL_ONE);
+        GH_ADC_set_Control_channel(GD_ADC_REQ_CHANNEL_ONE);
+    }
+    else
+    {
+        GH_ADC_set_AUX_ATOP_REG0_sar_maxsel(GD_ADC_CONTROL_CHANNEL_TWO);
+        GH_ADC_set_Control_channel(GD_ADC_REQ_CHANNEL_TWO);
+    }
+
+    ADC_state_machine_data[openParamsP->channel].channel       = openParamsP->channel;
+    ADC_state_machine_data[openParamsP->channel].using         = GTRUE;
+
+    GD_INT_Enable((GD_HANDLE*)&ADC_state_machine_data[openParamsP->channel].adcHandle, (U8)GD_INT_ENABLED);
+
+    return( GD_OK );
+}
+
+GERR GD_ADC_Close( GD_HANDLE *pHandle )
+{
+    GERR            ret;
+    GD_ADC_STATE_MACHINE_S    *device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device = (GD_ADC_STATE_MACHINE_S *)(*pHandle);
+
+    ret = ADCHandleCheck(*pHandle);
+    if (GD_OK != ret)
+    {
+        return ret;
+    }
+
+    device->using = GFALSE;
+    pHandle = NULL;
+
+    return( GD_OK );
+}
+
+GERR GD_ADC_Read( GD_HANDLE* pHandle, U32* data)
+{
+    GERR    ret;
+    GD_ADC_STATE_MACHINE_S    *device;
+
+    if ((pHandle == NULL) || (data == NULL))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+
+    device = (GD_ADC_STATE_MACHINE_S *)(*pHandle);
+    *data = GH_ADC_get_ReadData(device->channel);
+
+    return( GD_OK );
+}
+
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 1266 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/audio/gd_audio.c

@@ -0,0 +1,1266 @@
+/******************************************************************************
+**
+** \file      gd_audio.c
+**
+** \brief     AUDIO.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      
+**
+******************************************************************************/
+#include <string.h>
+#include <stdio.h>
+
+#include "gh_audio.h"
+#include "gh_i2s.h"
+
+#include "gd_dma.h"
+#include "gd_audio.h"
+#include "gd_timer.h"
+
+#define AUDIO_DEBUG
+
+//#define AUDIO_CHECK_CACHE
+
+#ifdef AUDIO_DEBUG
+#define AUDIO_PRINTF(args...) printf(args)
+#else
+#define AUDIO_PRINTF(args...)
+#endif
+
+#define AUDIO_DEV_AI	0x00004941  //"AI"
+#define AUDIO_DEV_AO	0x00004F41	//"AO"
+
+#define AI_DATA_CHANNEL 1 //single channel
+#define AO_DATA_CHANNEL 2 //AO must stereo channel data.
+
+#define AUDIO_STATE_DISABLE  0
+#define AUDIO_STATE_ENABLE   1
+#define AUDIO_STATE_RUNNING  2
+#define AUDIO_STATE_WAITING  3
+
+#define AUDIO_DEV_MIN_FRAME  2    				 //minimum frame number which device supported.
+#define AUDIO_DEV_MAX_FRAME (DMA_CHAN_MAX_DESC)	 //maximum frame number which device supported.
+#define AUDIO_DEV_MAX_BUFF  (AUDIO_DEV_MAX_FRAME*512)
+#define AUDIO_BUF_MIN_FRAME  2                    //data level  
+
+typedef struct
+{
+	GD_AUDIO_FRAME_S *frameBuffer;
+	GD_AUDIO_FRAME_S *frameRead;
+	GD_AUDIO_FRAME_S *frameWrite;
+	GD_AUDIO_FRAME_S *frameQueHead;
+	GD_AUDIO_FRAME_S *frameQueRear;
+	U32               frameSequence;
+}AUDIO_FRAME_QUENE_S;
+
+typedef struct
+{
+	U32                       audioDev;
+    GD_AUDIO_BIT_WIDTH_E      bitWidth;
+    GD_AUDIO_SOUND_MODE_E     soundMode;
+	GD_AUDIO_SAMPLE_RATE_E    sampleRate;
+    U32                       sampleNumber;
+    U32                       frameNumber;		  //max saved frame number.
+	U32						  frameSize;
+	U8                        *dmaFrameBuffer;    
+	U32                       *dmaReportBuffer;
+	U32                       nextDescriptor;
+	GD_HANDLE                 dmaHandle;
+	U32                       event;
+	U32                       state;
+	U32                       counter;
+	U32                       dmaState;
+	AUDIO_FRAME_QUENE_S       frameQuene;
+	GD_AUDIO_Notifier         notifier;
+}AUDIO_DEV_INFO_S;
+
+static volatile U32  aecFrameSeq = 0;  /*aecNumber*/
+static volatile GBOOL bindMode  = GFALSE;
+static AUDIO_DEV_INFO_S aiDevInfo __attribute__ ((section(".nocache_buffer")));
+static AUDIO_DEV_INFO_S aoDevInfo __attribute__ ((section(".nocache_buffer")));
+static U32 aiReportBuffer[AUDIO_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static U32 aoReportBuffer[AUDIO_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static U8 aiDmaBuffer[AUDIO_DEV_MAX_BUFF] __attribute__ ((aligned(DMA_BUFF_ADDR_ALIGN),section(".nocache_buffer")));
+static U8 aoDmaBuffer[AUDIO_DEV_MAX_BUFF] __attribute__ ((aligned(DMA_BUFF_ADDR_ALIGN),section(".nocache_buffer")));
+static GD_AUDIO_FRAME_S aiFrameBuffer[AUDIO_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static GD_AUDIO_FRAME_S aoFrameBuffer[AUDIO_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static U8 gainLevel = 0;
+static U32 RecAIFrameNum = 0;
+static U32 RecAOFrameNum = 0;
+static void GD_AUDIO_AI_Set_RecFrameNum(U32 RecFrameNum);
+static void GD_AUDIO_AO_Set_RecFrameNum(U32 RecFrameNum);
+
+/************************************************************************************************
+**                             GAIN & REG CONFIG MAP
+**
+** register          : ana_ctrl04
+** config value    :  0x2f  0x2e  0x28  0x29  0x2a  0x2b  0x2c  0x2d   0x3f  0x3e  0x38  0x39  0x3a  0x3b  0x3c  0x3d
+** micA1 bit[4]    : |                         0                                      |                            1                                   |
+** micA2 bit[2:0] :   7      6        0      1        2       3      4       5       7      6        0       1      2        3      4      5
+** micA1 gain(dB): |              -1.5dB      (NOT 13dB)                   |                0.5dB      (NOT 23dB)                    |
+** micA2 gain(dB):  -6    -3       0      3        6       9      12      15     -6     -3       0       3      6        9     12     15
+** total   gain(dB): -7.5  -4.5   -1.5   1.5     4.5    7.5    10.5   13.5  -5.5  -2.5   0.5    3.5    6.5     9.5   12.5  15.5
+**************************************************************************************************/
+static unsigned char gainMap[GAIN_LEVEL_MAX]= 
+{
+    /*ana_ctrl04   */        
+       0x2f,         /* -8  dB */ 
+       0x3f,         /* -6  dB */ 
+       0x2e,         /* -4  dB */ 
+       0x3e,         /* -3  dB */ 
+       0x28,         /* -2  dB */ 
+       0x38,         /*   0  dB */
+       0x29,         /*   2  dB */
+       0x39,         /*   4  dB */
+       0x2a,         /*   5  dB */
+       0x3a,         /*   7  dB */
+       0x2b,         /*   8  dB */
+       0x3b,         /*  10  dB */
+       0x2c,         /*  11  dB */
+       0x3c,         /*  13  dB */
+       0x2d,         /*  14  dB */
+       0x3d,         /* 16  dB */ 
+};
+
+static void set_aec_frame_seq(AUDIO_FRAME_QUENE_S *frameQuene)
+{
+    GD_AUDIO_FRAME_S *ptr_read;
+
+    ptr_read = frameQuene->frameRead;
+    if(ptr_read + 1 >= frameQuene->frameQueRear) {
+        ptr_read = frameQuene->frameQueHead;
+        aecFrameSeq = ptr_read->aecSeq;
+        ptr_read->aecSeq = 0;
+    }
+    else{
+        aecFrameSeq = (ptr_read + 1)->aecSeq;
+        (ptr_read + 1)->aecSeq = 0;
+    }
+}
+
+static void get_aec_frame_seq(unsigned int *aecSeq)
+{
+    *aecSeq = aecFrameSeq;
+    aecFrameSeq = 0;
+}
+
+static void ai_int_handler(void)
+{
+	U32 curDescriptor = 0;
+	U32 dmaStatus     = 0;
+	U32 revFrameNumber = 0;
+	GD_AUDIO_FRAME_S * frameReadPointer = 0;
+	GD_AUDIO_FRAME_S * frameWritePointer = 0;	
+	AUDIO_DEV_INFO_S * pDev = &aiDevInfo;
+	AUDIO_FRAME_QUENE_S *pFrameQue = &pDev->frameQuene;	
+	
+	curDescriptor = pDev->nextDescriptor;
+	pDev->nextDescriptor++;
+	if(pDev->nextDescriptor >= pDev->frameNumber)
+	{
+		pDev->nextDescriptor = 0;
+	}	
+
+	dmaStatus = pDev->dmaReportBuffer[curDescriptor];	
+	if(dmaStatus & DMA_CHAN_STATE_DD)
+	{
+	
+	}	
+	
+	if(dmaStatus & DMA_CHAN_STATE_OD) /* DO NOT verify this field, report buffer will not refresh after DMA int sometimes. */
+	{
+		pFrameQue->frameWrite->timeStamp = GD_TIMER_ReadTimerStamp();
+		pFrameQue->frameWrite->seqNumber = pFrameQue->frameSequence;
+		//pFrameQue->frameWrite->aecSeq	 = aecNumber;
+        get_aec_frame_seq((unsigned int*)&pFrameQue->frameWrite->aecSeq);
+		pFrameQue->frameSequence++;
+
+		if(++pFrameQue->frameWrite >= pFrameQue->frameQueRear)
+		{
+			pFrameQue->frameWrite = pFrameQue->frameQueHead;
+		}
+
+		pDev->dmaReportBuffer[curDescriptor] &= ~(DMA_CHAN_STATE_OD|DMA_CHAN_STATE_DN);
+		
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_FRAME);
+		}
+	}
+	else /* not expected interrupt */
+	{
+		pDev->event = AUDIO_EVENT_UNDEFINED;		  //for debug only.
+		pDev->notifier(AUDIO_EVENT_UNDEFINED);
+	}
+
+
+	frameReadPointer  = pFrameQue->frameRead;
+	frameWritePointer = pFrameQue->frameWrite;
+	if(frameReadPointer <= frameWritePointer)
+	{
+		revFrameNumber = frameWritePointer - frameReadPointer;
+	}
+	else
+	{
+		revFrameNumber = pDev->frameNumber -(frameReadPointer - frameWritePointer);
+	}
+    
+    GD_AUDIO_AI_Set_RecFrameNum(revFrameNumber); //set ai Frame Num
+	if(revFrameNumber >= pDev->frameNumber - AUDIO_BUF_MIN_FRAME)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_WILL_OVERFLOW);
+		}
+		pDev->event = AUDIO_EVENT_WILL_OVERFLOW;
+	}
+	if(revFrameNumber == 0)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_ALREADY_OVERFLOW);
+		}
+		pDev->event = AUDIO_EVENT_ALREADY_OVERFLOW;
+	}		
+
+}
+
+static void ao_int_handler(void)
+{
+	U32 curDescriptor = 0;
+	U32 dmaStatus     = 0;
+	U32 revFrameNumber = 0;
+	GD_AUDIO_FRAME_S * frameReadPointer = 0;
+	GD_AUDIO_FRAME_S * frameWritePointer = 0;	
+	AUDIO_DEV_INFO_S * pDev = &aoDevInfo;
+	AUDIO_FRAME_QUENE_S *pFrameQue = &pDev->frameQuene;
+	
+	curDescriptor = pDev->nextDescriptor;
+	pDev->nextDescriptor++;
+	if(pDev->nextDescriptor >= pDev->frameNumber)
+	{
+		pDev->nextDescriptor = 0;
+	}
+
+	dmaStatus = pDev->dmaReportBuffer[curDescriptor];
+	if(dmaStatus & DMA_CHAN_STATE_DD)
+	{
+	
+	}
+
+	//aecNumber = pFrameQue->frameRead->aecSeq;
+    set_aec_frame_seq(pFrameQue);
+
+	if(dmaStatus & DMA_CHAN_STATE_OD) /* DO NOT verify this field, report buffer will not refresh after DMA int sometimes. */
+	{
+	
+		if(++pFrameQue->frameRead >= pFrameQue->frameQueRear)
+		{
+			pFrameQue->frameRead = pFrameQue->frameQueHead;
+		}
+
+		pDev->dmaReportBuffer[curDescriptor] &= ~(DMA_CHAN_STATE_OD|DMA_CHAN_STATE_DN);
+
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_FRAME);
+		}
+	}		
+	else /* not expected interrupt */
+	{
+		pDev->event = AUDIO_EVENT_UNDEFINED;         //for debug only.
+		pDev->notifier(AUDIO_EVENT_UNDEFINED);
+	}
+
+
+	frameReadPointer  = pFrameQue->frameRead;
+	frameWritePointer = pFrameQue->frameWrite;
+	if(frameReadPointer <= frameWritePointer)
+	{
+		revFrameNumber = frameWritePointer - frameReadPointer;
+	}
+	else
+	{
+		revFrameNumber = pDev->frameNumber -(frameReadPointer - frameWritePointer);
+	}
+
+    GD_AUDIO_AO_Set_RecFrameNum(pDev->frameNumber - revFrameNumber); //set ao valid Frame buffer 
+	if(revFrameNumber <= 0)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_ALREADY_UNDERFLOW);
+		}
+		pDev->event = AUDIO_EVENT_ALREADY_UNDERFLOW;
+
+		GH_AUDIO_set_FIFO_CTRL_TX_FIFO_ENABLE(0);
+		pDev->state = AUDIO_STATE_WAITING;
+	}		
+	else if(revFrameNumber <= AUDIO_BUF_MIN_FRAME)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(AUDIO_EVENT_WILL_UNDERFLOW);
+		}
+		pDev->event = AUDIO_EVENT_WILL_UNDERFLOW;
+	}
+}
+
+
+static GERR dma_open(AUDIO_DEV_INFO_S *dev)
+{
+	U32 i = 0;
+	U32 align_offset = 0;
+	GERR err = GD_OK;
+	GD_DMA_DESCRIPTOR_S dmaDescriptor;
+	GD_DMA_OPEN_PARAM_S dmaOpenParam;
+		
+	if(dev->frameNumber<=0 || dev->frameSize<=0)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	////////////////////////////////
+	//config descriptor
+	////////////////////////////////
+	
+	if(dev->audioDev == AUDIO_DEV_AI)
+	{
+		dev->dmaReportBuffer = aiReportBuffer;
+		dev->dmaFrameBuffer  = aiDmaBuffer;
+		dmaOpenParam.channel = DMA_CHAN_AUDIO_RX;
+		dmaOpenParam.mode    = DMA_MODE_DESCRIPTOR;
+		dmaOpenParam.intNotifier = ai_int_handler;
+	}
+	else /* AUDIO_DEV_AO */
+	{
+		dev->dmaReportBuffer = aoReportBuffer;
+		dev->dmaFrameBuffer  = aoDmaBuffer;
+		dmaOpenParam.channel = DMA_CHAN_AUDIO_TX;
+		dmaOpenParam.mode	 = DMA_MODE_DESCRIPTOR;
+		dmaOpenParam.intNotifier = ao_int_handler;
+	}
+	AUDIO_PRINTF("[GD_AUDIO]dmaFrameBuffer:0x%08X\n", dev->dmaFrameBuffer);
+	
+	err = GD_DMA_Open(&dmaOpenParam, &dev->dmaHandle);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	////////////////////////////////
+	//config descriptor
+	////////////////////////////////	
+	for(i=0; i<dev->frameNumber; i++) 
+	{
+		if(dev->audioDev == AUDIO_DEV_AI)
+		{
+			dmaDescriptor.srcAddr  = DMA_RX_REG;
+			dmaDescriptor.dstAddr  = (U32)dev->dmaFrameBuffer + i * dev->frameSize;
+			dmaDescriptor.descAttr = DMA_DESC_WM|DMA_DESC_NI|DMA_DESC_TS_2B /*|DMA_DESC_EOC*/
+				                   |DMA_DESC_BLK_8B|DMA_DESC_ID|DMA_DESC_IE|DMA_DESC_ST;
+		}
+		else /* AUDIO_DEV_AO */
+		{
+			dmaDescriptor.srcAddr  = (U32)dev->dmaFrameBuffer + i * dev->frameSize;
+			dmaDescriptor.dstAddr  = DMA_TX_REG;
+			dmaDescriptor.descAttr = DMA_DESC_RM|DMA_DESC_NI|DMA_DESC_TS_4B /*|DMA_DESC_EOC*/
+				                   |DMA_DESC_BLK_8B|DMA_DESC_ID|DMA_DESC_IE|DMA_DESC_ST;		
+		}
+
+		dmaDescriptor.dataLength = dev->frameSize;
+		dmaDescriptor.reportAddr = (U32)(dev->dmaReportBuffer + i);
+		dmaDescriptor.next       = NULL;
+
+		err = GD_DMA_AddDescriptor(dev->dmaHandle, &dmaDescriptor);
+		if(err != GD_OK)
+		{
+			return err;
+		}		
+	} 
+
+	return GD_OK;	
+}
+
+static GERR dma_close(AUDIO_DEV_INFO_S *dev)
+{
+	if(dev == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	////////////////////////////////
+	//disable DMA
+	////////////////////////////////	
+	GD_DMA_Stop(dev->dmaHandle);
+	GD_DMA_Close(dev->dmaHandle);
+
+	return GD_OK;
+}
+
+static GERR frame_open(AUDIO_DEV_INFO_S *dev)
+{
+	U32 i = 0;
+	AUDIO_FRAME_QUENE_S *pQue = &dev->frameQuene;
+
+	if(dev==NULL || dev->frameNumber<=0)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	if(dev->audioDev == AUDIO_DEV_AI)
+	{
+		pQue->frameBuffer = aiFrameBuffer;
+	}
+	else /* AUDIO_DEV_AO */
+	{
+		pQue->frameBuffer = aoFrameBuffer;
+	}
+
+	for(i=0; i<dev->frameNumber; i++)
+	{
+		pQue->frameBuffer[i].frameAddr = (U32)dev->dmaFrameBuffer+dev->frameSize*i;
+		pQue->frameBuffer[i].frameSize = dev->frameSize;
+		pQue->frameBuffer[i].bitWidth  = dev->bitWidth;
+		pQue->frameBuffer[i].soundMode = dev->soundMode;
+		pQue->frameBuffer[i].sampleRate= dev->sampleRate;
+	}
+
+	pQue->frameQueHead = pQue->frameBuffer;
+	pQue->frameQueRear = pQue->frameBuffer + dev->frameNumber;
+	pQue->frameRead = pQue->frameQueHead;
+	pQue->frameWrite= pQue->frameQueHead;
+	pQue->frameSequence = 0;
+
+	return GD_OK;
+}
+
+static GERR frame_close(AUDIO_DEV_INFO_S *dev)
+{
+	AUDIO_FRAME_QUENE_S *pQue = &dev->frameQuene;
+	
+	if(dev == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	pQue->frameBuffer  = NULL;
+	pQue->frameQueHead = NULL;
+	pQue->frameQueRear = NULL;
+	pQue->frameRead    = NULL;
+	pQue->frameWrite   = NULL;
+	pQue->frameSequence = 0;
+
+	return GD_OK;
+}
+
+static void audio_init(void)
+{
+	/* DMA select */
+    GH_AUDIO_set_AHB_GENERAL1(0x01);
+
+	/* analog config */
+	GH_AUDIO_set_ANALOG_CTRL00(0x8040);
+	GH_AUDIO_set_ANALOG_CTRL03(0x4004);
+	GH_AUDIO_set_ANALOG_CTRL04(0x2000);
+	GH_AUDIO_set_ANALOG_CTRL06(0x0004);
+	GH_AUDIO_set_ANALOG_CTRL11(0x0000);
+	GH_AUDIO_set_ANALOG_CTRL13(0x6000);
+	GD_TIMER_Delay(1);
+	GH_AUDIO_set_ANALOG_CTRL00(0x8040);
+	GH_AUDIO_set_ANALOG_CTRL03(0x401C);  
+	GH_AUDIO_set_ANALOG_CTRL04(0x233A);	 
+	GH_AUDIO_set_ANALOG_CTRL05(0x280C);
+	GH_AUDIO_set_ANALOG_CTRL06(0x8407);
+	GH_AUDIO_set_ANALOG_CTRL07(0x3802);
+	GH_AUDIO_set_ANALOG_CTRL08(0x00F8);
+	GH_AUDIO_set_ANALOG_CTRL09(0x0000);
+	GH_AUDIO_set_ANALOG_CTRL10(0xC0C0);
+	GH_AUDIO_set_ANALOG_CTRL11(0x9080);
+	GH_AUDIO_set_ANALOG_CTRL12(0x0000);
+	GH_AUDIO_set_ANALOG_CTRL13(0x6000);
+
+	/* digital config */
+	GH_AUDIO_set_MMP_DPGA_CFG1(0, 0x5);  //MMP1_DPGA_CFG1
+	GH_AUDIO_set_MMP_DPGA_CFG1(1, 0x5);  //MMP2_DPGA_CFG1
+	GH_AUDIO_set_SYS_RST_CTRL0(0xE000);
+	GH_AUDIO_set_SYS_RST_CTRL0(0);
+	GH_AUDIO_set_AUDIOBAND_CTRL0(2);
+	GH_AUDIO_set_CKG_CTRL0(3);
+	GH_AUDIO_set_TIMING_CTRL0(0x33F);
+	GH_AUDIO_set_TIMING_CTRL1(0xF3E);
+	GH_AUDIO_set_AUDIOBAND_CTRL2(0xFAAF);
+	GH_AUDIO_set_SDM_CTRL0(0x15);
+	GH_AUDIO_set_MMP_DPGA_CFG1(0, 0);  //MMP1_DPGA_CFG1
+	GH_AUDIO_set_MMP_DPGA_CFG1(1, 0);  //MMP2_DPGA_CFG1
+	GH_AUDIO_set_TIMING_CTRL0(0x23F);
+	GH_AUDIO_set_MIX_CTRL0(0x2500);	   
+	GH_AUDIO_set_TIMING_CTRL1(0x23E);
+	GH_AUDIO_set_AUDIOBAND_CTRL1(0xEA82);
+	GH_AUDIO_set_AUDIOBAND_CTRL2(0xAAAF);
+	GH_AUDIO_set_ANALOG_CTRL02(8);
+	
+	GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000BB);
+	GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00008000);
+    GD_TIMER_Delay(1);
+	GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C0BB);
+    GD_TIMER_Delay(1);
+	GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000BB);
+	GH_AUDIO_set_NF_SYNTH_2_NF_H(0x000000c0);
+	GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+    GD_TIMER_Delay(1);
+	GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000c0c0);
+    GD_TIMER_Delay(1);
+	GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000c0);
+	GH_AUDIO_set_FIFO_TH_CTRL0(0x402);
+	GH_AUDIO_set_FIFO_CTRL(0);
+//	GH_AUDIO_set_FIFO_CTRL(0x8888);
+}
+#ifdef AUDIO_CHECK_CACHE
+void audio_cache_config(void)
+{
+	U32 reg;
+    __asm__ __volatile__ (
+        " mrc p15, 0, %0, c1, c0, 0 \n"
+        : "=r" (reg)
+        :
+        : "memory");
+	AUDIO_PRINTF("cache 0x%X\n",reg);
+}
+#endif
+
+static GERR audio_ai_set_attr(GD_AUDIO_ATTR_S *pattr)
+{
+    switch(pattr->sampleRate)
+    {
+	    case AUDIO_SAMPLE_RATE_8000:
+			GH_AUDIO_set_TIMING_CTRL0(0x003F);
+	        break;
+	    case AUDIO_SAMPLE_RATE_16000:
+	        GH_AUDIO_set_TIMING_CTRL0(0x013F);
+	        break;
+	    case AUDIO_SAMPLE_RATE_32000:
+	        GH_AUDIO_set_TIMING_CTRL0(0x023F);
+	        break;
+	    default:
+	        return GD_ERR_BAD_PARAMETER;
+    }
+
+    switch(pattr->soundMode)
+    {
+	    case AUDIO_SOUND_MODE_SINGLE:
+			GH_AUDIO_set_MIX_CTRL0_SEL_DEC2_DOUT(0);
+	        break;
+	    case AUDIO_SOUND_MODE_STEREO:
+	    case AUDIO_SOUND_MODE_LEFT:
+	    case AUDIO_SOUND_MODE_RIGHT:
+	    case AUDIO_SOUND_MODE_MONO:
+	        return GD_ERR_AUDIO_NOT_SUPPORTED;
+	    default:
+	        return GD_ERR_BAD_PARAMETER;
+    }
+	
+    return GD_OK;
+}
+
+static GERR audio_ao_set_attr(GD_AUDIO_ATTR_S *pattr)
+{
+    switch(pattr->sampleRate)
+    {
+	    case AUDIO_SAMPLE_RATE_8000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000002EE);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C2EE);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000002EE);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000300);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C300);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000300);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_11025:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000220);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x000037BA);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C220);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000220);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000022D);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00004766);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C22D);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000022D);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_12000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000001F4);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C1F4);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000001F4);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000200);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C200);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000200);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_16000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000177);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C177);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000177);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000180);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C180);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000180);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_22050:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000110);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00001BDD);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C110);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000110);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000116);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x0000A3B3);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C116);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000116);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_24000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000FA);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C0FA);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000FA);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000100);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C100);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000100);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_32000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000BB);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00008000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C0BB);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x000000BB);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x000000C0);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C0C0);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x000000C0);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_44100:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000088);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000DEF);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C088);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x00000088);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000008B);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x000051DA);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C08B);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000008B);			
+	        break;
+	    case AUDIO_SAMPLE_RATE_48000:
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000007D);
+			GH_AUDIO_set_NF_SYNTH_1_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000C07D);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_1_NF_H(0x0000007D);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000080);
+			GH_AUDIO_set_NF_SYNTH_2_NF_L(0x00000000);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x0000C080);
+		    GD_TIMER_Delay(1);
+			GH_AUDIO_set_NF_SYNTH_2_NF_H(0x00000080);			
+	        break;
+	    default:
+	        return GD_ERR_BAD_PARAMETER;
+    }
+
+    switch(pattr->soundMode)
+    {
+	    case AUDIO_SOUND_MODE_LEFT:
+			GH_AUDIO_set_MIX_CTRL0_CH1_MUX_SEL(0);
+			GH_AUDIO_set_MIX_CTRL0_CH2_MUX_SEL(3);
+	        break;
+	    case AUDIO_SOUND_MODE_RIGHT:
+			GH_AUDIO_set_MIX_CTRL0_CH1_MUX_SEL(3);
+			GH_AUDIO_set_MIX_CTRL0_CH2_MUX_SEL(0);
+	        break;
+	    case AUDIO_SOUND_MODE_STEREO:
+	    case AUDIO_SOUND_MODE_MONO:
+			GH_AUDIO_set_MIX_CTRL0_CH1_MUX_SEL(0);
+			GH_AUDIO_set_MIX_CTRL0_CH2_MUX_SEL(0);
+	        break;
+	    case AUDIO_SOUND_MODE_SINGLE:
+			GH_AUDIO_set_MIX_CTRL0_CH1_MUX_SEL(0);
+			GH_AUDIO_set_MIX_CTRL0_CH2_MUX_SEL(3);
+	        break;
+	    default:
+	        return GD_ERR_BAD_PARAMETER;
+    }
+
+    return GD_OK;
+}
+
+static void audio_ao_set_volume(int vol)
+{
+	U16 volume = 0;
+	
+    volume = vol<<8|vol;
+	GH_AUDIO_set_PGA_DPGA_CFG(volume);
+}
+
+GERR GD_AUDIO_Init(void)
+{
+	GERR err = GD_OK;
+	
+    audio_init();
+	audio_ao_set_volume(VOL_LEVEL_8);
+
+	memset(&aiDevInfo, 0, sizeof(AUDIO_DEV_INFO_S));
+	memset(&aoDevInfo, 0, sizeof(AUDIO_DEV_INFO_S));
+
+#ifdef AUDIO_CHECK_CACHE
+	audio_cache_config();
+#endif
+    return GD_OK;
+}
+
+GERR GD_AUDIO_Exit(void)
+{
+    return GD_OK;
+}
+
+GERR GD_AUDIO_Bind_Ai2Ao(void)
+{
+	if(bindMode == GTRUE)
+	{
+		return GD_OK;
+	}
+
+	GD_DMA_Stop(aiDevInfo.dmaHandle);	
+	GD_DMA_Stop(aoDevInfo.dmaHandle);
+	
+	GD_TIMER_Delay(10);
+	GH_AUDIO_set_MIX_CTRL0(0x6518);
+	
+	bindMode  = GTRUE;
+    return GD_OK;
+}
+
+GERR GD_AUDIO_Unbind_Ai2Ao(void)
+{
+	if(bindMode == GFALSE)
+	{
+		return GD_OK;
+	}
+
+	GH_AUDIO_set_MIX_CTRL0(0x2500);
+
+	GD_DMA_Start(aiDevInfo.dmaHandle, 0);	
+	GD_DMA_Start(aoDevInfo.dmaHandle, 0);
+
+	bindMode  = GFALSE;
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AI_Open(GD_AUDIO_OPEN_PARAM_S *openParamPtr)
+{
+	GERR err = GD_OK;
+	U32  frameNumber = 0, frameSize = 0;
+	GD_AUDIO_ATTR_S attr;
+	AUDIO_DEV_INFO_S *pDev = &aiDevInfo;
+
+	if(pDev->audioDev == AUDIO_DEV_AI)
+	{
+		return GD_ERR_ALREADY_OPEN;
+	}
+	if(openParamPtr->sampleNumber<=0)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	frameSize = openParamPtr->sampleNumber * (openParamPtr->bitWidth>>3) * AI_DATA_CHANNEL;
+	if((frameSize % DMA_BUFF_ADDR_ALIGN) != 0)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+
+	frameNumber = AUDIO_DEV_MAX_BUFF / frameSize;
+	if(frameNumber < AUDIO_DEV_MIN_FRAME)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+	if(frameNumber > AUDIO_DEV_MAX_FRAME)
+	{
+		frameNumber = AUDIO_DEV_MAX_FRAME;
+	}		
+	
+	pDev->audioDev     = AUDIO_DEV_AI;
+	pDev->state        = AUDIO_STATE_DISABLE;
+	pDev->bitWidth     = openParamPtr->bitWidth;
+	pDev->sampleRate   = openParamPtr->sampleRate;
+	pDev->sampleNumber = openParamPtr->sampleNumber;
+	pDev->soundMode    = openParamPtr->soundMode;
+	pDev->frameNumber  = frameNumber;
+	pDev->frameSize    = frameSize;
+	pDev->notifier     = openParamPtr->notifier;
+
+	err = dma_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	err = frame_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	attr.sampleRate = openParamPtr->sampleRate;
+	attr.soundMode  = openParamPtr->soundMode;
+	err = audio_ai_set_attr(&attr);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AI_Close(void)
+{
+	GERR err = GD_OK;
+	
+	err = dma_close(&aiDevInfo);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	err = frame_close(&aiDevInfo);
+	if(err != GD_OK)
+	{
+		return err;
+	}	
+
+    return GD_OK;
+}
+
+
+GERR GD_AUDIO_AI_Enable(void)
+{
+	GERR err = GD_OK;
+	AUDIO_DEV_INFO_S *pDev = &aiDevInfo;
+
+	if(pDev->state==AUDIO_STATE_ENABLE || pDev->state==AUDIO_STATE_RUNNING)
+	{
+		return GD_ERR_AUDIO_DEV_BUSY;
+	}	
+
+	GH_AUDIO_set_FIFO_CTRL_RX_FIFO_STATUS_CLR(0);
+	GH_AUDIO_set_FIFO_CTRL_RX_FIFO_INT_EN(8);
+	GH_AUDIO_set_FIFO_CTRL_RX_FIFO_ENABLE(1);
+
+	memset(pDev->dmaFrameBuffer, 0, pDev->frameNumber*pDev->frameSize);
+	pDev->nextDescriptor = 0;
+	pDev->frameQuene.frameRead = pDev->frameQuene.frameQueHead;
+	pDev->frameQuene.frameWrite= pDev->frameQuene.frameQueHead;	
+	pDev->state = AUDIO_STATE_ENABLE;
+	
+	err = GD_DMA_Start(pDev->dmaHandle, 0);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	pDev->state = AUDIO_STATE_RUNNING;
+	
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AI_Disable(void)
+{
+	GERR err = GD_OK;
+	
+	err = GD_DMA_Stop(aiDevInfo.dmaHandle);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	aiDevInfo.state = AUDIO_STATE_DISABLE;
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AI_Read_Frame(GD_AUDIO_FRAME_S *frame)
+{
+	U32 revFrameNumber = 0;
+	AUDIO_DEV_INFO_S    *pDev = &aiDevInfo;
+	AUDIO_FRAME_QUENE_S *pFrameQue = &pDev->frameQuene;
+	GD_AUDIO_FRAME_S    *frameReadPointer = NULL; 
+	GD_AUDIO_FRAME_S    *frameWritePointer = NULL;
+	
+	if(frame == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	if(pDev->state == AUDIO_STATE_DISABLE)
+	{
+		return GD_ERR_AUDIO_NOT_SUPPORTED;
+	}	
+
+	if(pDev->event == AUDIO_EVENT_ALREADY_OVERFLOW)
+	{
+		// TODO: overflow.
+	}	
+/*
+	if(frameReadPointer <= frameWritePointer)
+	{
+		revFrameNumber = frameWritePointer - frameReadPointer;
+	}
+	else
+	{
+		revFrameNumber = pDev->frameNumber -(frameReadPointer - frameWritePointer);
+	}
+
+	if(revFrameNumber <= 0)
+	{
+		return GD_ERR_AUDIO_DEV_WAIT;
+	}	
+*/
+
+	frameReadPointer = pFrameQue->frameRead; 
+	frameWritePointer = pFrameQue->frameWrite;
+
+	if(frameWritePointer == frameReadPointer)
+	{
+		return GD_ERR_AUDIO_DEV_WAIT;
+	}		
+
+	memcpy(frame, pFrameQue->frameRead, sizeof(GD_AUDIO_FRAME_S));
+
+	if(++pFrameQue->frameRead>= pFrameQue->frameQueRear)
+	{
+		pFrameQue->frameRead = pFrameQue->frameQueHead;
+	}
+	
+    return GD_OK;
+}
+
+static void GD_AUDIO_AI_Set_RecFrameNum(U32 RecFrameNum)
+{
+	RecAIFrameNum = RecFrameNum;
+}
+
+U32 GD_AUDIO_AI_Get_RecFrameNum(void)
+{
+	return RecAIFrameNum;
+}
+
+GERR GD_AUDIO_AI_Set_Attr(GD_AUDIO_ATTR_S *pattr)
+{
+	GERR err = GD_OK;
+
+	err = audio_ai_set_attr(pattr);
+    if(err == GD_OK)
+	{
+		aiDevInfo.sampleRate = pattr->sampleRate;
+		aiDevInfo.soundMode  = pattr->soundMode;
+	}
+
+    return err;
+}
+
+GERR GD_AUDIO_AI_Get_Attr(GD_AUDIO_ATTR_S *pattr)
+{
+	pattr->sampleRate = aiDevInfo.sampleRate;
+	pattr->soundMode  = aiDevInfo.soundMode;
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AI_Set_Gain(GD_AUDIO_GAIN_E gain)
+{
+	U16 value = 0;
+	
+	value = GH_AUDIO_get_ANALOG_CTRL04();
+	GH_AUDIO_set_ANALOG_CTRL04((value&(~0x00FF))|gainMap[gain]);
+
+    gainLevel = gain;
+    return GD_OK;
+}
+
+GD_AUDIO_GAIN_E GD_AUDIO_AI_Get_Gain(void)
+{
+    return gainLevel;
+}
+
+GERR GD_AUDIO_AO_Open(GD_AUDIO_OPEN_PARAM_S *openParamPtr)
+{
+	GERR err = GD_OK;
+	U32  frameNumber = 0, frameSize = 0;
+	GD_AUDIO_ATTR_S attr;
+	AUDIO_DEV_INFO_S *pDev = &aoDevInfo;
+
+	if(pDev->audioDev == AUDIO_DEV_AO)
+	{
+		return GD_ERR_ALREADY_OPEN;
+	}
+	if(openParamPtr->sampleNumber<=0)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}	
+
+	frameSize = openParamPtr->sampleNumber * (openParamPtr->bitWidth>>3) * AO_DATA_CHANNEL;
+	if((frameSize % DMA_BUFF_ADDR_ALIGN) != 0)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+
+	frameNumber = AUDIO_DEV_MAX_BUFF / frameSize;
+	if(frameNumber < AUDIO_DEV_MIN_FRAME)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+	if(frameNumber > AUDIO_DEV_MAX_FRAME)
+	{
+		frameNumber = AUDIO_DEV_MAX_FRAME;
+	}
+	
+	pDev->audioDev     = AUDIO_DEV_AO;
+	pDev->state        = AUDIO_STATE_DISABLE;
+	pDev->bitWidth     = openParamPtr->bitWidth;
+	pDev->sampleRate   = openParamPtr->sampleRate;
+	pDev->sampleNumber = openParamPtr->sampleNumber;
+	pDev->soundMode    = openParamPtr->soundMode;
+	pDev->frameNumber  = frameNumber;
+	pDev->frameSize    = frameSize;
+	pDev->notifier     = openParamPtr->notifier;
+
+	err = dma_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	err = frame_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}	
+
+	attr.sampleRate = openParamPtr->sampleRate;
+	attr.soundMode  = openParamPtr->soundMode;
+	err = audio_ao_set_attr(&attr);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Close(void)
+{
+	GERR err = GD_OK;
+	
+	err = dma_close(&aoDevInfo);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	err = frame_close(&aoDevInfo);
+	if(err != GD_OK)
+	{
+		return err;
+	}	
+
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Enable(void)
+{
+	AUDIO_DEV_INFO_S	*pDev = &aoDevInfo;
+
+	if(pDev->state==AUDIO_STATE_ENABLE || pDev->state==AUDIO_STATE_RUNNING)
+	{
+		return GD_ERR_AUDIO_DEV_BUSY;
+	}
+
+	GH_AUDIO_set_FIFO_CTRL_TX_FIFO_STATUS_CLR(0);
+	GH_AUDIO_set_FIFO_CTRL_TX_FIFO_INT_EN(8);
+	GH_AUDIO_set_FIFO_CTRL_TX_FIFO_ENABLE(1);			
+
+	memset(pDev->dmaFrameBuffer, 0, pDev->frameNumber*pDev->frameSize);
+	pDev->nextDescriptor = 0;
+	pDev->frameQuene.frameRead = pDev->frameQuene.frameQueHead;
+	pDev->frameQuene.frameWrite= pDev->frameQuene.frameQueHead;
+	pDev->state = AUDIO_STATE_ENABLE;
+	
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Disable(void)
+{
+	GERR err = GD_OK;
+	
+	err = GD_DMA_Stop(aoDevInfo.dmaHandle);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	aoDevInfo.state = AUDIO_STATE_DISABLE;	
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Write_Frame(GD_AUDIO_FRAME_S *frame)
+{
+	U32 revFrameNumber = 0;
+	GERR err = GD_OK;
+	AUDIO_DEV_INFO_S	*pDev = &aoDevInfo;
+	AUDIO_FRAME_QUENE_S *pFrameQue = &pDev->frameQuene;
+	GD_AUDIO_FRAME_S	*frameReadPointer = pFrameQue->frameRead; 
+	GD_AUDIO_FRAME_S	*frameWritePointer = pFrameQue->frameWrite;
+	
+	if(frame == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+	
+	if(pDev->state == AUDIO_STATE_DISABLE)
+	{
+		return GD_ERR_AUDIO_NOT_SUPPORTED;
+	}		
+
+	if((frameWritePointer-pFrameQue->frameQueHead+1)%pDev->frameNumber == frameReadPointer-pFrameQue->frameQueHead)
+	{
+		return GD_ERR_AUDIO_DEV_BUSY;
+	}	
+
+	pFrameQue->frameWrite->aecSeq = frame->aecSeq;
+	memcpy(frame, pFrameQue->frameWrite, sizeof(GD_AUDIO_FRAME_S));
+
+	if(++pFrameQue->frameWrite >= pFrameQue->frameQueRear)
+	{
+		pFrameQue->frameWrite = pFrameQue->frameQueHead;
+	}
+
+	if(pDev->state==AUDIO_STATE_ENABLE || pDev->state==AUDIO_STATE_WAITING)
+	{
+		if(frameReadPointer <= frameWritePointer)
+		{
+			revFrameNumber = frameWritePointer - frameReadPointer;
+		}
+		else
+		{
+			revFrameNumber = pDev->frameNumber - (frameReadPointer - frameWritePointer);
+		}
+
+		if(revFrameNumber>=AUDIO_BUF_MIN_FRAME && pDev->state==AUDIO_STATE_ENABLE)
+		{
+			err = GD_DMA_Start(pDev->dmaHandle, 0);
+			if(err != GD_OK)
+			{
+				return err;
+			}
+			pDev->state = AUDIO_STATE_RUNNING;
+		}
+		if(revFrameNumber>=AUDIO_BUF_MIN_FRAME && pDev->state==AUDIO_STATE_WAITING)
+		{
+			GH_AUDIO_set_FIFO_CTRL_TX_FIFO_ENABLE(1);
+			pDev->state = AUDIO_STATE_RUNNING;
+		}		
+	}
+
+	return GD_OK;
+}
+
+static void GD_AUDIO_AO_Set_RecFrameNum(U32 RecFrameNum)
+{
+	RecAOFrameNum = RecFrameNum;
+}
+
+U32 GD_AUDIO_AO_Get_RecFrameNum(void)
+{
+	return RecAOFrameNum;
+}
+
+GERR GD_AUDIO_AO_Set_Attr(GD_AUDIO_ATTR_S *pattr)
+{
+	GERR err = GD_OK;
+
+	err = audio_ao_set_attr(pattr);
+    if(err == GD_OK)
+	{
+		aoDevInfo.sampleRate = pattr->sampleRate;
+		aoDevInfo.soundMode  = pattr->soundMode;
+	}
+
+    return err;
+}
+
+GERR GD_AUDIO_AO_Get_Attr(GD_AUDIO_ATTR_S *pattr)
+{
+	pattr->sampleRate = aoDevInfo.sampleRate;
+	pattr->soundMode  = aoDevInfo.soundMode;
+
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Set_Volume(GD_AUDIO_VOLUME_E volume)
+{
+	audio_ao_set_volume(volume);
+
+    return GD_OK;
+}
+
+GD_AUDIO_VOLUME_E GD_AUDIO_AO_Get_Volume(void)
+{
+    return ((GH_AUDIO_get_PGA_DPGA_CFG()&(~0x4040))>>8);
+}
+
+GERR GD_AUDIO_AO_Mute(void)
+{
+	GH_AUDIO_set_PGA_DPGA_CFG_PGA1_mute(1);
+	GH_AUDIO_set_PGA_DPGA_CFG_PGA2_mute(1);
+    return GD_OK;
+}
+
+GERR GD_AUDIO_AO_Unmute(void)
+{
+	GH_AUDIO_set_PGA_DPGA_CFG_PGA1_mute(0);
+	GH_AUDIO_set_PGA_DPGA_CFG_PGA2_mute(0);
+    return GD_OK;
+}
+

+ 347 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/crypto/gd_crypto.c

@@ -0,0 +1,347 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/crypto/crypto.c
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gh_crypto.h"
+#include "gd_int.h"
+#include "gd_timer.h"
+#include "gd_crypto.h"
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+#define ENCRPT  0
+#define DECRPT  1
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+typedef struct
+{
+    GD_CRYPTO_MODE_E    mode;
+    GBOOL               useint;
+    GD_HANDLE           inthandle;
+    void                (*notifyFct)();
+}GD_CRYPTO_DeviceT;
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+static GD_CRYPTO_DeviceT    desdevice;
+static GD_CRYPTO_DeviceT    aesdevice;
+static GD_HANDLE            deshandle = 0;
+static GD_HANDLE            aeshandle = 0;
+static volatile GBOOL       des_done __attribute__ ((section(".nocache_buffer")));
+static volatile GBOOL       aes_done __attribute__ ((section(".nocache_buffer")));
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+static GISR2 gd_aes_crypt_isr(void);
+static GISR2 gd_des_crypt_isr(void);
+static GERR gd_crypto_ProcessData(GD_HANDLE handle, U32 type, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out);
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+GERR GD_CRYPTO_Open(GD_CRYPTO_OpenParamsT* pOpenParams, GD_HANDLE* pHandle)
+{
+    U32 i,nkey;
+    GD_INT_OPEN_PARAMS_S OpenParams;
+    GD_CRYPTO_DeviceT* device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+    if((pOpenParams == NULL) || (pOpenParams->pkey == NULL))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if (pOpenParams->mode >= GD_CRYPTO_MODE_MAX)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    nkey = 2;
+    switch(pOpenParams->mode)
+    {
+    case GD_CRYPTO_DES:
+        if(deshandle)
+        {
+            return GD_ERR_ALREADY_OPEN;
+        }
+        nkey = 2;
+        for(i=0;i<nkey;i++)
+        {
+            GH_CRYPTO_set_DES_Key(i,(*pOpenParams->pkey).key[i]);
+        }
+        desdevice.mode      = pOpenParams->mode;
+        desdevice.useint    = pOpenParams->useint;
+        desdevice.notifyFct = pOpenParams->notifyFct;
+
+        *pHandle  = (GD_HANDLE)&desdevice;
+        deshandle = (GD_HANDLE)&aesdevice;
+        break;
+    case GD_CRYPTO_AES_128:
+        if(aeshandle)
+        {
+            return GD_ERR_ALREADY_OPEN;
+        }
+        nkey = 4;
+        for(i=0;i<nkey;i++)
+        {
+            GH_CRYPTO_set_AES_128_Key(i,(*pOpenParams->pkey).key[i]);
+        }
+        aesdevice.mode      = pOpenParams->mode;
+        aesdevice.useint    = pOpenParams->useint;
+        aesdevice.notifyFct = pOpenParams->notifyFct;
+
+        *pHandle  = (GD_HANDLE)&aesdevice;
+        aeshandle = (GD_HANDLE)&aesdevice;
+        break;
+    case GD_CRYPTO_AES_192:
+        if(aeshandle)
+        {
+            return GD_ERR_ALREADY_OPEN;
+        }
+        nkey = 6;
+        for(i=0;i<nkey;i++)
+        {
+            GH_CRYPTO_set_AES_192_Key(i,(*pOpenParams->pkey).key[i]);
+        }
+        aesdevice.mode      = pOpenParams->mode;
+        aesdevice.useint    = pOpenParams->useint;
+        aesdevice.notifyFct = pOpenParams->notifyFct;
+
+        *pHandle  = (GD_HANDLE)&aesdevice;
+        aeshandle = (GD_HANDLE)&aesdevice;
+        break;
+    case GD_CRYPTO_AES_256:
+        if(aeshandle)
+        {
+            return GD_ERR_ALREADY_OPEN;
+        }
+        nkey = 8;
+        for(i=0;i<nkey;i++)
+        {
+            GH_CRYPTO_set_AES_256_Key(i,(*pOpenParams->pkey).key[i]);
+        }
+        aesdevice.mode      = pOpenParams->mode;
+        aesdevice.useint    = pOpenParams->useint;
+        aesdevice.notifyFct = pOpenParams->notifyFct;
+
+        *pHandle  = (GD_HANDLE)&aesdevice;
+        aeshandle = (GD_HANDLE)&aesdevice;
+        break;
+    }
+
+    device = (GD_CRYPTO_DeviceT*)(*pHandle);
+    if(device->useint)
+    {
+        OpenParams.sensitivity  = GD_INT_RISING_EDGE;
+        OpenParams.priority     = GD_INT_MID_PRIORITY;
+        if(pOpenParams->mode == GD_CRYPTO_DES)
+        {
+            GH_CRYPTO_set_DES_Interrupt_En(1);
+#if defined(GK710X)            
+            OpenParams.type     = GD_INT_DES_OUTPUT_READY_IRQ;
+#else
+            OpenParams.type     = GD_INT_CRYPTO_OUTPUT_READY_IRQ;
+#endif            
+            OpenParams.isrFct.midPrio = gd_des_crypt_isr;
+        }
+        else
+        {
+            GH_CRYPTO_set_AES_Interrupt_En(1);
+#if defined(GK710X)            
+            OpenParams.type     = GD_INT_AES_OUTPUT_READY_IRQ;
+#else
+            OpenParams.type     = GD_INT_CRYPTO_OUTPUT_READY_IRQ;
+#endif               
+            OpenParams.isrFct.midPrio = gd_aes_crypt_isr;
+        }
+        GD_INT_Open(&OpenParams, &device->inthandle);
+        GD_INT_Enable(&device->inthandle, 1);
+    }
+    return GD_OK;
+}
+
+GERR GD_CRYPTO_Close(GD_HANDLE* pHandle)
+{
+    GD_CRYPTO_DeviceT* device = (GD_CRYPTO_DeviceT*)(*pHandle);
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    switch(device->mode)
+    {
+    case GD_CRYPTO_DES:
+        deshandle = 0;
+        break;
+    case GD_CRYPTO_AES_128:
+        aeshandle = 0;
+        break;
+    case GD_CRYPTO_AES_192:
+        aeshandle = 0;
+        break;
+    case GD_CRYPTO_AES_256:
+        aeshandle = 0;
+        break;
+    }
+    if(device->mode == GD_CRYPTO_DES)
+    {
+        GH_CRYPTO_set_DES_Interrupt_En(0);
+    }
+    else
+    {
+        GH_CRYPTO_set_AES_Interrupt_En(0);
+    }
+    if(device->useint && device->inthandle)
+    {
+        GD_INT_Enable(&device->inthandle, 0);
+        GD_INT_Close(&device->inthandle);
+    }
+    *pHandle = 0;
+    return GD_OK;
+}
+
+GERR GD_CRYPTO_EncrptData(GD_HANDLE handle, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out)
+{
+    return gd_crypto_ProcessData(handle, ENCRPT, data_in, data_out);
+}
+
+GERR GD_CRYPTO_DecrptData(GD_HANDLE handle, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out)
+{
+    return gd_crypto_ProcessData(handle, DECRPT, data_in, data_out);
+}
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+static GISR2 gd_des_crypt_isr(void)
+{
+    des_done = GTRUE;
+}
+
+static GISR2 gd_aes_crypt_isr(void)
+{
+    aes_done = GTRUE;
+}
+
+static GERR gd_crypto_ProcessData(GD_HANDLE handle, U32 type, GD_CRYPTO_DATA_T* data_in, GD_CRYPTO_DATA_T* data_out)
+{
+    GD_CRYPTO_DeviceT* device = (GD_CRYPTO_DeviceT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    if((data_in == NULL) || (data_out == NULL))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    switch(device->mode)
+    {
+    case GD_CRYPTO_DES:
+        des_done = GFALSE;
+        GH_CRYPTO_set_DES_Opcode(type);
+        GH_CRYPTO_set_DES_Input(0, data_in->des_data.data_hi);
+        GH_CRYPTO_set_DES_Input(1, data_in->des_data.data_lo);
+        if(device->useint)
+        {
+            do
+            {
+                GD_TIMER_Delay(2);
+            }while(!des_done);
+            data_out->des_data.data_hi = GH_CRYPTO_get_DES_Output(0);
+            data_out->des_data.data_lo = GH_CRYPTO_get_DES_Output(1);
+        }
+        else
+        {
+            while(!GH_CRYPTO_get_DES_Output_Rdy())
+            {
+                ;
+            }
+            data_out->des_data.data_hi = GH_CRYPTO_get_DES_Output(0);
+            data_out->des_data.data_lo = GH_CRYPTO_get_DES_Output(1);
+        }
+        break;
+    case GD_CRYPTO_AES_128:
+    case GD_CRYPTO_AES_192:
+    case GD_CRYPTO_AES_256:
+        aes_done = GFALSE;
+        GH_CRYPTO_set_AES_Opcode(type);
+        GH_CRYPTO_set_AES_Input(0, data_in->aes_data.data_127_96);
+        GH_CRYPTO_set_AES_Input(1, data_in->aes_data.data_95_64);
+        GH_CRYPTO_set_AES_Input(2, data_in->aes_data.data_63_32);
+        GH_CRYPTO_set_AES_Input(3, data_in->aes_data.data_31_0);
+        if(device->useint)
+        {
+            do
+            {
+                GD_TIMER_Delay(2);
+            }while(!aes_done);
+            data_out->aes_data.data_127_96 = GH_CRYPTO_get_AES_Output(0);
+            data_out->aes_data.data_95_64  = GH_CRYPTO_get_AES_Output(1);
+            data_out->aes_data.data_63_32  = GH_CRYPTO_get_AES_Output(2);
+            data_out->aes_data.data_31_0   = GH_CRYPTO_get_AES_Output(3);
+        }
+        else
+        {
+            while(!GH_CRYPTO_get_AES_Output_Rdy())
+            {
+                ;
+            }
+            data_out->aes_data.data_127_96 = GH_CRYPTO_get_AES_Output(0);
+            data_out->aes_data.data_95_64  = GH_CRYPTO_get_AES_Output(1);
+            data_out->aes_data.data_63_32  = GH_CRYPTO_get_AES_Output(2);
+            data_out->aes_data.data_31_0   = GH_CRYPTO_get_AES_Output(3);
+        }
+        break;
+    }
+    return GD_OK;
+}
+
+
+
+

+ 327 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/dma/gd_dma.c

@@ -0,0 +1,327 @@
+/******************************************************************************
+**
+** \file      gd_uart.c
+**
+** \brief     DEMO test application.
+**
+**            (C) Goke Microelectronics China 2002 - 2007
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version   \$Id: gd_uart.c,v 1.8 2007/01/04 15:13:22 mneuma Exp $
+**
+******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gd_int.h"
+#include "gd_dma.h"
+#include "gh_dma.h"
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+//#define DMA_DEBUG
+
+#ifdef DMA_DEBUG
+#define DMA_PRINTF(args...) printf(args)
+#else
+#define DMA_PRINTF(args...)
+#endif	
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+typedef struct
+{
+	GBOOL inUse;
+	U32 channel;
+	U32 mode;
+	U32 descNumber;
+	GD_DMA_DESCRIPTOR_S *pDescriptor;
+	GD_DMA_NOTIFIER_F    notifier;
+}DMA_DEVICE_S;
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+static GD_HANDLE dmaIntHandle = 0;
+static GD_DMA_DESCRIPTOR_S dmaDescriptor[DMA_CHAN_MAX_NUM][DMA_CHAN_MAX_DESC] __attribute__((aligned(DMA_BUFF_ADDR_ALIGN),section(".nocache_buffer")));
+static DMA_DEVICE_S  dmaDev[DMA_CHAN_MAX_NUM];
+static U8 initialised = 0;
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+static void dma_int_handler(void)
+{
+    U32 i = 0;
+	U32 intSource = 0;
+
+	intSource = GH_DMA_get_IR();
+    for (i=0; i<=DMA_CHAN_MAX_NUM; i++)
+    {
+        if((intSource&(1<<i)) && (dmaDev[i].notifier!=NULL))
+        {
+            dmaDev[i].notifier();
+			GH_DMA_set_Status(i,0);
+        }
+    }
+}
+
+static GERR dma_set_eoc(DMA_DEVICE_S *dev)
+{
+	U32 i = 0;
+	GD_DMA_DESCRIPTOR_S *pdescriptor = NULL;
+	
+	if(dev == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	pdescriptor = dev->pDescriptor;
+
+	for(i=0; i<dev->descNumber; i++,pdescriptor++)
+	{
+		pdescriptor->descAttr |= DMA_DESC_EOC;	
+	}
+
+	return GD_OK;
+}
+
+
+static GERR dma_clr_eoc(DMA_DEVICE_S *dev)
+{
+	U32 i = 0;
+	GD_DMA_DESCRIPTOR_S *pdescriptor = NULL;
+	
+	if(dev == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	pdescriptor = dev->pDescriptor;
+
+	for(i=0; i<dev->descNumber; i++,pdescriptor++)
+	{
+		pdescriptor->descAttr &= ~DMA_DESC_EOC;	
+	}
+
+	return GD_OK;
+}
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+GERR GD_DMA_Init(void)
+{
+	GERR err = GD_OK;
+    GD_INT_OPEN_PARAMS_S intParams;
+	
+    if(initialised)
+    {
+        return(GD_OK);
+    }
+
+	memset((void *)dmaDescriptor, 0, sizeof(GD_DMA_DESCRIPTOR_S)*DMA_CHAN_MAX_NUM*DMA_CHAN_MAX_DESC);
+	memset((void *)dmaDev, 0, sizeof(DMA_DEVICE_S)*DMA_CHAN_MAX_NUM);
+
+    intParams.type           = GD_INT_DMA_IRQ;
+    intParams.sensitivity    = GD_INT_LEVEL_HIGH;
+    intParams.active         = GD_INT_NO_INVERT_IRQ;
+    intParams.priority       = GD_INT_MID_PRIORITY;
+    intParams.isrFct.lowPrio = dma_int_handler;
+    err = GD_INT_Open(&intParams,&dmaIntHandle);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	GD_INT_Enable(&dmaIntHandle, GD_INT_ENABLED);
+	
+	initialised = 1;
+		
+	return GD_OK;
+
+}
+
+GERR GD_DMA_Exit(void)
+{
+    if(!initialised)
+    {
+        return(GD_ERR_NOT_INITIALIZED);
+    }
+	
+	GD_INT_Enable(&dmaIntHandle, GD_INT_DISABLED);
+	GD_INT_Close(&dmaIntHandle);
+
+	initialised = 0;
+
+	return GD_OK;
+}
+
+GERR GD_DMA_Open(GD_DMA_OPEN_PARAM_S *openParam, GD_HANDLE *handle)
+{
+	DMA_DEVICE_S *pDev = NULL;
+
+	if(openParam==NULL || handle==NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+	if(openParam->channel >= DMA_CHAN_MAX_NUM)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}	
+	
+	pDev = &dmaDev[openParam->channel];
+	if(pDev->inUse == GTRUE)
+	{
+		return GD_ERR_ALREADY_OPEN;
+	}
+
+	pDev->inUse       = GTRUE;
+	pDev->channel     = openParam->channel;
+	pDev->mode        = openParam->mode;
+	pDev->notifier    = openParam->intNotifier;
+	pDev->pDescriptor = dmaDescriptor[pDev->channel];
+	pDev->descNumber  = 0;
+
+	*handle = (GD_HANDLE)pDev;
+
+	return GD_OK;
+}
+
+GERR GD_DMA_Close(GD_HANDLE handle)
+{
+	DMA_DEVICE_S *pDev = (DMA_DEVICE_S *)handle;
+
+	memset((void *)pDev->pDescriptor, 0, sizeof(GD_DMA_DESCRIPTOR_S)*DMA_CHAN_MAX_DESC);
+	memset((void *)pDev, 0, sizeof(DMA_DEVICE_S));
+
+	return GD_OK;
+}
+
+GERR GD_DMA_AddDescriptor(GD_HANDLE handle, GD_DMA_DESCRIPTOR_S *descriptor)
+{
+	DMA_DEVICE_S *pDev = (DMA_DEVICE_S *)handle;
+	GD_DMA_DESCRIPTOR_S *pLastDescriptor = NULL;
+
+	if(pDev->inUse != GTRUE)
+	{
+		return GD_ERR_INVALID_HANDLE;
+	}
+	if(pDev->mode != DMA_MODE_DESCRIPTOR)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}	
+	if(pDev->descNumber >= DMA_CHAN_MAX_DESC)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}		
+
+	descriptor->next = pDev->pDescriptor;
+	if(pDev->descNumber > 0)
+	{
+		pLastDescriptor       = pDev->pDescriptor+pDev->descNumber-1;
+		pLastDescriptor->next = pDev->pDescriptor+pDev->descNumber;
+	}
+	memcpy((void *)(pDev->pDescriptor+pDev->descNumber), (void *)descriptor, sizeof(GD_DMA_DESCRIPTOR_S));
+	pDev->descNumber++;
+
+	return GD_OK;
+}
+
+
+GERR GD_DMA_Start(GD_HANDLE handle, U32 desc)
+{
+#ifdef DMA_DEBUG
+	U32 i = 0;
+	GD_DMA_DESCRIPTOR_S *pdescriptor = NULL;
+#endif
+	DMA_DEVICE_S *pDev = (DMA_DEVICE_S *)handle;
+
+	if(pDev->inUse != GTRUE)
+	{
+		return GD_ERR_INVALID_HANDLE;
+	}
+	
+	if(pDev->mode == DMA_MODE_NORMAL)
+	{
+		// TODO: DMA NORMAL MODE
+	}
+	else
+	{
+		if(desc >= pDev->descNumber)
+		{
+			return GD_ERR_FEATURE_NOT_SUPPORTED;
+		}	
+
+		dma_clr_eoc(pDev);
+		
+#ifdef DMA_DEBUG
+		pdescriptor = pDev->pDescriptor;
+		for(i=0; i<pDev->descNumber; i++,pdescriptor++)
+		{
+			DMA_PRINTF("[GD_DMA]DMA ch%d descriptor %d: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+				pDev->channel, i+1,
+				pdescriptor->srcAddr, pdescriptor->dstAddr, (U32)pdescriptor->next, 
+				pdescriptor->reportAddr, pdescriptor->dataLength, pdescriptor->descAttr);
+		}
+#endif		
+		GH_DMA_set_Status(pDev->channel, 0);
+		GH_DMA_set_Descriptor_Address(pDev->channel, (U32)(pDev->pDescriptor+desc));
+		GH_DMA_set_Control(pDev->channel, DMA_CHAN_CTRL_EN|DMA_CHAN_CTRL_D);
+	}
+
+    return GD_OK;
+}
+
+
+GERR GD_DMA_Stop(GD_HANDLE handle)
+{
+	DMA_DEVICE_S *pDev = (DMA_DEVICE_S *)handle;
+
+	if(pDev->inUse != GTRUE)
+	{
+		return GD_ERR_INVALID_HANDLE;
+	}
+	
+	if(pDev->mode == DMA_MODE_NORMAL)
+	{
+		// TODO: DMA NORMAL MODE
+	}
+	else
+	{
+		dma_set_eoc(pDev);
+	}
+
+    return GD_OK;
+}
+
+

+ 1140 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_emac.c

@@ -0,0 +1,1140 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_emac.c
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gh_eth.h"
+#include "gd_int.h"
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_timer.h"
+
+//#define DEBUG_PRINT
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+#define EMAC_CR    0x0    //  60-100MHz      84clk, 1.68us
+//#define EMAC_CR    0x1    // 100-150MHz     124clk, 2.48us
+//#define EMAC_CR    0x2    //  20- 35MHz      32clk, 0.6401us
+//#define EMAC_CR    0x3    //  35~ 60MHz
+//#define EMAC_CR    0x4    //  150-250 MHz
+//#define EMAC_CR    0x5    //  250-300 MHz
+//MDC read:
+//000        60-100 MHz clk_csr_i/42    clk_csr_i=25MHz
+//001        100-150 MHz clk_csr_i/62
+//010        20-35 MHz clk_csr_i/16
+//011        35-60 MHz clk_csr_i/26
+//100        150-250 MHz clk_csr_i/102
+//101        250-300 MHz clk_csr_i/122
+//110,111  Reserved
+
+
+/* Error count MAX value */
+#define GD_ETH_LC_MAX             (50)
+#define GD_ETH_TJT_MAX            (50)
+#define GD_ETH_RWT_MAX            (50)
+#define GD_ETH_UNF_MAX            (50)
+#define GD_ETH_OVF_MAX            (50)
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+void ethStopDevice(GD_HANDLE handle, GD_ETH_RWE rw);
+void ETH_MAC_RxDataProcess(GD_HANDLE handle);
+void ethDelay(void);
+
+#if USE_FLOWCTL
+void ethSendPause(void);
+#endif
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+/*!
+*****************************************************************************
+** \brief Interrupt service routine of the Ethernet driver.
+**
+** This function calls user callback function, which is registered by
+** GD_ETH_Open, when receiving Ethernet frames.
+**
+** \note This function implements GD_SYS_DriverT::isrFunc.
+**
+** \return 0, as no further background processing is used.
+**
+** \sa GD_ETH_Open()
+*****************************************************************************
+*/
+/*lint -e(961, 537, 451) */
+GISR1 GD_ETH_Isr(void)
+{
+    U32 sr;
+
+    GD_HANDLE handle = gd_eth_get_handle();
+
+    // read & clear interrupt status
+    sr = GH_ETH_get_SR();
+    GH_ETH_set_SR(sr);
+
+#ifdef DEBUG_PRINT
+    GM_Printf("sr = 0x%08x\n", sr);
+    //GM_Printf("cursr = 0x%08x\n", GH_ETH_get_SR());
+#endif
+
+    //GH_ARC_set_IRQClear(0x200);
+    //GH_ARC_set_IRQClear(GD_INT_ETH_IRQ);
+
+    // Fatal Bus Error
+    if ( (sr & ETH_REG_SR_FBE) == ETH_REG_SR_FBE )
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_FBE! SR = 0x%08x\n",sr);
+#endif
+        ethFBEInt( handle, sr );
+    }
+
+    if((sr & (ETH_REG_SR_OVF)) == ETH_REG_SR_OVF)
+    {
+        //This bit indicates overflow
+#ifdef DEBUG_PRINT
+        GM_Printf("The rx descriptor is overflow! SR = 0x%08x\n",sr);
+#endif
+    }
+
+    if((sr & (ETH_REG_SR_ERI)) == ETH_REG_SR_ERI)
+    {   //This bit indicates that the MDC had filled the first data buffer of the packe.
+        //SR(bit6)RI automatically clears this bit
+        //U8 i = 0;
+
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_ERI! SR = 0x%08x\n",sr);
+#endif
+    }
+
+    //This bit indicates that the next descriptor in the receive list is owned by the host.
+    if ( (sr & ETH_REG_SR_RU) == ETH_REG_SR_RU)
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_RU! SR = 0x%08x\n",sr);
+#endif
+        ethRUInt( handle );
+        GH_ETH_set_RPDR(1);
+    }
+
+    if ( (sr & ETH_REG_SR_RI) == ETH_REG_SR_RI )//frame receive finish
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_RI! SR = 0x%08x\n",sr);
+#endif
+        ETH_MAC_RxDataProcess(handle);
+    }
+
+    // Transfer Descriptor Update , point to next descriptor
+    if ((sr & (ETH_REG_SR_ETI | ETH_REG_SR_UNF | ETH_REG_SR_TPS | ETH_REG_SR_TU | ETH_REG_SR_TI | ETH_REG_SR_TJT)) != 0 )
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH TX! SR = 0x%08x\n",sr);
+#endif
+        ethHandleIntTx( handle);
+    }
+
+    if((sr & (ETH_REG_SR_RPS)) == ETH_REG_SR_RPS)
+    {   //This bit asserted when Receive Process enters the stopped state.
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_RPS! SR = 0x%08x\n",sr);
+#endif
+    }
+
+    if((sr & (ETH_REG_SR_RWT)) == ETH_REG_SR_RWT)
+    {   //This bit is assert when a frame with a length greater than 2048 bytes is received
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_RWT! SR = 0x%08x\n",sr);
+#endif
+    }
+
+    if ((sr & ETH_REG_SR_TU) == ETH_REG_SR_TU)
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("ETH_REG_SR_TU! SR = 0x%08x\n",sr);
+#endif
+        ethTUInt( handle );
+    }
+}
+
+GBOOL GD_ETH_CheckPhyBusy(void)
+{
+    U32 i=0, value;
+    while ( i < 2000 )//how to ensure the numbers of the cycle??
+    {
+        value = GH_ETH_get_GAR();
+        if((value & 0x1) == 0) //if MII not busy
+            return GFALSE;
+        i++;
+    }
+    return GTRUE;//busy
+}
+
+GBOOL GD_ETH_ReadPhy(U8 phyAddr, U8 phyReg, U32* phyRegValue)
+{
+    GBOOL   retval;
+
+    /* parameter checkout */
+    if( (phyAddr > GD_ETH_PHY_EXTERNAL_AUTO)
+       ||(phyReg >= GD_ETH_PHY_MAX_REG_NUM)
+       ||(phyRegValue == NULL))
+    {
+        return GFALSE;
+    }
+
+    /* check if the PHY is busy? Busy:True, Idle:False */
+    retval = GD_ETH_CheckPhyBusy();
+    if(retval != GFALSE)
+        return GFALSE;
+
+    /* set GDR: */
+    //busy and read ,CR=0(MDC:1.42-2.38MHz)
+    GH_ETH_set_GAR((phyAddr << ETH_REG_GAR_SHIFT_PA)
+                   |(phyReg << ETH_REG_GAR_SHIFT_GR)
+                   | ETH_REG_GAR_GB
+                   | (EMAC_CR << ETH_REG_GAR_SHIFT_CR));
+
+    /* check if the PHY is busy? Busy:True, Idle:False */
+    retval = GD_ETH_CheckPhyBusy();
+    if ( retval != GFALSE )
+        return GFALSE;
+
+    /* read data: */
+    *phyRegValue = (U32)GH_ETH_get_GDR_GD();
+
+    return GTRUE;
+
+}
+
+//MDC write:
+GBOOL GD_ETH_WritePhy(U8 phyAddr, U8 phyReg, U32 phyRegVal)
+{
+    U32  i;
+    GBOOL retval;
+
+    /* parameter checkout */
+    if((phyAddr > GD_ETH_PHY_EXTERNAL_AUTO)||(phyReg >= GD_ETH_PHY_MAX_REG_NUM))// out of range:5 bit
+        return GFALSE;
+
+    /* check if the PHY is busy? Busy:True, Idle:False */
+    retval = GD_ETH_CheckPhyBusy();
+    if ( retval != GFALSE )
+        return GFALSE;
+
+    /* set GDR: */
+    i=(GH_ETH_get_GDR()& 0xffff0000);
+    GH_ETH_set_GDR(i + (phyRegVal & 0xffff));
+
+    /* check if the PHY is busy? Busy:True, Idle:False */
+    retval = GD_ETH_CheckPhyBusy();
+    if ( retval != GFALSE )
+        return GFALSE;
+
+    /* set DAR: */
+    //busy and write ,CR=0(MDC:1.42-2.38MHz)
+    GH_ETH_set_GAR((phyAddr << ETH_REG_GAR_SHIFT_PA)
+                   |(phyReg << ETH_REG_GAR_SHIFT_GR )
+                   | ETH_REG_GAR_GW
+                   | ETH_REG_GAR_GB
+                   | (EMAC_CR << ETH_REG_GAR_SHIFT_CR));//status is busy, next action will be write
+
+    return GTRUE;
+
+}
+
+GERR GD_ETH_PHY_HWReset(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device && device->phyreset)
+    {
+        GD_GPIO_Write(device->phyreset, 1);
+        ethDelay(); //100ms delay
+        GD_GPIO_Write(device->phyreset, 0);
+        //gd_eth_TimerDelay(50);//100ms
+        ethDelay(); //100ms delay
+        GD_GPIO_Write(device->phyreset, 1);
+        //ethDelay(); //100ms delay
+    }
+    return GD_OK;
+}
+
+void GD_ETH_StartDevice(GD_HANDLE handle, GD_ETH_RWE IsRx)
+{
+    U32 omr;
+    U32 old_omr;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)   return;
+
+    /* Get the information of OMR(MDC Operation Mode Register) */
+    omr = GH_ETH_get_OMR();
+#ifdef DEBUG_PRINT
+    GM_Printf("oldOMR = 0x%08x\n",omr);
+#endif
+    old_omr = omr;
+    if ( IsRx & GD_ETH_R)
+    {
+        if((device->StopFlag & GD_ETH_RX_STOP)||
+           (device->StopFlag & GD_ETH_RX_STOP_HWERR))
+        {
+            device->StopFlag &= ~GD_ETH_RX_STOP;
+            device->StopFlag &= ~GD_ETH_RX_STOP_HWERR;
+            device->StopFlag |= GD_ETH_RX_RUN;
+            omr |= ETH_REG_OMR_SR;
+        }
+        else if((device->StopFlag & GD_ETH_RX_SUSP_NOBUF)||
+                (device->StopFlag & GD_ETH_RX_SUSP_HWERR))
+        {
+            device->StopFlag &= ~GD_ETH_RX_SUSP_NOBUF;
+            device->StopFlag &= ~GD_ETH_RX_SUSP_HWERR;
+            device->StopFlag |= GD_ETH_RX_RUN;
+
+            GH_ETH_set_RPDR(1);//set any value, then F_MAC3H will check receive descriptor
+        }
+    }
+
+    if(IsRx & GD_ETH_W)
+    {
+        if((device->StopFlag & GD_ETH_TX_STOP)||
+           (device->StopFlag & GD_ETH_TX_STOP_HWERR))
+        {
+            device->StopFlag &= ~GD_ETH_TX_STOP;
+            device->StopFlag &= ~GD_ETH_TX_STOP_HWERR;
+            device->StopFlag |= GD_ETH_TX_RUN;
+
+            omr |= ETH_REG_OMR_ST;
+        }
+        else if((device->StopFlag & GD_ETH_TX_SUSP_NODAT)||
+                (device->StopFlag & GD_ETH_TX_SUSP_HWERR))
+        {
+            device->StopFlag &= ~GD_ETH_TX_SUSP_NODAT;
+            device->StopFlag &= ~GD_ETH_TX_SUSP_HWERR;
+            device->StopFlag |= GD_ETH_TX_RUN;
+
+            GH_ETH_set_TPDR(1);//set any value, then F_MAC3H will check for frame to be transmit.s
+        }
+    }
+
+#ifdef DEBUG_PRINT
+    GM_Printf("newOMR = 0x%08x\n",omr);
+#endif
+
+    if ( omr != old_omr )
+    {
+        /* Update the OMR */
+        GH_ETH_set_OMR(omr);
+    }
+}
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+
+/*
+*****************************************************************************
+** \brief software bug assert
+**
+** This function asserts a software bug to stop receive/transmit process later
+** and also generates some messages.
+**
+** \param func    Pointer to a name of function
+** \param message Pointer to a message
+**
+*****************************************************************************
+*/
+/*lint -e{715} */
+void gmcSWError(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+    device->error.RWTErrorCnt++;
+    if(device->error.RWTErrorCnt>GD_ETH_RWT_MAX)
+    {
+        device->StopFlag |= GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        device->StopFlag |= GD_ETH_RX_RUN;
+    }
+}
+
+/*
+*****************************************************************************
+** \brief LC error handler
+**
+** This function handles LC(Loss of Carrier) error.
+**
+** \param rw      Read/write direction
+**
+*****************************************************************************
+*/
+void ethLCErr(GD_HANDLE handle, GBOOL IsRx)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+
+    device->error.lcCnt++;
+    if(device->error.lcCnt>GD_ETH_LC_MAX)
+    {
+        device->StopFlag |=GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        if(IsRx)
+        {
+            device->StopFlag |=GD_ETH_RX_RUN;
+        }
+        else
+        {
+            device->StopFlag |=GD_ETH_TX_RUN;
+        }
+    }
+}
+/*
+*****************************************************************************
+** \brief RU error handler
+**
+** This function handles RU(Receive Buffer Unavailable) error.
+**
+*****************************************************************************
+*/
+void ethRUInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return;
+    }
+
+#if USE_FLOWCTL
+    ethSendPause();
+#endif
+
+    device->error.RUErrorCnt++;
+    //device->StopFlag |= GD_ETH_RX_SUSP_NOBUF;
+    //device->StopFlag &= (~GD_ETH_RX_RUN);
+
+    /*stop the receiving*/
+    ethStopDevice(handle,GD_ETH_R);
+
+    /*disable ru interrupt*/
+    GH_ETH_set_IER_RU(0);
+
+    /*process received packets*/
+    ETH_MAC_RxDataProcess(handle);
+
+    /*reset the receicve descriptors*/
+    //ETH_MAC_InitRxTxBufDesc(GFALSE, GTRUE);
+
+    GH_ETH_set_RDLAR((U32)(device->RxDesStartAddr));
+    device->CurRxDesSite = 0;
+
+    /*enable RU interrupt*/
+    GH_ETH_set_IER_RU(1);
+
+    /*restart the receiving*/
+    GD_ETH_StartDevice(handle, GD_ETH_R);//make it in rx state
+
+}
+
+/*
+*****************************************************************************
+** \brief OVF error handler
+**
+** This function handles OVF(Receive Overflow) error.
+**
+*****************************************************************************
+*/
+void ethOVFInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+    device->error.OvfErrorCnt++;
+    if(device->error.OvfErrorCnt>GD_ETH_OVF_MAX)
+    {
+        device->StopFlag |=GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        device->StopFlag |=GD_ETH_RX_RUN;
+    }
+}
+
+/*
+*****************************************************************************
+** \brief RWT error handler
+**
+** This function handles RWT(Receive Watchdog Timeout) error.
+**
+** \param    Fmac3h device Id
+**
+*****************************************************************************
+*/
+void ethRWTInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+    {
+        return;
+    }
+    device->error.RWTErrorCnt++;
+    if(device->error.RWTErrorCnt>GD_ETH_RWT_MAX)
+    {
+        device->StopFlag |= GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        device->StopFlag |= GD_ETH_RX_RUN;
+    }
+}
+
+/*
+*****************************************************************************
+** \brief TU error handler
+**
+** This function handles TU(Transmit Buffer Unavailable) error.
+**
+*****************************************************************************
+*/
+void ethTUInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+        return;
+    device->error.TUErrorCnt++;
+    device->StopFlag |= GD_ETH_TX_SUSP_NODAT;
+    //device->StopFlag &= (~GD_ETH_TX_RUN);
+}
+
+/*
+*****************************************************************************
+** \brief UNF error handler
+**
+** This function handles UNF(Transmit Underflow) error.
+**
+*****************************************************************************
+*/
+void ethUNFInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+    device->error.UnfErrorCnt++;
+
+    if(device->error.UnfErrorCnt>GD_ETH_UNF_MAX)
+    {
+        device->StopFlag |=GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        device->StopFlag |=GD_ETH_TX_SUSP_HWERR;
+        GD_ETH_StartDevice(handle, GD_ETH_W );
+    }
+}
+
+/*
+*****************************************************************************
+** \brief TJT error handler
+**
+** This function handles TJT(Transmit Jabber Timeout) error.
+**
+*****************************************************************************
+*/
+void ethTJTInt(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+    device->error.TjtErrorCnt++;
+    if(device->error.TjtErrorCnt>GD_ETH_TJT_MAX)
+    {
+        device->StopFlag |=GD_ETH_FATAL_ERROR;
+        ethStopDevice(handle, GD_ETH_RW );
+        device->StopFlag = GD_ETH_FATAL_ERROR;
+    }
+    else
+    {
+        device->StopFlag |=GD_ETH_TX_STOP_HWERR;
+        GD_ETH_StartDevice(handle, GD_ETH_W );
+    }
+}
+
+/*
+*****************************************************************************
+** \brief FBE error handler
+**
+** This function handles FBE(Fatal Bus Error) error.
+**
+** \param sr      SR register value
+**
+*****************************************************************************
+*/
+void ethFBEInt(GD_HANDLE handle, U32 sr)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+
+    device->StopFlag |=GD_ETH_FATAL_ERROR;
+    if((sr & ETH_REG_SR_EB) == ETH_REG_SR_TXEB)//host abort received in transmition
+    {
+        device->error.FbeTxErrorCnt++;
+    }
+    else
+    {
+        device->error.FbeRxErrorCnt++;
+    }
+    ethStopDevice(handle, GD_ETH_RW);
+    device->StopFlag = GD_ETH_FATAL_ERROR;
+}
+
+/*
+*****************************************************************************
+** \brief handler for receive interrupt
+**
+** This function handles receive interrupt(RI). It searches for completed descriptors
+** by checking descriptor status (Own bit) and make descPtrRx updated.
+**
+** \return
+**        -#GTRUE    Readable data was detected
+**        -#GFALSE   Readable data was not detected
+*****************************************************************************
+*/
+void ethHandleIntRx(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    GD_ETH_MAC_DesT* p;
+    GBOOL bHandling = GTRUE;
+    /*   Before        Descriptors         After interrupt
+     *                +---------------+
+     *                |1              |
+     *                |---------------|
+     *                |1              |
+     *  descPtrRead-->|---------------|
+     *                |0              |
+     *                |---------------|
+     *                |0              |
+     *  descPtrRx  -->|---------------|
+     *                |1=>0           |    Own bit is 1 => 0, and
+     *                |---------------|<---new descPtrRx should be here.
+     *                |1              |
+     *                +---------------+
+     */
+
+    if(device==NULL)
+        return;
+
+    while (bHandling)
+    {
+        p=(GD_ETH_MAC_DesT*)((device->RxDesStartAddr)+device->CurRxDesSite*sizeof(GD_ETH_MAC_DesT));
+        if((p->des0 & 0x80000000) == 0x80000000)
+            break;
+        if(device->CurRxDesSite==device->RxbufferNum-1)
+           device->CurRxDesSite=0;
+        else
+           device->CurRxDesSite++;
+        if ( device->CurRxDesSite == device->CurReadDesSite)
+            break;
+    }
+}
+
+/*
+*****************************************************************************
+** \brief handler for transfer interrupt
+**
+** This function handles transfer interrupt(TI). It searches for completed
+** descriptors by checking descriptor status(Own bit), and make descPtrTx updated.
+** It also reclaims used transmit buffers.
+**
+*****************************************************************************
+*/
+void ethHandleIntTx(GD_HANDLE handle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    GD_ETH_MAC_DesT* p;
+    GBOOL bHandling = GTRUE;
+
+    /*   Before        Descriptors         After interrupt
+     *                +---------------+
+     *                |1              |
+     *                |---------------|
+     *                |1              |
+     * descPtrTx   -->|---------------|
+     *                |1=>0           |    Own bit is 1 => 0, and
+     *                |---------------|<---new descPtrTx should be here.
+     *                |0              |
+     *                |---------------|
+     *                |0              |
+     * descPtrWrite-->|---------------|
+     *                |1              |
+     *                +---------------+
+     */
+
+    if(device==NULL)
+        return;
+
+    if(device->CurTxDesSite == device->CurWriteDesSite)
+    {
+        return;
+    }
+
+    while(bHandling)
+    {
+        //GM_Printf("+");
+        p=(GD_ETH_MAC_DesT*)((device->TxDesStartAddr)+device->CurTxDesSite*sizeof(GD_ETH_MAC_DesT));
+
+#ifdef DEBUG_PRINT
+        GM_Printf("Des0 = 0x%08x\n",p->des0);
+        GM_Printf("Des1 = 0x%08x\n",p->des1);
+        GM_Printf("Des2 = 0x%08x\n",p->des2);
+        GM_Printf("Des3 = 0x%08x\n",p->des3);
+#endif
+
+        if( (p->des0 & 0x80000000) == 0x80000000)
+        {
+            break;
+        }
+        if(p->des0 & ETH_DES_T0_ES)//happen any error
+        {
+            if(p->des0 & ETH_DES_T0_JT)
+                ethTJTInt(handle);
+            if(p->des0 & ETH_DES_T0_UF)
+                ethUNFInt(handle);
+            if(p->des0 & ETH_DES_T0_LCO)
+                ethLCErr(handle, GFALSE);
+            if((p->des0 & ETH_DES_T0_EC )||(p->des0 & ETH_DES_T0_ED))
+            {
+                ;
+            }
+            if((p->des1 & ETH_DES_T1_LS)==0)
+            {
+                break;
+            }
+        }
+        if(device->CurTxDesSite==device->TxbufferNum-1)
+        {
+            device->CurTxDesSite=0;
+        }
+        else
+        {
+            device->CurTxDesSite++;
+        }
+        if ( device->CurTxDesSite == device->CurWriteDesSite)
+        {
+            break;
+        }
+    }
+}
+
+GBOOL ethGetRxDescriptorDataSize(volatile GD_ETH_MAC_DesT* p, U16* datalen)
+{
+    if((p == NULL)||(datalen == NULL))
+        return GFALSE;
+
+    if(p->des0 & ETH_DES_R0_LS)//last buffers of the frame
+        *datalen=(p->des0 & ETH_DES_R0_FL) >> 16;//frame lenth
+    else
+        *datalen=(p->des1 & ETH_DES_R1_RBS1);
+
+    return GTRUE;
+}
+
+void ETH_MAC_RxDataProcess(GD_HANDLE handle)
+{
+    GD_ETH_MAC_DesT* p_RxDesTmp;
+    volatile GD_ETH_MAC_DesT* p;
+    volatile GD_ETH_MAC_DesT* p_FrameStart;
+    GBOOL  b_FrameStart=GFALSE; 
+    volatile U8* revbuf;
+    volatile U8* p_RxCopyBuf;    
+    volatile U8* p_RxSrcBuf;    
+    U16 m_RxDesLoopBackNum=0;
+    U16 n_RxFrameLen=0;
+    //U8* des;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    U16 len,i;
+    len = 0;
+
+    p = (volatile GD_ETH_MAC_DesT*)((device->RxDesStartAddr) + device->CurRxDesSite * sizeof(GD_ETH_MAC_DesT));
+    while((p->des0 & ETH_DES_R0_OWN) != ETH_DES_R0_OWN)
+    {
+#ifdef DEBUG_PRINT
+        GM_Printf("@\n");
+#endif
+
+        if((p->des0 & (ETH_DES_R0_ES|ETH_DES_R0_LE|ETH_DES_R0_OE|ETH_DES_R0_GF|  \
+            ETH_DES_R0_LC|ETH_DES_R0_RWT|ETH_DES_R0_RE|ETH_DES_R0_DL|ETH_DES_R0_CE)) != 0)
+        {
+#ifdef DEBUG_PRINT
+            GM_Printf("RxDES0=0x%x\n",p->des0);
+#endif
+        }
+        //else
+        if((p->des0 & ETH_DES_R0_FT) != ETH_DES_R0_FT)
+        {
+#ifdef DEBUG_PRINT
+            GM_Printf("other type frame\n",p->des0);
+#endif
+        }
+        //else
+        if((p->des0 & ETH_DES_R0_VLAN) == ETH_DES_R0_VLAN)
+        {
+#ifdef DEBUG_PRINT
+            GM_Printf("Vlan frame\n",p->des0);
+#endif
+        }
+        //else
+
+        if(((p->des0) & ETH_DES_R0_FS) == ETH_DES_R0_FS)
+        {
+            revbuf=(volatile U8*)(p->des2);//buffer is adjacent. Be careful the last buffrer->the first buffer
+            p_FrameStart=p;
+            b_FrameStart=GTRUE;
+            m_RxDesLoopBackNum=0;
+            n_RxFrameLen=0;
+            
+            p_RxDesTmp=( GD_ETH_MAC_DesT*)((device->RxDesStartAddr) + (device->RxbufferNum-1) * sizeof(GD_ETH_MAC_DesT));
+            p_RxCopyBuf=(volatile U8 *)(p_RxDesTmp->des2+device->SizePerRxBuffer);
+
+        }
+        else if(b_FrameStart==GTRUE)//not only one buffer
+        {  
+            if(p==(volatile GD_ETH_MAC_DesT*)device->RxDesStartAddr)//(device->CurRxDesSite == 0)//loopback
+            {
+                m_RxDesLoopBackNum++;
+            }
+            else if(m_RxDesLoopBackNum != 0)
+            {
+                m_RxDesLoopBackNum++;
+            }
+        }
+
+        if(((p->des0) & ETH_DES_R0_LS) == ETH_DES_R0_LS)
+        {
+            if(ethGetRxDescriptorDataSize(p,&len) == GFALSE)
+            {
+#ifdef DEBUG_PRINT
+                GM_Printf("Get Rx data size fail, please check\n!");
+#endif
+                continue;
+            }
+#if !STRIP_CRC
+            len -= 4;                       //strip the crc field
+#endif
+
+            if(m_RxDesLoopBackNum!=0)//copy buffer
+            {
+#ifdef DEBUG_PRINT
+                GM_Printf("memcpy:SRC_ADDR=0x%08x\tDST_ADDR=0x%08x\tLEN=%d\n!",p_RxCopyBuf,p->des2,len-n_RxFrameLen);
+#endif            
+                p_RxSrcBuf=(U8 *)(p->des2);
+                for(i=0;i<len-n_RxFrameLen;i++)
+                {
+                    *p_RxCopyBuf++=*p_RxSrcBuf++;
+                }
+
+/*                memcpy((void *)p_RxCopyBuf,(const void *)p_RxSrcBuf,len-n_RxFrameLen);               
+                p_RxCopyBuf=p_RxCopyBuf+(len-n_RxFrameLen);    */ 
+
+            }
+
+            //for(j=0;j<len;j++)
+            //des[j]=revbuf[j];
+            if(device->eth_rcve)
+            {
+                device->eth_rcve(revbuf,len);
+            }
+           
+            while(p_FrameStart!=p) //Host release all the Rx descriptors to FMAC3
+            {
+
+                p_FrameStart->des1 = ((p_FrameStart->des1) & ETH_DES_R1_RER) | device->SizePerRxBuffer;//device->SizePerRxBuffer <2048
+                p_FrameStart->des2 = (U32)device->Rxbufferstart + device->CurRxDesSite * device->SizePerRxBuffer;
+                p_FrameStart->des3 = 0x0;
+                p_FrameStart->des0 = ETH_DES_R0_OWN;//owned by mac
+				
+                device->CurRxDesSite++;
+                p_FrameStart++;
+                if(device->CurRxDesSite == device->RxbufferNum)
+                {
+                    device->CurRxDesSite = 0;
+                    p_FrameStart =(GD_ETH_MAC_DesT*) (device->RxDesStartAddr);
+                }
+                
+            }
+
+
+            p->des1 = ((p->des1) & ETH_DES_R1_RER) | device->SizePerRxBuffer;//device->SizePerRxBuffer <2048
+            p->des2 = (U32)device->Rxbufferstart + device->CurRxDesSite * device->SizePerRxBuffer;
+            p->des3 = 0x0;
+            p->des0 = ETH_DES_R0_OWN;//owned by mac
+			            
+            device->CurRxDesSite++;
+            if(device->CurRxDesSite == device->RxbufferNum)
+            {
+                device->CurRxDesSite = 0;
+            }
+            
+            p = (volatile GD_ETH_MAC_DesT*)((device->RxDesStartAddr) + device->CurRxDesSite * sizeof(GD_ETH_MAC_DesT));
+            
+            b_FrameStart=GFALSE;
+            m_RxDesLoopBackNum=0;
+            n_RxFrameLen=0;          
+        }
+        else if(b_FrameStart==GTRUE)//not last buffer, the frame has two buffer at least
+        {
+            ethGetRxDescriptorDataSize(p,&len);//len==device->SizePerRxBuffer ,except for last buffer               
+            n_RxFrameLen=n_RxFrameLen+len;
+            if(m_RxDesLoopBackNum!=0)//copy buffer
+            {
+#ifdef DEBUG_PRINT
+                GM_Printf("memcpy:SRC_ADDR=0x%08x\tDST_ADDR=0x%08x\tLEN=%d\n!",p_RxCopyBuf,p->des2,len);
+#endif
+                p_RxSrcBuf=(U8 *)(p->des2);
+                for(i=0;i<len;i++)
+                {
+                    *p_RxCopyBuf++=*p_RxSrcBuf++;
+                }
+ 
+/*                memcpy((void *)p_RxCopyBuf,(const void *)p_RxSrcBuf,len);               
+                p_RxCopyBuf=p_RxCopyBuf+len; */               
+            }     
+
+            if(p==p_RxDesTmp)
+            {
+                p=(volatile GD_ETH_MAC_DesT*)device->RxDesStartAddr;
+            }
+            else
+            {
+                p++;
+            }
+            //continue;    
+        }
+        else//error
+        {
+            //Host release the Rx descriptor to FMAC3
+            p->des1 = ((p->des1) & ETH_DES_R1_RER) | device->SizePerRxBuffer;//device->SizePerRxBuffer <2048
+            p->des2 = (U32)device->Rxbufferstart + device->CurRxDesSite * device->SizePerRxBuffer;
+            p->des3 = 0x0;
+            p->des0 = ETH_DES_R0_OWN;//owned by mac
+
+
+            device->CurRxDesSite++;
+            if(device->CurRxDesSite == device->RxbufferNum)
+            {
+                device->CurRxDesSite = 0;
+            }
+            p = (volatile GD_ETH_MAC_DesT*)((device->RxDesStartAddr) + device->CurRxDesSite * sizeof(GD_ETH_MAC_DesT));
+            
+            b_FrameStart=GFALSE;
+            m_RxDesLoopBackNum=0;
+            n_RxFrameLen=0;    
+        }
+    }
+}
+
+void ethStopDevice(GD_HANDLE handle, GD_ETH_RWE rw)
+{
+    U32 omr; //    = ETH_REG_OMR;
+    U32 old_omr;// = omr;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return;
+    omr=GH_ETH_get_OMR();
+    old_omr = omr;
+
+    if((rw == GD_ETH_R)||(rw == GD_ETH_RW))
+    {
+        omr &= ~(ETH_REG_OMR_SR);//end receive
+        device->StopFlag &= ~GD_ETH_RX_RUN;
+        device->StopFlag &= ~GD_ETH_RX_SUSP_NOBUF;
+        device->StopFlag &= ~GD_ETH_RX_SUSP_HWERR;
+        device->StopFlag &= ~GD_ETH_RX_STOP_HWERR;
+
+        device->StopFlag |= GD_ETH_RX_STOP;
+    }
+
+    if((rw == GD_ETH_W)||(rw == GD_ETH_RW))
+    {
+        omr &= ~(ETH_REG_OMR_ST);//end send
+        device->StopFlag &= ~GD_ETH_TX_RUN;
+        device->StopFlag &= ~GD_ETH_TX_SUSP_NODAT;
+        device->StopFlag &= ~GD_ETH_TX_SUSP_HWERR;
+        device->StopFlag &= ~GD_ETH_TX_STOP_HWERR;
+
+        device->StopFlag |= GD_ETH_TX_STOP;
+    }
+
+    if ( omr != old_omr )
+        GH_ETH_set_OMR(omr);
+
+}
+
+#if USE_FLOWCTL
+void ethSendPause(void)
+{
+    U32 fcr;
+    U32 timeout;
+
+    for ( timeout = 0; timeout < 0x100; timeout++ )
+    {
+        //fcr = ETH_REG_FCR;
+        fcr=GH_ETH_get_FCR();
+        if ( (fcr & ETH_REG_FCR_FCB) == 0x0 )
+            break;
+    }
+    if ( timeout >= 0x100 )
+    {
+        return;
+    }
+    fcr &= ~ETH_REG_FCR_PT;
+    fcr |=  (0x1d0 << 16);//pause time
+    fcr |= ETH_REG_FCR_FCB;
+    //ETH_REG_FCR = fcr;
+    GH_ETH_set_FCR(fcr);
+}
+#endif
+
+/*
+*****************************************************************************
+** \brief calculate MCR value
+**
+** This function calculates and returns a value for
+** initializing MCR (MAC Configuration Register).
+**
+** \param devId   Fmac3h device Id
+**
+** \return
+**      MCR value
+*****************************************************************************
+*/
+U32 ethSetupMCR(GD_HANDLE handle)
+{
+    U32 mcr = (U32)0;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device==NULL)
+        return 0;
+
+    if ( device->supJumbo == GTRUE)
+    {
+        mcr |= ETH_REG_MCR_WD;//disable watch dog
+        mcr |= ETH_REG_MCR_JD;//disable jabber
+        mcr |= ETH_REG_MCR_JE;//enable jumbo frame
+    }
+    if ( device->workmode.mode == GD_ETH_PHY_IF_MODE_GMII)
+    {
+        mcr &= ~ETH_REG_MCR_PS;
+    }
+    else
+    {
+        mcr |= ETH_REG_MCR_PS;  //MII
+    }
+
+
+    mcr &= ~ETH_REG_MCR_EM; //little endian
+
+
+    if ( device->workmode.loopback == GD_ETH_LOOP_ON_MAC )
+    {
+        mcr |= ETH_REG_MCR_LM;
+    }
+
+
+    if ( device->workmode.duplex == GD_ETH_HALF_DUPLEX )
+    {
+        mcr &= ~ETH_REG_MCR_DM;
+    }
+    else
+    {
+        mcr |= ETH_REG_MCR_DM;  //mac loop back should excute here
+    }
+
+    mcr |= ETH_REG_MCR_APS; //auto pad stripping
+    mcr |= ETH_REG_MCR_ACS; //auto crc stripping
+    mcr |= ETH_REG_MCR_DC;  //deferral check
+    mcr |= ETH_REG_MCR_TE;  //tx enable
+    mcr |= ETH_REG_MCR_RE;  //rx enable
+ //   mcr |= ETH_REG_MCR_DO;//disable receive own
+    return mcr;
+
+}
+
+void ethDelay(void)
+{
+    U32 i = 0, j = 0;
+
+    for(i=0;i<100000/6;i++)
+    {
+        for(i=0;i<1000000;i++)
+        {
+            GH_ETH_get_GAR();
+        }
+    }
+}

+ 253 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_emac.h

@@ -0,0 +1,253 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_emac.h
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_EMAC_H_
+#define _GD_ETH_EMAC_H_
+#include "gtypes.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+#define GD_ETH_PHY_MAX_REG_NUM  32
+//-----------GAR---------------------MDC GMII address register
+#define ETH_REG_GAR_SHIFT_PA            (11)        //Physical layer address
+#define ETH_REG_GAR_SHIFT_GR            (6)         //GMII/MII register
+#define ETH_REG_GAR_SHIFT_CR            (2)         //Application clock range
+#define ETH_REG_GAR_GW                  (1<<1)      //GMII/MII write
+#define ETH_REG_GAR_GB                  (1<<0)      //GMII/MII busy
+
+//-----------BMR---------------------MDC bus mode reg
+#define ETH_REG_BMR_SWRST               (1<<0)
+#define ETH_REG_BMR_PBL1                (1<<8)
+#define ETH_REG_BMR_PBL2                (2<<8)
+#define ETH_REG_BMR_PBL4                (4<<8)
+#define ETH_REG_BMR_PBL8                (8<<8)
+#define ETH_REG_BMR_PBL16               (16<<8)
+#define ETH_REG_BMR_PBL32               (32<<8)     //if set, all internal regs of F_MAC3H is reset
+
+//-----------IER---------------------MDC INT enable
+#define ETH_REG_IER_TI                   (1<<0)     //transmit int
+#define ETH_REG_IER_TS                   (1<<1)     //transmit process stopped
+#define ETH_REG_IER_TU                   (1<<2)     //transmit buf unavailable
+#define ETH_REG_IER_TJ                   (1<<3)     //transmit jabber timeout
+#define ETH_REG_IER_OVF                  (1<<4)     //
+#define ETH_REG_IER_UN                   (1<<5)     //transmit underflow
+#define ETH_REG_IER_RI                   (1<<6)     //receive int
+#define ETH_REG_IER_RU                   (1<<7)     //reveive buf unavailable
+#define ETH_REG_IER_RS                   (1<<8)     //reveive process stopped
+#define ETH_REG_IER_RW                   (1<<9)     //reveive watchdog timeout
+#define ETH_REG_IER_ETE                  (1<<10)    //early transmit int
+#define ETH_REG_IER_FBE                  (1<<13)    //fatal bus error
+#define ETH_REG_IER_ERE                  (1<<14)    //early reveive int
+#define ETH_REG_IER_AI                   (1<<15)    //abnormal int
+#define ETH_REG_IER_NI                   (1<<16)    //normal int
+
+//---------------MCR----------------------MAC configuration reg
+#define ETH_REG_MCR_RE                   (1<<2)     //reveive enable
+#define ETH_REG_MCR_TE                   (1<<3)     //transmit enable
+#define ETH_REG_MCR_DC                   (1<<4)     //deferral check
+#define ETH_REG_MCR_BL                   (3<<5)     //back-off limit
+#define ETH_REG_MCR_ACS                  (1<<7)     //automatic crc stripping
+#define ETH_REG_MCR_APS                  (1<<8)     //automatic pad stripping
+#define ETH_REG_MCR_DR                   (1<<9)     //disable retry
+#define ETH_REG_MCR_DM                   (1<<11)    //duplex mode
+#define ETH_REG_MCR_LM                   (1<<12)    //loop_back mode
+#define ETH_REG_MCR_DO                   (1<<13)    //disable receive own
+#define ETH_REG_MCR_EM                   (1<<14)    //Endian mode
+#define ETH_REG_MCR_PS                   (1<<15)    //port select(0-GMII / 1-MII)
+#define ETH_REG_MCR_JE                   (1<<20)    //Jumbo frame enable
+#define ETH_REG_MCR_BE                   (1<<21)    //frame burst enable
+#define ETH_REG_MCR_JD                   (1<<22)    //jabber disable
+#define ETH_REG_MCR_WD                   (1<<23)    //watchdog disable
+
+//---------------MFFR----------------------MAC frame filter reg
+#define ETH_REG_MFFR_PR                   (1<<0)    //promiscuous mode
+#define ETH_REG_MFFR_HP                   (1<<1)    //hash/perfect filtering mode
+#define ETH_REG_MFFR_HO                   (1<<2)    //hash only filtering mode
+#define ETH_REG_MFFR_IF                   (1<<3)    //inverse filtering
+#define ETH_REG_MFFR_PM                   (1<<4)    //pass all multicast
+#define ETH_REG_MFFR_DB                   (1<<5)    //disable broadcast frame
+#define ETH_REG_MFFR_PCF                  (1<<7)    //pass control frames
+#define ETH_REG_MFFR_RA                   0x80000000   //(1<<31)   //revceive all
+
+//---------------FCR----------------------flow control reg
+#define ETH_REG_FCR_FCB                   (1<<0)    //flow control busy
+#define ETH_REG_FCR_TFE                   (1<<1)    //
+#define ETH_REG_FCR_RFE                   (1<<2)    //receive flow control enable
+#define ETH_REG_FCR_UP                    (1<<3)    //unicast pause frame detect
+#define ETH_REG_FCR_PT                    (0xffff<<16)  //pause time
+
+//---------------OMR----------------------MDC operation mode reg
+#define ETH_REG_OMR_SR                    (1<<1)    //start/stop receive
+#define ETH_REG_OMR_OSF                   (1<<2)    //operate on second frame
+#define ETH_REG_OMR_ST                    (1<<13)   //start/stop transmit
+#define ETH_REG_OMR_TTC                   (7<<14)   //transmit threshold control
+#define ETH_REG_OMR_SF                    (1<<21)   //store and forward
+
+//---------------SR------------------------MDC status reg
+#define ETH_REG_SR_TI                   (1<<0)      //transmit int(frame complete)
+#define ETH_REG_SR_TPS                  (1<<1)      //transmit process stopped
+#define ETH_REG_SR_TU                   (1<<2)      //transmit buf unavailable
+#define ETH_REG_SR_TJT                  (1<<3)      //transmit jabber timeout
+#define ETH_REG_SR_OVF                  (1<<4)      //
+#define ETH_REG_SR_UNF                  (1<<5)      //transmit underflow
+#define ETH_REG_SR_RI                   (1<<6)      //receive int(frame complete)
+#define ETH_REG_SR_RU                   (1<<7)      //reveive buf unavailable
+#define ETH_REG_SR_RPS                  (1<<8)      //receive process stopped
+#define ETH_REG_SR_RWT                  (1<<9)      //reveive watchdog timeout
+#define ETH_REG_SR_ETI                  (1<<10)     //early transmit int
+#define ETH_REG_SR_FBE                  (1<<13)     //fatal bus error
+#define ETH_REG_SR_ERI                  (1<<14)     //early receive int
+#define ETH_REG_SR_AIS                  (1<<15)     //abnormal int summary
+#define ETH_REG_SR_NIS                  (1<<16)     //normal int summary
+#define ETH_REG_SR_RS                   (7<<17)     //(not int)receive process state
+#define ETH_REG_SR_TS                   (7<<20)     //(not int)transmit process state
+#define ETH_REG_SR_EB                   (7<<23)     //(not int)error bits(1-host abort during transmit / 2-host abort during receive)
+
+#define ETH_REG_SR_TXEB                 (1<<23)     //
+#define ETH_REG_SR_RXEB                 (2<<23)     //
+
+//---------------RDES0------------------------
+#define ETH_DES_R0_RMA                 (1<<0)       //RX MAC Address
+#define ETH_DES_R0_CE                  (1<<1)       //crc error
+#define ETH_DES_R0_DL                  (1<<2)       //Dribble Bit Error
+#define ETH_DES_R0_RE                  (1<<3)       //receive error
+#define ETH_DES_R0_RWT                 (1<<4)       //receive watchdog timeout
+#define ETH_DES_R0_FT                  (1<<5)       //frame type
+#define ETH_DES_R0_LC                  (1<<6)       //late conllision
+#define ETH_DES_R0_GF                  (1<<7)       //giant frame
+#define ETH_DES_R0_LS                  (1<<8)       //last descriptor
+#define ETH_DES_R0_FS                  (1<<9)       //first descriptor
+#define ETH_DES_R0_VLAN                (1<<10)      //vlan frame is received
+#define ETH_DES_R0_OE                  (1<<11)      //overflow error
+#define ETH_DES_R0_LE                  (1<<12)      //length error
+#define ETH_DES_R0_SAF                 (1<<13)      //Source Address Filter Fail
+#define ETH_DES_R0_DE                  (1<<14)      //descriptor length
+#define ETH_DES_R0_ES                  (1<<15)      //error summary
+#define ETH_DES_R0_FL                  (0x3fff<<16) //frame length
+#define ETH_DES_R0_AFM                 (1<<30)      //Destination Address Filter Fail
+#define ETH_DES_R0_OWN                 0x80000000   //(1<<31)      //OWN bit
+
+//---------------RDES1------------------------
+#define ETH_DES_R1_RBS1                (0x7ff<<0)   //receive buf1 size
+#define ETH_DES_R1_RBS2                (0x7ff<<11)  //receive buf2 size
+#define ETH_DES_R1_RCH                 (1<<24)      //second address chained
+#define ETH_DES_R1_RER                 (1<<25)      //receive end of ring
+#define ETH_DES_R1_DIC                 0x80000000   //(1<<31)      //Disable Interrupt on Completion
+
+//---------------TDES0------------------------
+#define ETH_DES_T0_DB                  (1<<0)       //defferal bit
+#define ETH_DES_T0_UF                  (1<<1)       //underflow error
+#define ETH_DES_T0_ED                  (1<<2)       //excessive defferal
+#define ETH_DES_T0_CC                  (0xf<<3)     //collision count
+#define ETH_DES_T0_VF                  (1<<7)       //vlan frame
+#define ETH_DES_T0_EC                  (1<<8)       //excessive collision
+#define ETH_DES_T0_LCO                 (1<<9)       //late collision
+#define ETH_DES_T0_NC                  (1<<10)      //no carrier
+#define ETH_DES_T0_LC                  (1<<11)      //loss of carrier
+#define ETH_DES_T0_FF                  (1<<13)      //Frame Flushed
+#define ETH_DES_T0_JT                  (1<<14)      //jabber timeout
+#define ETH_DES_T0_ES                  (1<<15)      //error summary
+#define ETH_DES_T0_OWN                 0x80000000   //(1<<31)      //OWN bit
+
+//---------------TDES1------------------------
+#define ETH_DES_T1_TBS1                (0x7ff<<0)   //transmit buf1 size
+#define ETH_DES_T1_TBS2                (0x7ff<<11)  //transmit buf2 size
+#define ETH_DES_T1_DP                  (1<<23)      //disable padding
+#define ETH_DES_T1_TCH                 (1<<24)      //second address chained
+#define ETH_DES_T1_TER                 (1<<25)      //transmit end of ring
+#define ETH_DES_T1_DC                  (1<<26)      //disable crc
+#define ETH_DES_T1_FS                  (1<<29)      //first segment
+#define ETH_DES_T1_LS                  (1<<30)      //last segment
+#define ETH_DES_T1_IC                  0x80000000   //(1<<31)        //int on collision
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+typedef struct
+{
+    U32    des0;    //record the status information of the rx/tx
+    U32    des1;    //rx/tx buffer size
+    U32    des2;    //rx/tx buffer address which the current description pointed to
+    U32    des3;    //reserved
+} GD_ETH_MAC_DesT;
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+void gmcSWError(GD_HANDLE handle);
+void ethLCErr(GD_HANDLE handle, GBOOL IsRx);
+void ethRUInt(GD_HANDLE handle);
+void ethOVFInt(GD_HANDLE handle);
+void ethRWTInt(GD_HANDLE handle);
+void ethTUInt(GD_HANDLE handle);
+void ethUNFInt(GD_HANDLE handle);
+void ethTJTInt(GD_HANDLE handle);
+void ethFBEInt(GD_HANDLE handle, U32 sr);
+void ethHandleIntRx(GD_HANDLE handle);
+void ethHandleIntTx(GD_HANDLE handle);
+U32 ethSetupMCR(GD_HANDLE handle);
+
+void GD_ETH_StartDevice(GD_HANDLE handle, GD_ETH_RWE IsRx);
+GBOOL GD_ETH_CheckPhyBusy(void);
+GBOOL GD_ETH_ReadPhy(U8 phyAddr, U8 phyReg, U32* phyRegValue);
+GBOOL GD_ETH_WritePhy(U8 phyAddr, U8 phyReg, U32 phyRegVal);
+GERR GD_ETH_PHY_HWReset(GD_HANDLE handle);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GISR1 GD_ETH_Isr(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_EMAC_H_ */
+

+ 570 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_ephy.c

@@ -0,0 +1,570 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_rtl8201.c
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gd_timer.h"
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_eth_ephy.h"
+
+#include "gh_eth.h"
+#include "gh_ephy.h"
+#include "gh_gpio.h"
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+#define WRREG(addr, value)  *(volatile unsigned long*)(addr) = (value)
+#define RDREG(addr)         *(volatile unsigned long*)(addr)
+#if 0
+void MHal_EMAC_WritReg8( U32 bank, U32 reg, U8 val )
+{
+    U32 address = REG_EPHY_CONTROL + (bank-0x32)*0x100*2;
+    address = address + (reg << 1) - (reg & 1);
+
+    *( ( volatile U8* ) address ) = val;
+}
+
+U8 MHal_EMAC_ReadReg8( U32 bank, U32 reg )
+{
+    U8 val;
+    U32 address = REG_EPHY_CONTROL + (bank-0x32)*0x100*2;
+    address = address + (reg << 1) - (reg & 1);
+
+    val = *( ( volatile U8* ) address );
+    return val;
+}
+#endif
+
+GERR GD_ETH_EPHY_Init(void)
+{
+    U8 uRegVal;
+#if 1
+    //WRREG(0x60022540, 0x0000);//default is 0x1000
+    //GH_EPHY_set_MDIIO_mdio_idle_error_cnt_clear(0x00);
+    GH_EPHY_set_MDIIO_pd_vbuf(0x00);
+
+    //WRREG(0x600220C8, 0xC400);  //default is 0x0000// reg_test_out(debug_bus_out)
+    //GH_EPHY_set_DEBUG_snr_locked(0x00);
+    //GH_EPHY_set_DEBUG_snr_locked_raw(0x00);
+    //GH_EPHY_set_DEBUG_sig_det_flag(0x00);
+    //GH_EPHY_set_DEBUG_state_sync_on(0x00);
+    //GH_EPHY_set_DEBUG_state_st_lk(0x00);
+    GH_EPHY_set_DEBUG_mux_recov_cnt(0x04);
+    GH_EPHY_set_DEBUG_test_mux_sel(0x03);
+    //GH_EPHY_set_DEBUG(0xC400);
+
+    //WRREG(0x600220E0, 0x810A);//default is 0x0000  // debug mode
+    GH_EPHY_set_DEBUG_MODE_signal(0x0A);
+    GH_EPHY_set_DEBUG_MODE_module(0x81);
+    //GH_EPHY_set_DEBUG(0x810A);
+
+    //WRREG(0x60022588, 0x0007);  // DAC 100M clk gate for 10M TX
+    //GH_EPHY_set_CLK0_lpi_tx_tq_timer_msb(0x07);
+    //GH_EPHY_set_CLK0_clko_125_inv(0x00);
+    //GH_EPHY_set_CLK0_clko_100_gat(0x00);
+    //GH_EPHY_set_CLK0_clko_100_inv(0x00);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xde, 0x59);
+    //WRREG(0x600223BC, 0x0059);//default is 0x0059
+    //GH_EPHY_set_PWR_pwr_k_in_lp(0x01);
+    //GH_EPHY_set_PWR_dtpwr_enable_lp(0x01);
+    //GH_EPHY_set_PWR_gcr_adcpl_div_lp(0x05);
+    //GH_EPHY_set_PWR_dummy(0x00);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xf4, 0x21);
+    //WRREG(0x600223E8, 0x0821);//default is 0x0821
+    //GH_EPHY_set_ADCPL_mod_10t(0x01);
+    //GH_EPHY_set_ADCPL_mod(0x00);
+    //GH_EPHY_set_ADCPL_mod_lp(0x02);
+    //GH_EPHY_set_ADCPL_adc_frc_zero(0x00);
+    //GH_EPHY_set_ADCPL_adcpl_step(0x04);
+    //GH_EPHY_set_ADCPL_ac_a_timer_start(0x00);
+    //GH_EPHY_set_ADCPL_ac_sample_timer_start(0x00);
+    //GH_EPHY_set_ADCPL_txramp_gen_10t(0x00);
+
+    //MHal_EMAC_WritReg8(0x0032, 0x72, 0x80);
+    //WRREG(0x600220E4, 0x0480);//default is 0x0480
+    //GH_EPHY_set_RST_EN_mau_srst(0x00);
+    //GH_EPHY_set_RST_EN_pls_srst(0x00);
+    //GH_EPHY_set_RST_EN_sqe_test_enable(0x00);
+    //GH_EPHY_set_RST_EN_lpbk_enable(0x00);
+    //GH_EPHY_set_RST_EN_jabber_enable(0x00);
+    //GH_EPHY_set_RST_EN_ser_polarity_correction(0x00);
+    //GH_EPHY_set_RST_EN_por_stick_mode(0x00);
+    //GH_EPHY_set_RST_EN_recv_bit_bucket(0x01);
+    //GH_EPHY_set_RST_EN_rxclk_pol(0x00);
+    //GH_EPHY_set_RST_EN_txclk_pol(0x00);
+    //GH_EPHY_set_RST_EN_adc_input_sign(0x01);
+    //GH_EPHY_set_RST_EN_mii_test_packet(0x00);
+    //GH_EPHY_set_RST_EN_clear_rcvpack(0x00);
+    //GH_EPHY_set_RST_EN_miiloop_en_10m(0x00);
+    //GH_EPHY_set_RST_EN_mii_rxclk_pol(0x00);
+    //GH_EPHY_set_RST_EN_mii_txclk_pol(0x00);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xfc, 0x00);
+    //MHal_EMAC_WritReg8(0x0033, 0xfd, 0x00);
+    //WRREG(0x600223F8, 0x0000);//default is 0x0102
+    GH_EPHY_set_LDO_dummy(0x0000);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xb7, 0x07);
+    //WRREG(0x6002236C, 0x0700);//default is 0x1704
+    GH_EPHY_set_ADC_adc_bp(0x00);
+    //GH_EPHY_set_ADC_dac10t_testen(0x00);
+    //GH_EPHY_set_ADC_reg_dac100t_testen(0x00);
+    //GH_EPHY_set_ADC_adc_bma(0x07);
+    GH_EPHY_set_ADC_adc_pd(0x00);
+    //GH_EPHY_set_ADC_region_bank_rd(0x00);
+    //GH_EPHY_set_ADC_adcpll_ana_clken(0x00);
+    //GH_EPHY_set_ADC_adcbin_testen(0x00);
+    //GH_EPHY_set_ADC(0x0700);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xcb, 0x11);
+    //WRREG(0x60022394, 0x1100);//default is 0x111A
+    //GH_EPHY_set_PLL_ADC_CTRL0_ro_adcpl_lock(0x00);
+    GH_EPHY_set_PLL_ADC_CTRL0_gcr_adcpl_div(0x00);
+    GH_EPHY_set_PLL_ADC_CTRL0_test_adcpl_extcksel(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_ro_adcpl_high_flag(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_pllclk_outen(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_ov_ref_test(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_gc_adcpl_rstb(0x01);
+    //GH_EPHY_set_PLL_ADC_CTRL0_ref_bgap_pd(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_adcraw_tst(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_adcraw_tst_sw(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_ldo_pwrgd(0x01);
+    //GH_EPHY_set_PLL_ADC_CTRL0_adcraw_overflow(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_adcpl_force_phase(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0_gcr_adcpl_tog_clkcc(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL0(0x1100);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xcc, 0x80);
+    //MHal_EMAC_WritReg8(0x0033, 0xcd, 0xd1);
+    //WRREG(0x60022398, 0xD180);//default is 0xD990
+    //GH_EPHY_set_PLL_ADC_CTRL1_gc_adcpl_adcpd0(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gc_adcpl_adcpd1(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gc_adcpl_ccpd0(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gc_adcpl_ccpd1(0x00);
+    GH_EPHY_set_PLL_ADC_CTRL1_pd_adcpl_reg(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gcr_adcpl_mod_100t(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gcr_adcpl_ictrl(0x03);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gcr_adcpl_enfrunz(0x00);
+    GH_EPHY_set_PLL_ADC_CTRL1_en_adcpl_porst(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_en_adcpl_adcphdac(0x01);
+    //GH_EPHY_set_PLL_ADC_CTRL1_gc_adcpl_adcselect(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL1_tx_d_test(0x03);
+    //GH_EPHY_set_PLL_ADC_CTRL1(0xD180);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xd4, 0x00);
+    //WRREG(0x600223A8, 0x0000);//default is 0x0020
+    //GH_EPHY_set_PLL_ADC_CTRL2_gc_ref_vgen(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_gc_ref_vcom(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_gc_ref_vcmpcmvx(0x00);
+    GH_EPHY_set_PLL_ADC_CTRL2_pd_lpf_op(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_gc_adc_force1(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_gc_adc_force0(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_endiscz_10(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_gcr_adcpl_pdphadc(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_adcpl_bank(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_adcpl_phase_force(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_adcpl_phase_force_st(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2_adcpl_force_go(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL2(0x0000);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xb9, 0x40);
+    //WRREG(0x60022370, 0x4000);//default is 0x4100
+    GH_EPHY_set_PLL_ADC_CTRL3_rxlpf_pd(0x00);
+    //GH_EPHY_set_PLL_ADC_CTRL3_tx_b_test(0x20);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xbb, 0x05);
+    //WRREG(0x60022374, 0x0500);//default is 0x4403
+    //GH_EPHY_set_RX_LPF_rxlpf_ibsel(0x00);
+    //GH_EPHY_set_RX_LPF_rxlpf_bwsel(0x00);
+    //GH_EPHY_set_RX_LPF_unkown(0x02);
+    //GH_EPHY_set_RX_LPF_rxlpf_cmsel(0x01);
+    //GH_EPHY_set_RX_LPF_rxlpf_outp_test(0x00);
+    //GH_EPHY_set_RX_LPF_rxlpf_outm_test(0x00);
+    //GH_EPHY_set_RX_LPF_rxlpf_bypass(0x00);
+    //GH_EPHY_set_RX_LPF_ref_pd(0x00);
+    //GH_EPHY_set_RX_LPF_ref_iint_pd(0x00);
+    GH_EPHY_set_RX_LPF(0x0500);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xea, 0x46);
+    //WRREG(0x600223D4, 0x0046);//default is 0x4060
+    //GH_EPHY_set_ADC_DC_dc_force_en(0x00);
+    GH_EPHY_set_ADC_DC_dc_force(0x03);
+    GH_EPHY_set_ADC_DC_dc_can_inv(0x00);
+    //GH_EPHY_set_ADC_DC_analog_blw(0x01);
+    //GH_EPHY_set_ADC_DC_dc_k(0x00);
+    //GH_EPHY_set_ADC_DC_srst(0x00);
+    //GH_EPHY_set_ADC_DC_adc_cancel_out(0x00);
+    GH_EPHY_set_ADC_DC_adc_cancel_disable(0x00);
+    //GH_EPHY_set_ADC_DC_adc_start(0x00);
+    //GH_EPHY_set_ADC_DC(0x0046);
+
+    //MHal_EMAC_WritReg8(0x0033, 0xa1, 0x00);
+    //WRREG(0x60022340, 0x0000);//default is 0x1000
+    //GH_EPHY_set_LPF_lpf_out_h(0x00);
+    //GH_EPHY_set_LPF_rxlpf_bwsel_10t(0x00);
+    GH_EPHY_set_LPF_rxlpf_bwsel_100t(0x00);
+    //GH_EPHY_set_LPF_cable_length(0x00);
+    //GH_EPHY_set_LPF(0x0000);
+
+    //MHal_EMAC_WritReg8(0x0034, 0x3a, 0x03);
+    //MHal_EMAC_WritReg8(0x0034, 0x3b, 0x00);
+    //WRREG(0x60022474, 0x0003);//default is 0x03F3 power down close
+    //GH_EPHY_set_POWER_pd_tx_ld(0x01);
+    //GH_EPHY_set_POWER_pd_tx_idac(0x01);
+    //GH_EPHY_set_POWER_pd_dacramp_new(0x00);
+    //GH_EPHY_set_POWER_pd_dacnew_testen(0x00);
+    GH_EPHY_set_POWER_pd_tx_ld_10t(0x00);
+    GH_EPHY_set_POWER_pd_tx_ld_100t(0x00);
+    GH_EPHY_set_POWER_pd_tx_ld_lp(0x00);
+    GH_EPHY_set_POWER_pd_tx_idac_10t(0x00);
+    GH_EPHY_set_POWER_pd_tx_idac_100t(0x00);
+    GH_EPHY_set_POWER_pd_tx_idac_lp(0x00);
+    //GH_EPHY_set_POWER(0x0003);
+
+    //gain shift
+    //MHal_EMAC_WritReg8(0x0033, 0xb4, 0x56);
+    //WRREG(0x60022368, 0x0056);//default is 0x0000
+    GH_EPHY_set_ADC_GSHIFT_adc_gshift(0x02);
+    GH_EPHY_set_ADC_GSHIFT_gain(0x15);
+    //GH_EPHY_set_ADC_GSHIFT(0x0056);
+
+    //det max
+    //MHal_EMAC_WritReg8(0x0033, 0x4f, 0x02);
+    //WRREG(0x6002229C, 0x024C);//default is 0x054C
+    //GH_EPHY_set_DET_MAX_thrh_max_vga_coarse(0x4C);
+    GH_EPHY_set_DET_MAX_thrh_max_sig_det(0x02);
+    //GH_EPHY_set_DET_MAX(0x024C);
+
+    //det min
+    //MHal_EMAC_WritReg8(0x0033, 0x51, 0x01);
+    //WRREG(0x600222A0, 0x0160);//default is 0x0260
+    //GH_EPHY_set_DET_MIN_thrh_max_vga_fine(0x60);
+    GH_EPHY_set_DET_MIN_thrh_min_sig_det(0x01);
+    //GH_EPHY_set_DET_MIN(0x0160);
+
+    //snr len (emc noise)
+    //MHal_EMAC_WritReg8(0x0033, 0x77, 0x18);
+    //WRREG(0x600222EC, 0x1800);//default is 0x0000
+    //GH_EPHY_set_SNR_LEN_mcu_ctrl_dsp_fsm_state(0x00);
+    //GH_EPHY_set_SNR_LEN_force_100m_en(0x00);
+    //GH_EPHY_set_SNR_LEN_force_100m_snr_lock(0x00);
+    //GH_EPHY_set_SNR_LEN_dsp_fsm_agc_en_mode_a(0x00);
+    GH_EPHY_set_SNR_LEN_cable_len_offset(0x03);
+    //GH_EPHY_set_SNR_LEN(0x1800);
+
+    //snr k value
+    //MHal_EMAC_WritReg8(0x0033, 0x43, 0x15);
+    //WRREG(0x60022284, 0x1520);//default is 0x1520
+    //GH_EPHY_set_SNR_K_slice_up(0x20);
+    //GH_EPHY_set_SNR_K_snrchk_k1(0x01);
+    //GH_EPHY_set_SNR_K_snrchk_k2(0x01);
+    //GH_EPHY_set_SNR_K_snrchk_k3(0x01);
+    //GH_EPHY_set_SNR_K_gcr_ccpl_master_coarse_clkcc(0x00);
+
+    //100 gat
+    //MHal_EMAC_WritReg8(0x0034, 0xc5, 0x00);
+    //WRREG(0x60022588, 0x0007);//default is 0x4007 DAC 100M clk gate for 10M TX
+    //GH_EPHY_set_CLK0_lpi_tx_tq_timer_msb(0x07);
+    //GH_EPHY_set_CLK0_clko_125_inv(0x00);
+    GH_EPHY_set_CLK0_clko_100_gat(0x00);
+    //GH_EPHY_set_CLK0_clko_100_inv(0x00);
+    //GH_EPHY_set_CLK0(0x0007);
+
+    //200 gat
+    //MHal_EMAC_WritReg8(0x0034, 0x30, 0x43);
+    //WRREG(0x60022460, 0x0043);//default is 0x0053 Add this 100M up down loop
+    //GH_EPHY_set_CLK1_unkown(0x03);
+    GH_EPHY_set_CLK1_clko_200_gat(0x00);
+    //GH_EPHY_set_CLK1_clko_200_inv(0x00);
+    //GH_EPHY_set_CLK1_lut_new(0x01);
+    //GH_EPHY_set_CLK1(0x0043);
+
+    //en_100t_phase
+    //MHal_EMAC_WritReg8(0x0034, 0x39, 0x41);
+    //WRREG(0x60022470, 0x4100);//default is 0x0000
+    //GH_EPHY_set_GCR_TX_ioffset_sel(0x00);
+    //GH_EPHY_set_GCR_TX_ld_vcmo(0x00);
+    //GH_EPHY_set_GCR_TX_ph_delay(0x00);
+    GH_EPHY_set_GCR_TX_phase_100t(0x01);
+    //GH_EPHY_set_GCR_TX_ld_iq_sel(0x00);
+    //GH_EPHY_set_GCR_TX_ld_iq_ibias(0x00);
+    //GH_EPHY_set_GCR_TX_en_tx_ioffset(0x00);
+    GH_EPHY_set_GCR_TX_save2x_tx(0x01);
+    //GH_EPHY_set_GCR_TX_wssel_inv(0x00);
+    //GH_EPHY_set_GCR_TX(0x4100);
+
+    //10T waveform
+    //uRegVal = MHal_EMAC_ReadReg8(0x0034, 0xe8);
+    //uRegVal &= 0xf8;
+    //uRegVal |= 0x06;
+    //MHal_EMAC_WritReg8(0x0034, 0xe8, uRegVal);
+    //WRREG(0x600225D0, uRegVal);//default is 0x0000
+    GH_EPHY_set_WAVE_CTRL_shadow(0x06);
+
+    //MHal_EMAC_WritReg8(0x0032, 0x2b, 0x00);
+    //WRREG(0x60022054, 0x0000);//default is 0xF800 or 0xFC00
+    //GH_EPHY_set_WAVE_SHAPING_DE_ltp_D(0x00);
+    GH_EPHY_set_WAVE_SHAPING_DE_ltp_E(0x00);
+    //GH_EPHY_set_WAVE_SHAPING_DE(0x0000);
+
+    //analog
+    //MHal_EMAC_WritReg8(0x0033, 0xd8, 0xb0);
+    //MHal_EMAC_WritReg8(0x0033, 0xd9, 0x30);
+    //WRREG(0x600223B0, 0x30B0);//default is 0x0000
+    GH_EPHY_set_TEST_TX(0x30B0);
+
+    //disable EEE
+    //uRegVal = MHal_EMAC_ReadReg8(0x0032, 0x2d);
+    //uRegVal |= 0x40;
+    //MHal_EMAC_WritReg8(0x0032, 0x2d, uRegVal);
+    //WRREG(0x60022058, 0x7C00);//default is 0x3C00
+    //GH_EPHY_set_SPEED_ltp_F(0x00);
+    //GH_EPHY_set_SPEED_isolate(0x00);
+    //GH_EPHY_set_SPEED_rptr(0x00);
+    //GH_EPHY_set_SPEED_duplex(0x01);
+    //GH_EPHY_set_SPEED_speed(0x01);
+    //GH_EPHY_set_SPEED_ane(0x01);
+    //GH_EPHY_set_SPEED_ldps(0x01);
+    GH_EPHY_set_SPEED_disable_eee_force(0x01);
+    //GH_EPHY_set_SPEED(0x7C00);
+#else
+    //WRREG(0x60022000, 0x00000000);
+    WRREG(0x600223F8, 0x00000000);
+    WRREG(0x6002236C, 0x00000700);
+    WRREG(0x60022394, 0x00001100);
+    WRREG(0x60022398, 0x0000D180);
+    WRREG(0x600223A8, 0x00000000);
+    WRREG(0x60022370, 0x00004000);
+    WRREG(0x60022374, 0x00000500);
+    WRREG(0x600223D4, 0x00000046);
+    WRREG(0x60022540, 0x00000000);
+    WRREG(0x60022474, 0x00003A03);  // power down close
+    WRREG(0x600220C8, 0x0000C400);  // reg_test_out(debug_bus_out)
+    WRREG(0x600220E0, 0x0000810A);  // debug mode
+    // riu_cs_bkb
+    //WRREG(0x60022588, RDREG(0x60022588)&(~(1<<14)));    // DAC 100M clk gate for 10M TX
+    WRREG(0x60022588, 0x00000007); // DAC 100M clk gate for 10M TX
+    //WRREG(0x60022450, RDREG(0x60022450)&(~(1<<4)));     // DAC 200M clk gate for 10M TX
+    //WRREG(0x60022450, 0x00000002); // DAC 200M clk gate for 10M TX
+#if 0 // CASE 1 100M dis_an TX->RX GD_ETH_Open failed
+    WRREG(0x60022058, RDREG(0x60022058)&(~(1<<12)));    // an_en from HW
+    WRREG(0x60022058, RDREG(0x60022058)|(1<<11));       // MII 100M speed sel from HW
+    WRREG(0x60022088, RDREG(0x60022088)|(1<<7));        // reg_force_100M_link_good
+#endif
+
+#if 0 // CASE 2 100M near_loop
+    WRREG(0x60022058, RDREG(0x60022058)&(~(1<<12)));    // an_en from HW
+    WRREG(0x60022058, RDREG(0x60022058)|(1<<11));       // MII 100M speed sel from HW
+    WRREG(0x60022088, RDREG(0x60022088)|(1<<7));        // force 100M link good
+    WRREG(0x60022000, RDREG(0x60022000)|(1<<14));       // reg_mii_ctl_loopback
+    WRREG(0x600220DC, RDREG(0x600220DC)|0x7F);          // near_loop_s1
+    // wait 100us
+    for(ii=0;ii<20;ii++)
+    {
+        ;
+    }
+    //WRREG(0x600220DC, (RDREG(0x600220DC)&(~0x7F))|0x7E);// near_loop_s2
+    // wait 100us
+    for(ii=0;ii<20;ii++)
+    {
+        ;
+    }
+    WRREG(0x600220DC, (RDREG(0x600220DC)&(~0x7F))|0x7D);// near_loop_s3
+#endif
+
+#if 1 // CASE 3 10M dis_an TX->RX OK
+    //WRREG(0x60022460, RDREG(0x60022460)&(~(1<<4)));     // reg_clk0_200
+    //WRREG(0x60022058, RDREG(0x60022058)&(~(1<<12)));    // an_en from HW
+    //WRREG(0x60022058, RDREG(0x60022058)&(~(1<<11)));    // MII 10M speed sel from HW
+    //WRREG(0x60022080, RDREG(0x60022080)|(1<<7));        // force nlp pass
+    WRREG(0x60022460, 0x0043);       // Add this 100M up down loop
+    //GH_EPHY_set_SPEED_ane(0x01);
+
+    //WRREG(0x60022088, RDREG(0x60022088)|(1<<7));        // force 100M link good
+    GH_EPHY_set_SPEED_ane(0x00);
+    GH_EPHY_set_SPEED_duplex(1);//full
+    GH_EPHY_set_SPEED_speed(1);//100M
+    WRREG(0x600221AC, RDREG(0x600221AC)|(1<<0));        // transmit pattern generation
+#endif
+
+#if 0 // CASE 4 10M near_loop
+    WRREG(0x60022058, RDREG(0x60022058)&(~(1<<12)));    // an_en from HW
+    WRREG(0x60022058, RDREG(0x60022058)&(~(1<<11)));    // MII 10M speed sel from HW
+    WRREG(0x60022080, RDREG(0x60022080)|(1<<7));        // force nlp pass
+    WRREG(0x60022180, RDREG(0x60022180)|(1<<14));       // reg_10M_near_loop
+#endif
+
+#if 0 // CASE 5 100M AN
+    WRREG(0x60022058, RDREG(0x60022058)|(1<<12));       // an_en from HW
+    WRREG(0x600221AC, RDREG(0x600221AC)|(1<<0));        // transmit pattern generation
+    WRREG(0x6002209C, RDREG(0x6002209C)&0xFFFFFF00);    // reg_breaklink_timer
+    WRREG(0x600220AC, RDREG(0x600220AC)|(1<<15));       // is_clk_sel, speed the simulation
+#endif
+#endif
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_Open(GD_HANDLE handle)
+{
+    GH_GPIO_set_PER_SEL_enet_sel((U32)0x00000000);
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_Close(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_SWReset(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT workmode)
+{
+    GERR gerr = GD_OK;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    U8      ii = 0;
+    GBOOL   retval = GFALSE;
+    U32     regval = (U32)0;
+    U8      addr;
+    // to be do: only can use an mode
+    return GD_OK;
+    if (handle == 0)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(handle);
+
+    // workmode.mode
+    if(workmode.mode == GD_ETH_PHY_IF_MODE_MII)
+    {
+    }
+    else
+    {
+        return GD_ERR_ETH_NOT_SUPPORTED;
+    }
+
+    if (workmode.bEnAutoNeg == GTRUE)
+    {
+        GH_EPHY_set_SPEED_ane(0x01);
+    }
+    else
+    {
+        GH_EPHY_set_SPEED_ane(0x00);
+        // workmode.speed
+        if (workmode.speed == GD_ETH_SPEED_100M )   /* 100M */
+        {
+            GH_EPHY_set_SPEED_speed(0x01);
+        }
+        else if (workmode.speed == GD_ETH_SPEED_10M )/* 10M */
+        {
+            GH_EPHY_set_SPEED_speed(0x00);
+        }
+        else
+        {
+            return GD_ERR_ETH_NOT_SUPPORTED;
+        }
+
+        /* duplex */
+        // workmode.duplex
+        if(workmode.duplex == GD_ETH_FULL_DUPLEX)   /* Full Duplex */
+        {
+            GH_EPHY_set_SPEED_duplex(0x01);
+        }
+        else if(workmode.duplex == GD_ETH_HALF_DUPLEX) /* half */
+        {
+            GH_EPHY_set_SPEED_duplex(0x00);
+        }
+        else
+        {
+            return GD_ERR_ETH_NOT_SUPPORTED;
+        }
+    }
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat)
+{
+    U16     reg;
+    reg = GH_EPHY_get_CONTROL();
+
+    pStat->speed    = (reg & 0x2000) ? GD_ETH_SPEED_100M : GD_ETH_SPEED_10M;
+    pStat->duplex   = (reg & 0x0100) ? GD_ETH_FULL_DUPLEX : GD_ETH_HALF_DUPLEX;
+
+    reg = GH_EPHY_get_STATUS();
+    pStat->linkup   = (reg & 0x0020) ? GD_ETH_LINKUP : GD_ETH_LINKDOWN;
+
+    return GD_OK;
+}
+GERR GD_ETH_EPHY_GetId(GD_HANDLE handle, U32 *phy_id)
+{
+    //U32     ulPhyId;
+    //*phy_id |= (ulPhyId & 0xffff);
+    return GD_OK;
+}
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+

+ 83 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_ephy.h

@@ -0,0 +1,83 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_ephy.h
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_EPHY_H_
+#define _GD_ETH_EPHY_H_
+#include "gtypes.h"
+#include "gd_eth_phy.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ETH_EPHY_Init(void);
+GERR GD_ETH_EPHY_Open(GD_HANDLE handle);
+GERR GD_ETH_EPHY_Close(GD_HANDLE handle);
+GERR GD_ETH_EPHY_SWReset(GD_HANDLE handle);
+GERR GD_ETH_EPHY_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT workmode);
+GERR GD_ETH_EPHY_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+GERR GD_ETH_EPHY_GetId(GD_HANDLE handle, U32 *phy_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_EPHY_H_ */
+

+ 649 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy.c

@@ -0,0 +1,649 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy.c
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gh_gpio.h"
+#include "gh_eth.h"
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_eth_phy_rtl8201.h"
+#include "gd_eth_phy_lan8700.h"
+#include "gd_eth_phy_ar8032.h"
+#include "gd_eth_ephy.h"
+#include "gd_timer.h"
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+static GBOOL                        initialized = GFALSE;
+static GD_HANDLE                    phyhandle   = 0;
+static GD_ETH_PHY_DEVICE_DATA_S*    phydevice[GD_ETH_PHY_EXTERNAL_AUTO];
+static GD_ETH_PHY_DEVICE_DATA_S     phy[]=
+{
+    {
+        0x0007C0C4,                         /* deviceID */
+        "SMSC",                             /* manufactureName */
+        "LAN8700",                          /* deviceName */
+        GD_ETH_PHY_LAN8700_Init ,           /* GD_ETH_PHY_Init */
+        GD_ETH_PHY_LAN8700_Open,            /* GD_ETH_PHY_Open */
+        GD_ETH_PHY_LAN8700_Close,           /* GD_ETH_PHY_Close */
+        NULL,                               /* GD_ETH_PHY_SWReset use the default*/
+        NULL,                               /* GD_ETH_PHY_SetWorkMode */
+        GD_ETH_PHY_LAN8700_GetWorkStatus,   /* GD_ETH_PHY_GetWorkStatus */
+        NULL,                               /* GD_ETH_PHY_GetId use the default*/
+        (GD_ETH_PHY_AddrE)-1,               /* addr*/
+    },
+    {
+        0x0007C0F1,                         /* deviceID */
+        "SMSC",                             /* manufactureName */
+        "LAN8710/LAN8720",                          /* deviceName */
+        GD_ETH_PHY_LAN8700_Init ,           /* GD_ETH_PHY_Init */
+        GD_ETH_PHY_LAN8700_Open,            /* GD_ETH_PHY_Open */
+        GD_ETH_PHY_LAN8700_Close,           /* GD_ETH_PHY_Close */
+        NULL,                               /* GD_ETH_PHY_SWReset use the default*/
+        NULL,                               /* GD_ETH_PHY_SetWorkMode */
+        GD_ETH_PHY_LAN8700_GetWorkStatus,   /* GD_ETH_PHY_GetWorkStatus */
+        NULL,                               /* GD_ETH_PHY_GetId use the default*/
+        (GD_ETH_PHY_AddrE)-1,               /* addr*/
+    },
+    {
+        0x001CC815,                         /* deviceID */
+        "REALTEK",                          /* manufactureName */
+        "RTL8201",                          /* deviceName */
+        GD_ETH_PHY_RTL8200_Init ,           /* GD_ETH_PHY_Init */
+        GD_ETH_PHY_RTL8200_Open,            /* GD_ETH_PHY_Open */
+        GD_ETH_PHY_RTL8200_Close,           /* GD_ETH_PHY_Close */
+        NULL,                               /* GD_ETH_PHY_SWReset use the default*/
+        NULL,                               /* GD_ETH_PHY_SetWorkMode use the default*/
+        GD_ETH_PHY_RTL8200_GetWorkStatus,   /* GD_ETH_PHY_GetWorkStatus */
+        NULL,                               /* GD_ETH_PHY_GetId use the default*/
+        (GD_ETH_PHY_AddrE)-1,               /* addr*/
+    },
+    {
+        0x004DD023,                         /* deviceID */
+        "ATHEROS",                          /* manufactureName */
+        "AR8032",                           /* deviceName */
+        GD_ETH_PHY_AR8032_Init ,            /* GD_ETH_PHY_Init */
+        GD_ETH_PHY_AR8032_Open,             /* GD_ETH_PHY_Open */
+        GD_ETH_PHY_AR8032_Close,            /* GD_ETH_PHY_Close */
+        NULL,                               /* GD_ETH_PHY_SWReset use the default*/
+        NULL,                               /* GD_ETH_PHY_SetWorkMode use the default*/
+        GD_ETH_PHY_AR8032_GetWorkStatus,    /* GD_ETH_PHY_GetWorkStatus */
+        NULL,                               /* GD_ETH_PHY_GetId use the default*/
+        (GD_ETH_PHY_AddrE)-1,               /* addr*/
+    },
+    {
+        0x00000000,                         /* deviceID */
+        "GOKE",                             /* manufactureName */
+        "GK7101E",                          /* deviceName */
+        GD_ETH_EPHY_Init ,                  /* GD_ETH_PHY_Init */
+        GD_ETH_EPHY_Open,                   /* GD_ETH_PHY_Open */
+        GD_ETH_EPHY_Close,                  /* GD_ETH_PHY_Close */
+        GD_ETH_EPHY_SWReset,                /* GD_ETH_PHY_SWReset*/
+        GD_ETH_EPHY_SetWorkMode,            /* GD_ETH_PHY_SetWorkMode */
+        GD_ETH_EPHY_GetWorkStatus,          /* GD_ETH_PHY_GetWorkStatus */
+        GD_ETH_EPHY_GetId,                  /* GD_ETH_PHY_GetId*/
+        0x1F,                               /* addr*/
+    },
+};
+
+static const char *phy_if_strings[] __attribute__ ((section(".nocache_buffer"))) = {
+    "mii",
+    "gmii",
+    "sgmii",
+    "tbi",
+    "rmii",
+    "rgmii",
+    "rgmii-id",
+    "rgmii-rxid",
+    "rgmii-txid",
+    "rtbi",
+    "xgmii",
+    "",
+};
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+GERR GD_ETH_PHY_Init(U8 phyType)
+{
+    U32 i,j,k,count,phy_id,try_time;
+	U32 a = 0;
+	
+    if (initialized == GTRUE)
+    {
+        return GD_ERR_ALREADY_INITIALIZED;
+    }
+
+    try_time = 2;
+    for(k=0; k<try_time && !initialized; k++)
+    {
+        count = sizeof(phy) / sizeof(GD_ETH_PHY_DEVICE_DATA_S);
+
+        for (i=0; i<GD_ETH_PHY_EXTERNAL_AUTO; i++)
+        {
+            phydevice[i] = NULL;
+            for (j=0; j<count; j++)
+            {
+                if(phy[j].addr == (GD_ETH_PHY_AddrE)-1)
+                {
+                    if(phy[j].GD_ETH_PHY_GetId)
+                    {
+                        phy[j].GD_ETH_PHY_GetId(i, &phy_id);
+                    }
+                    else
+                    {
+                        phy[j].addr = (GD_ETH_PHY_AddrE)i;
+                        GD_ETH_PHY_GetId((GD_HANDLE)&phy[j], &phy_id);
+                    }
+                    if(phy_id == phy[j].deviceID)
+                    {
+                        phydevice[i]   = &phy[j];
+                        phy[j].addr    = (GD_ETH_PHY_AddrE)i;
+                        initialized = GTRUE;
+                        printf("find phy[%s] at:%d\n", phy[j].deviceName, i);
+                        break;
+                    }
+                    else
+                    {
+                        phy[j].addr    = (GD_ETH_PHY_AddrE)(-1);
+                    }
+                }
+                else if(phy[j].addr == i)
+                {
+                    phydevice[i]   = &phy[j];
+                    phy[j].addr    = (GD_ETH_PHY_AddrE)i;
+                    initialized = GTRUE;
+                    printf("find phy[%s] at:%d\n", phy[j].deviceName, i);
+                    break;
+                }
+                //GD_TIMER_Delay(2);
+			    if(phyType != 0)
+			    {
+					for(a=0;a<100000;a++)
+					{
+						GH_ETH_get_GAR();
+					}
+			    }
+            }
+        }
+    }
+    phyhandle   = 0;
+    return initialized ? GD_OK : GD_ERR_NO_DEVICE_DETECT;
+}
+
+GERR GD_ETH_PHY_Open(GD_ETH_PHY_AddrE* paddr, GD_HANDLE* pHandle)
+{
+    U32 i;
+    GERR gerr;
+    GD_ETH_PHY_DEVICE_DATA_S*    device;
+    if (initialized == GFALSE)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+    if(phyhandle)
+    {
+        return GD_ERR_ALREADY_OPEN;
+    }
+    if(*paddr==GD_ETH_PHY_EXTERNAL_AUTO)
+    {
+        for(i=0;i<GD_ETH_PHY_EXTERNAL_AUTO;i++)
+        {
+            if(phydevice[i] != NULL)
+            {
+                phyhandle = (GD_HANDLE)phydevice[i];
+                *pHandle  = phyhandle;
+                *paddr    = (GD_ETH_PHY_AddrE)i;
+                //return GD_OK;
+				goto PHY_INIT;
+                //if(phyhandle)
+                //{
+                //    return GD_ERR_ALREADY_OPEN;
+                //}
+            }
+        }
+        return GD_ERR_ETH_PHY_NOT_EXIST;
+    }
+    if(phydevice[*paddr] == NULL)
+    {
+        return GD_ERR_ETH_PHY_NOT_EXIST;
+    }
+    phyhandle   = (GD_HANDLE)phydevice[*paddr];
+    *pHandle = phyhandle;
+
+PHY_INIT:
+    device = phydevice[*paddr];
+    if(device->GD_ETH_PHY_Init)
+    {
+        gerr =  device->GD_ETH_PHY_Init();
+        if(gerr != GD_OK)
+        {
+            return gerr;
+        }
+    }
+    if(device->GD_ETH_PHY_Open)
+    {
+        gerr =  device->GD_ETH_PHY_Open(phyhandle);
+        if(gerr != GD_OK)
+        {
+            return gerr;
+        }
+    }
+    return GD_OK;
+}
+
+GERR GD_ETH_PHY_Close(GD_HANDLE* pHandle)
+{
+    GERR gerr;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    if (initialized == GFALSE)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+
+    if (pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(*pHandle);
+    /* call close function if any */
+    if (device->GD_ETH_PHY_Close != NULL)
+    {
+        gerr = device->GD_ETH_PHY_Close(*pHandle);
+        if (gerr != GD_OK)
+        {
+            return gerr;
+        }
+    }
+    /* reset phyhandle */
+    phyhandle = (GD_HANDLE)0;
+    *pHandle = (GD_HANDLE)0;
+    return GD_OK;
+}
+
+GERR GD_ETH_PHY_SWReset(GD_HANDLE handle)
+{
+    GERR gerr = GD_OK;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    if (initialized == GFALSE)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+
+    if (handle == 0)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(handle);
+    if (device->GD_ETH_PHY_SWReset != NULL)
+    {
+        gerr = device->GD_ETH_PHY_SWReset(handle);
+    }
+    else
+    {
+        GBOOL   retval;
+        U32     ulRegV;
+        int     timeout = 500;  //0.5s
+        U8      addr = device->addr;
+
+        /* Firstly read BMCR */
+        retval = GD_ETH_ReadPhy(addr, PHY_addr(0,BMCR), &ulRegV);
+        if ( retval != GTRUE )
+        {
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        /* Set up the softreset bit */
+        ulRegV |= PHY_val(0,RESET);
+
+        /* reset PHY */
+        retval = GD_ETH_WritePhy(addr, PHY_addr(0,BMCR), ulRegV);
+        if ( retval != GTRUE )
+        {
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        /*
+            * Poll the control register for the reset bit to go to 0 (it is
+            * auto-clearing).  This should happen within 0.5 seconds per the
+            * IEEE spec.
+            */
+        ulRegV = PHY_val(0,RESET);
+        while (((ulRegV & PHY_mask(0,RESET)) == PHY_val(0,RESET)) && timeout--)
+        {
+            /* Get PHY status */
+            if (GD_ETH_ReadPhy(addr, PHY_addr(0,BMCR), &ulRegV) == GFALSE)
+            {
+                return GD_ERR_ETH_PHY_RW;
+            }
+
+            /* Delay 1ms */
+            GD_TIMER_Delay(1);
+        }
+
+        /* Determine the PHY status */
+        if (ulRegV & PHY_mask(0,RESET))
+        {
+            return GD_ERR_ETH_PHY_RW;
+        }
+    }
+    return gerr;
+}
+
+GERR GD_ETH_PHY_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT workmode)
+{
+    GERR gerr = GD_OK;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    U8      ii = 0;
+    GBOOL   retval = GFALSE;
+    U32     regval = (U32)0;
+    U8      addr;
+    if (initialized == GFALSE)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+
+    if (handle == 0)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(handle);
+
+    if (device->GD_ETH_PHY_SetWorkMode != NULL)
+    {
+        gerr = device->GD_ETH_PHY_SetWorkMode(handle, workmode);
+    }
+    else
+    {
+        /*Set MII mode: reg 25 bit 10---0:MII , 1:RMII*/
+        addr = (U8)device->addr;
+
+        // workmode.mode
+        while(1)
+        {
+            regval = 0;
+            retval = GD_ETH_ReadPhy(addr, PHY_addr(25,TESTR), &regval);
+            if ( retval != GTRUE )
+            {
+                printf("%s:Failed to read PHY Reg_%d!\n",__FUNCTION__, PHY_addr(25,TESTR));
+                return GD_ERR_ETH_PHY_RW;
+            }
+
+            if(workmode.mode == GD_ETH_PHY_IF_MODE_RMII)
+            {
+                /*RMII mode*/
+                if((regval & PHY_mask(25,RPHY_MODE)) == PHY_val(25,RPHY_RMII))//MII mode: bit 10---0:MII , 1:RMII
+                {
+                    if((regval&PHY_mask(25,RPHY_CLKIN)) == PHY_mask(25,RPHY_CLKIN))
+                    {
+                        regval &= (~PHY_mask(25,RPHY_CLKIN));
+                        printf("25-%08x\n",regval );
+                        retval = GD_ETH_WritePhy(addr, PHY_addr(25,TESTR), regval);
+                        if ( retval != GTRUE )
+                        {
+                            printf("%s:Failed to write PHY Reg_%d!\n",__FUNCTION__, PHY_addr(25,TESTR));
+                            return GD_ERR_ETH_PHY_RW;
+                        }
+                    }
+                    else
+                    {
+                        printf("Rmii mode set OK!\n");
+                    }
+                    break;
+                }
+
+                regval &= (~PHY_mask(25,RPHY_MODE));
+                regval |= PHY_val(25,RPHY_RMII);
+            }
+            else if(workmode.mode == GD_ETH_PHY_IF_MODE_MII)
+            {
+                /*MII mode*/
+                if((regval & PHY_mask(25,RPHY_MODE)) == PHY_val(25,RPHY_MII))//MII mode: bit 10---0:MII , 1:RMII
+                {
+                    printf("mii mode set OK!\n");
+                    break;
+                }
+
+                regval &= (~PHY_mask(25,RPHY_MODE));
+                regval |= PHY_val(25,RPHY_MII);
+            }
+            else
+            {
+                return GD_ERR_ETH_NOT_SUPPORTED;
+            }
+
+            retval = GD_ETH_WritePhy(addr, PHY_addr(25,TESTR), regval);
+            if ( retval != GTRUE )
+            {
+                printf("%s:Failed to write PHY Reg_%d!\n",__FUNCTION__, PHY_addr(25,TESTR));
+                return GD_ERR_ETH_PHY_RW;
+            }
+
+            ii++;
+            if(ii >= 10)
+            {
+                //printf("%s mode set failure!\n", phy_str_for_if(pPhyDev->phyPort));
+                return GD_ERR_ETH_PHY_OTHER;
+            }
+        }
+
+
+        regval = (U32)0;
+        /* loopback setting */
+        // workmode.loopback
+        regval &= (~PHY_mask(0,LOOPBACK));
+        if (workmode.loopback == GD_ETH_LOOP_ON_PHY )
+        {
+            regval |= PHY_val(0,LOOPBACK);
+        }
+
+            /* auto nego */
+        // workmode.bEnAutoNeg
+        regval &= (~PHY_mask(0,AN_ENABLE));
+        if (workmode.bEnAutoNeg == GTRUE)
+        {
+            regval |= PHY_val(0,AUTO_NEGO);
+            // RMII mode RXD_3 used as 10/100M indicator
+            if(workmode.mode == GD_ETH_PHY_IF_MODE_RMII)
+            {
+                GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_3)-2, GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_1));
+            }
+        }
+        else
+        {
+            /* speed */
+            // workmode.speed
+            regval &= (~PHY_mask(0,SPEEDSELECT));
+            if (workmode.speed == GD_ETH_SPEED_100M )   /* 100M */
+            {
+                regval |= PHY_val(0,100M);
+                // RMII mode RXD_3 used as 10/100M indicator
+                if(workmode.mode == GD_ETH_PHY_IF_MODE_RMII)
+                {                
+			GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_3)-2, GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_1));
+                }
+            }
+            else if (workmode.speed == GD_ETH_SPEED_10M )/* 10M */
+            {
+                regval |= PHY_val(0,10M);    //nothing need to do.
+                // RMII mode RXD_3 used as 10/100M indicator
+                if(workmode.mode == GD_ETH_PHY_IF_MODE_RMII)
+                {
+			GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_ENET_PHY_RXD_3)-2, GD_GPIO_GET_IN_SEL(GD_GPIO_TYPE_INPUT_0));                    
+                }
+            }
+            else
+            {
+                return GD_ERR_ETH_NOT_SUPPORTED;
+            }
+
+            /* duplex */
+            // workmode.duplex
+            regval &= (~PHY_mask(0,DUPLEX_MODE));
+            if(workmode.duplex == GD_ETH_FULL_DUPLEX)   /* Full Duplex */
+            {
+                regval |= PHY_val(0,DUPLEX_FULL);
+            }
+            else if(workmode.duplex == GD_ETH_HALF_DUPLEX) /* half */
+            {
+                regval |= PHY_val(0,DUPLEX_HALF);    //nothing need to do.
+            }
+            else
+            {
+                return GD_ERR_ETH_NOT_SUPPORTED;
+            }
+        }
+        /* write settings */
+        retval = GD_ETH_WritePhy(addr, PHY_addr(0,BMCR), regval);
+        if ( retval != GTRUE )
+            return GD_ERR_ETH_PHY_RW;
+        return GD_OK;
+    }
+    return gerr;
+}
+
+GERR GD_ETH_PHY_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat)
+{
+    GERR gerr = GD_OK;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    if (initialized == GFALSE)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+
+    if (handle == 0)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(handle);
+
+    if (device->GD_ETH_PHY_GetWorkStatus != NULL)
+    {
+        gerr = device->GD_ETH_PHY_GetWorkStatus(handle, pStat);
+    }
+    else
+    {
+        gerr = GD_ERR_FEATURE_NOT_SUPPORTED;
+    }
+    return gerr;
+}
+
+GERR GD_ETH_PHY_GetId(GD_HANDLE handle, U32 *phy_id)
+{
+    GERR gerr = GD_OK;
+    GD_ETH_PHY_DEVICE_DATA_S* device;
+    //if (initialized == GFALSE)
+    //{
+    //    return GD_ERR_NOT_INITIALIZED;
+    //}
+
+    if (handle == 0)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    device = (GD_ETH_PHY_DEVICE_DATA_S*)(handle);
+
+    if (device->GD_ETH_PHY_GetId != NULL)
+    {
+        gerr = device->GD_ETH_PHY_GetId(device->addr, phy_id);
+    }
+    else
+    {
+        GBOOL   retval;
+        U32     ulPhyId;
+        U8      addr = device->addr;
+
+        /* Grab the bits from PHYIR1, and put them in the upper half */
+        retval = GD_ETH_ReadPhy(addr, PHY_addr(2,ID1), &ulPhyId);
+        if ( retval != GTRUE )
+        {
+#ifdef PRINT_ETH_LOG
+            printf("%s:PHYID1 read failed!\n",__FUNCTION__);
+#endif
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        *phy_id = (ulPhyId & 0xffff) << 16;
+
+        /* Grab the bits from PHYIR2, and put them in the lower half */
+        retval = GD_ETH_ReadPhy(addr, PHY_addr(3,ID2), &ulPhyId);
+        if ( retval != GTRUE )
+        {
+#ifdef PRINT_ETH_LOG
+            printf("%s:PHYID2 read failed!\n",__FUNCTION__);
+#endif
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        *phy_id |= (ulPhyId & 0xffff);
+    }
+    return gerr;
+}
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+

+ 100 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy.h

@@ -0,0 +1,100 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy.h
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_PHY_H_
+#define _GD_ETH_PHY_H_
+#include "gtypes.h"
+#include "gd_ethernet.h"
+#include "gd_eth_phy_reg.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+/*lint -emacro(835,PHY_*) */
+#define PHY_addr(N,M)       (PHY_REG##N##_##M)
+#define PHY_mask(N,F)       ((U32)(PHY_REG##N##_bit_##F) << (PHY_REG##N##_sft_##F))
+#define PHY_val(N,V)        ((U32)(PHY_REG##N##_val_##V))
+#define PHY_get_val(N,F,V)  (V&(PHY_msk(N,F))
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+typedef struct
+{
+    U32     deviceID;           // Device identification
+    char*   manufactureName;    // Pointer to manufacture name
+    char*   deviceName;         // Pointer to device name
+    GERR    (*GD_ETH_PHY_Init)(void);
+    GERR    (*GD_ETH_PHY_Open)(GD_HANDLE handle);
+    GERR    (*GD_ETH_PHY_Close)(GD_HANDLE handle);
+    GERR    (*GD_ETH_PHY_SWReset)(GD_HANDLE handle);
+    GERR    (*GD_ETH_PHY_SetWorkMode)(GD_HANDLE handle, GD_ETH_Work_ModeT Mode);
+    GERR    (*GD_ETH_PHY_GetWorkStatus)(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+    GERR    (*GD_ETH_PHY_GetId)(GD_HANDLE handle, U32 *phy_id);
+
+    GD_ETH_PHY_AddrE    addr;
+    GD_ETH_Work_ModeT   workmode;
+}GD_ETH_PHY_DEVICE_DATA_S;
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+GERR GD_ETH_PHY_Init(U8 phyType);
+GERR GD_ETH_PHY_Open(GD_ETH_PHY_AddrE* paddr, GD_HANDLE* pHandle);
+GERR GD_ETH_PHY_Close(GD_HANDLE* pHandle);
+GERR GD_ETH_PHY_SWReset(GD_HANDLE handle);
+GERR GD_ETH_PHY_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT Mode);
+GERR GD_ETH_PHY_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+GERR GD_ETH_PHY_GetId(GD_HANDLE handle, U32 *phy_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _GD_ETH_PHY_H_ */
+

+ 137 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_ar8032.c

@@ -0,0 +1,137 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_ar8032.c
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include "gtypes.h"
+#include "gd_timer.h"
+#include "gh_gpio.h"
+#include "gd_gpio.h"
+#define PHY_RESET_GPIO_TYPE_OUTPUT  GD_GPIO_TYPE_OUTPUT_0
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_eth_phy_ar8032.h"
+
+#include "gh_eth.h"
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+GERR GD_ETH_PHY_AR8032_Init(void)
+{
+#if 0
+    GBOOL   ret;
+    U32     features;
+    U32     phyRegVal;
+    /* For now, I'll claim that the generic driver supports
+        * all possible port types */
+    features = (SP_TP | SP_MII | SP_AUI | SP_FIBRE | SP_BNC);
+
+    /* Do we support autonegotiation? */
+    ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_BMSR_REG1, &phyRegVal);
+    if (ret != GTRUE)
+        return GD_ERR_ETH_PHY_RW;
+
+    if (phyRegVal & ETH_BMSR_ANEG_CAPABLE)
+        features |= SP_AUTONEG;
+
+    if (phyRegVal & ETH_BMSR_100TX_FULL)
+        features |= SP_100T_FULL;
+    if (phyRegVal & ETH_BMSR_100TX_HALF)
+        features |= SP_100T_HALF;
+    if (phyRegVal & ETH_BMSR_10T_FULL)
+        features |= SP_10T_FULL;
+    if (phyRegVal & ETH_BMSR_10T_HALF)
+        features |= SP_10T_HALF;
+
+    if (phyRegVal & ETH_BMSR_ESTATEN) {
+        ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_EXPS_REG15, &phyRegVal);
+        if (ret != GTRUE) return GD_ERR_ETH_PHY_RW;
+
+        if (phyRegVal & ETH_EXPS_1000_TFULL)
+            features |= SP_1000T_FULL;
+        if (phyRegVal & ETH_EXPS_1000_THALF)
+            features |= SP_1000T_HALF;
+    }
+
+    pPhyDev->supported      = features;
+    pPhyDev->advertising    = features;
+
+    GD_ETH_PHY_ConfigANeg(pPhyDev);
+#endif
+    return GD_OK;
+}
+GERR GD_ETH_PHY_AR8032_Open(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_PHY_AR8032_Close(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_PHY_AR8032_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat)
+{
+    return GD_OK;
+}
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+

+ 82 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_ar8032.h

@@ -0,0 +1,82 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_ar8032.h
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_PHY_AR8032_H_
+#define _GD_ETH_PHY_AR8032_H_
+#include "gtypes.h"
+#include "gd_eth_phy.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ETH_PHY_AR8032_Init(void);
+GERR GD_ETH_PHY_AR8032_Open(GD_HANDLE handle);
+GERR GD_ETH_PHY_AR8032_Close(GD_HANDLE handle);
+GERR GD_ETH_PHY_AR8032_SWReset(GD_HANDLE handle);
+GERR GD_ETH_PHY_AR8032_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+GERR GD_ETH_PHY_AR8032_GetId(GD_HANDLE handle, U32 *phy_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_PHY_AR8032_H_ */
+

+ 271 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_lan8700.c

@@ -0,0 +1,271 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_lan8700.c
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include "gtypes.h"
+#include "gd_timer.h"
+#include "gh_gpio.h"
+#include "gd_gpio.h"
+#define PHY_RESET_GPIO_TYPE_OUTPUT  GD_GPIO_TYPE_OUTPUT_0
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_eth_phy_lan8700.h"
+
+#include "gh_eth.h"
+//#define DEBUG_PRINT
+#ifdef DEBUG_PRINT
+#include <gm_lib/gm_debug.h>
+#endif
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+GERR GD_ETH_PHY_LAN8700_Init(void)
+{
+#if 0
+    GBOOL   ret;
+    U32     features;
+    U32     phyRegVal;
+    /* For now, I'll claim that the generic driver supports
+        * all possible port types */
+    features = (SP_TP | SP_MII | SP_AUI | SP_FIBRE | SP_BNC);
+
+    /* Do we support autonegotiation? */
+    ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_BMSR_REG1, &phyRegVal);
+    if (ret != GTRUE)
+        return GD_ERR_ETH_PHY_RW;
+
+    if (phyRegVal & ETH_BMSR_ANEG_CAPABLE)
+        features |= SP_AUTONEG;
+
+    if (phyRegVal & ETH_BMSR_100TX_FULL)
+        features |= SP_100T_FULL;
+    if (phyRegVal & ETH_BMSR_100TX_HALF)
+        features |= SP_100T_HALF;
+    if (phyRegVal & ETH_BMSR_10T_FULL)
+        features |= SP_10T_FULL;
+    if (phyRegVal & ETH_BMSR_10T_HALF)
+        features |= SP_10T_HALF;
+
+    if (phyRegVal & ETH_BMSR_ESTATEN) {
+        ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_EXPS_REG15, &phyRegVal);
+        if (ret != GTRUE) return GD_ERR_ETH_PHY_RW;
+
+        if (phyRegVal & ETH_EXPS_1000_TFULL)
+            features |= SP_1000T_FULL;
+        if (phyRegVal & ETH_EXPS_1000_THALF)
+            features |= SP_1000T_HALF;
+    }
+
+    pPhyDev->supported      = features;
+    pPhyDev->advertising    = features;
+
+    GD_ETH_PHY_ConfigANeg(pPhyDev);
+#endif
+    return GD_OK;
+}
+GERR GD_ETH_PHY_LAN8700_Open(GD_HANDLE handle)
+{
+    //GD_ETH_PHY_DEVICE_DATA_S* device = (GD_ETH_PHY_DEVICE_DATA_S*)handle;
+    return GD_OK;
+}
+GERR GD_ETH_PHY_LAN8700_Close(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_PHY_LAN8700_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT workmode)
+{
+    /*Set MII mode: reg 18 bit 14---0:MII , 1:RMII*/
+    U8      ii = 0;
+    GBOOL   retval = GFALSE;
+    U32     regval = (U32)0;
+    GD_ETH_PHY_DEVICE_DATA_S* device = (GD_ETH_PHY_DEVICE_DATA_S*)handle;
+    U8      addr = (U8)device->addr;
+    // workmode.mode
+    while(1)
+    {
+        regval = 0;
+        retval = GD_ETH_ReadPhy(addr, PHY_addr(18,SCSR), &regval);
+        if ( retval != GTRUE )
+        {
+#ifdef DEBUG_PRINT
+            GM_Printf("%s:Failed to read PHY Reg_%d!\n",__FUNCTION__, PHY_addr(18,SCSR));
+#endif
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        if(workmode.mode == GD_ETH_PHY_IF_MODE_RMII)
+        {
+            /*RMII mode*/
+            if((regval & PHY_mask(18,RPHY_MODE)) == PHY_val(18,RPHY_RMII))//MII mode: bit 10---0:MII , 1:RMII
+            {
+#ifdef DEBUG_PRINT
+                GM_Printf("Rmii mode set OK!\n");
+#endif
+                break;
+            }
+
+            regval &= (~PHY_mask(18,RPHY_MODE));
+            regval |= PHY_val(18,RPHY_RMII);
+        }
+        else if(workmode.mode == GD_ETH_PHY_IF_MODE_MII)
+        {
+            /*MII mode*/
+            if((regval & PHY_mask(18,RPHY_MODE)) == PHY_val(18,RPHY_MII))//MII mode: bit 10---0:MII , 1:RMII
+            {
+#ifdef DEBUG_PRINT
+                GM_Printf("mii mode set OK!\n");
+#endif
+                break;
+            }
+
+            regval &= (~PHY_mask(18,RPHY_MODE));
+            regval |= PHY_val(18,RPHY_MII);
+        }
+        else
+        {
+            return GD_ERR_ETH_NOT_SUPPORTED;
+        }
+
+        retval = GD_ETH_WritePhy(addr, PHY_addr(18,SCSR), regval);
+        if ( retval != GTRUE )
+        {
+#ifdef DEBUG_PRINT
+            GM_Printf("%s:Failed to write PHY Reg_%d!\n",__FUNCTION__, PHY_addr(18,SCSR));
+#endif
+            return GD_ERR_ETH_PHY_RW;
+        }
+
+        ii++;
+        if(ii >= 10)
+        {
+            //GM_Printf("%s mode set failure!\n", phy_str_for_if(pPhyDev->phyPort));
+            return GD_ERR_ETH_PHY_OTHER;
+        }
+    }
+
+
+    regval = (U32)0;
+    /* loopback setting */
+    // workmode.loopback
+    regval &= (~PHY_mask(0,LOOPBACK));
+    if (workmode.loopback == GD_ETH_LOOP_ON_PHY )
+    {
+        regval |= PHY_val(0,LOOPBACK);
+    }
+
+        /* auto nego */
+    // workmode.bEnAutoNeg
+    regval &= (~PHY_mask(0,AN_ENABLE));
+    if (workmode.bEnAutoNeg == GTRUE)
+    {
+        regval |= PHY_val(0,AUTO_NEGO);
+    }
+    else
+    {
+        /* speed */
+        // workmode.speed
+        regval &= (~PHY_mask(0,SPEEDSELECT));
+        if (workmode.speed == GD_ETH_SPEED_100M )   /* 100M */
+        {
+            regval |= PHY_val(0,100M);
+        }
+        else if (workmode.speed == GD_ETH_SPEED_10M )/* 10M */
+        {
+            regval |= PHY_val(0,10M);    //nothing need to do.
+        }
+        else
+        {
+            return GD_ERR_ETH_NOT_SUPPORTED;
+        }
+
+        /* duplex */
+        // workmode.duplex
+        regval &= (~PHY_mask(0,DUPLEX_MODE));
+        if(workmode.duplex == GD_ETH_FULL_DUPLEX)   /* Full Duplex */
+        {
+            regval |= PHY_val(0,DUPLEX_FULL);
+        }
+        else if(workmode.duplex == GD_ETH_HALF_DUPLEX) /* half */
+        {
+            regval |= PHY_val(0,DUPLEX_HALF);    //nothing need to do.
+        }
+        else
+        {
+            return GD_ERR_ETH_NOT_SUPPORTED;
+        }
+    }
+    /* write settings */
+    retval = GD_ETH_WritePhy(addr, PHY_addr(0,BMCR), regval);
+    if ( retval != GTRUE )
+        return GD_ERR_ETH_PHY_RW;
+    return GD_OK;
+}
+GERR GD_ETH_PHY_LAN8700_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat)
+{
+    return GD_OK;
+}
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+

+ 83 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_lan8700.h

@@ -0,0 +1,83 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_lan8700.h
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_PHY_LAN8700_H_
+#define _GD_ETH_PHY_LAN8700_H_
+#include "gtypes.h"
+#include "gd_eth_phy.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ETH_PHY_LAN8700_Init(void);
+GERR GD_ETH_PHY_LAN8700_Open(GD_HANDLE handle);
+GERR GD_ETH_PHY_LAN8700_Close(GD_HANDLE handle);
+GERR GD_ETH_PHY_LAN8700_SWReset(GD_HANDLE handle);
+GERR GD_ETH_PHY_LAN8700_SetWorkMode(GD_HANDLE handle, GD_ETH_Work_ModeT workmode);
+GERR GD_ETH_PHY_LAN8700_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+GERR GD_ETH_PHY_LAN8700_GetId(GD_HANDLE handle, U32 *phy_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_PHY_LAN8700_H_ */
+

+ 568 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_reg.h

@@ -0,0 +1,568 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_reg.h
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_PHY_REG_H_
+#define _GD_ETH_PHY_REG_H_
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+/* ------------------------------------------------------------------------- */
+/*  Register 00 Basic Mode Control Register                                  */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG0_BMCR                (0x00)
+
+#define PHY_REG0_sft_RESET           (15)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_LOOPBACK        (14)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_SPEEDSELECT     (13)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_AN_ENABLE       (12)  /*1bit*/    /* read/write 1 */
+#define PHY_REG0_sft_POWER_DOWN      (11)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_ISOLATE         (10)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_RESTART_AN      ( 9)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_DUPLEX_MODE     ( 8)  /*1bit*/    /* read/write 0 */
+#define PHY_REG0_sft_COLLISION_TEST  ( 7)  /*1bit*/    /* read/write 0 */   /* Collision test */
+#define ETH_BMCR_sft_SPEED1000       ( 6)  /*1bit*/    /* read/write 0 */   /* MSB of Speed (1000) */
+
+#define PHY_REG0_bit_RESET           (1)
+#define PHY_REG0_bit_LOOPBACK        (1)
+#define PHY_REG0_bit_SPEEDSELECT     (1)
+#define PHY_REG0_bit_AN_ENABLE       (1)
+#define PHY_REG0_bit_POWER_DOWN      (1)
+#define PHY_REG0_bit_ISOLATE         (1)
+#define PHY_REG0_bit_RESTART_AN      (1)
+#define PHY_REG0_bit_DUPLEX_MODE     (1)
+#define PHY_REG0_bit_COLLISION_TEST  (1)
+#define PHY_REG0_bit_SPEED1000       (1)
+
+#define PHY_REG0_val_RESET           ((1) << PHY_REG0_sft_RESET          )
+#define PHY_REG0_val_LOOPBACK        ((1) << PHY_REG0_sft_LOOPBACK       )
+#define PHY_REG0_val_100M            ((1) << PHY_REG0_sft_SPEEDSELECT    )
+#define PHY_REG0_val_10M             ((0) << PHY_REG0_sft_SPEEDSELECT    )
+#define PHY_REG0_val_AUTO_NEGO       ((1) << PHY_REG0_sft_AN_ENABLE      )
+#define PHY_REG0_val_POWER_DOWN      ((1) << PHY_REG0_sft_POWER_DOWN     )
+#define PHY_REG0_val_POWER_ON        ((0) << PHY_REG0_sft_POWER_DOWN     )
+#define PHY_REG0_val_ISOLATE         ((1) << PHY_REG0_sft_ISOLATE        )
+#define PHY_REG0_val_RESTART_AUTONEG ((1) << PHY_REG0_sft_RESTART_AN     )
+#define PHY_REG0_val_DUPLEX_FULL     ((1) << PHY_REG0_sft_DUPLEX_MODE    )
+#define PHY_REG0_val_DUPLEX_HALF     ((0) << PHY_REG0_sft_DUPLEX_MODE    )
+#define PHY_REG0_val_COLLISION_TEST  ((1) << PHY_REG0_sft_COLLISION_TEST )
+#define PHY_REG0_val_SPEED1000       ((1) << ETH_BMCR_sft_SPEED1000      )
+
+/* ------------------------------------------------------------------------- */
+/*  Register 01 Basic Mode Status Register (RO)                              */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG1_BMSR                (0x01)
+
+#define PHY_REG1_sft_100T4           (15)  /*1bit*/    /* read 0 */
+#define PHY_REG1_sft_100TX_FULL      (14)  /*1bit*/    /* read 1 */
+#define PHY_REG1_sft_100TX_HALF      (13)  /*1bit*/    /* read 1 */
+#define PHY_REG1_sft_10_FULL         (12)  /*1bit*/    /* read 1 */
+#define PHY_REG1_sft_10_HALF         (11)  /*1bit*/    /* read 1 */
+#define PHY_REG1_sft_100_FULL2       (10)  /*1bit*/    /* read 1 */     /* Can do 100BASE-T2 FDX */
+#define PHY_REG1_sft_100_HALF2       ( 9)  /*1bit*/    /* read 1 */     /* Can do 100BASE-T2 HDX */
+#define PHY_REG1_sft_ESTATEN         ( 8)  /*1bit*/    /* read 1 */     /* Extended Status in R15 */
+#define PHY_REG1_sft_PRE_SUPPRESSION ( 6)  /*1bit*/    /* read 1 */
+#define PHY_REG1_sft_AN_COMPLETE     ( 5)  /*1bit*/    /* read 0 */
+#define PHY_REG1_sft_REMOTE_FAULT    ( 4)  /*1bit*/    /* read 0 */
+#define PHY_REG1_sft_AN_ABILITY      ( 3)  /*1bit*/    /* read 0 */    /* Able to do auto-negotiation */
+#define PHY_REG1_sft_LINK_STAT       ( 2)  /*1bit*/    /* read 0 */
+#define PHY_REG1_sft_EXT_CAPABLE     ( 1)  /*1bit*/    /* read 0 */
+#define PHY_REG1_sft_JABBER_DETECT   ( 1)  /*1bit*/    /* read 0 */     /* Jabber detected */
+#define PHY_REG1_sft_ERCAP           ( 0)  /*1bit*/    /* read 0 */     /* Ext-reg capability */
+
+#define PHY_REG1_bit_100T4           (1)
+#define PHY_REG1_bit_100TX_FULL      (1)
+#define PHY_REG1_bit_100TX_HALF      (1)
+#define PHY_REG1_bit_10_FULL         (1)
+#define PHY_REG1_bit_10_HALF         (1)
+#define PHY_REG1_bit_PRE_SUPPRESSION (1)
+#define PHY_REG1_bit_AN_COMPLETE     (1)
+#define PHY_REG1_bit_REMOTE_FAULT    (1)
+#define PHY_REG1_bit_AN_ABILITY      (1)
+#define PHY_REG1_bit_LINK_STAT       (1)
+#define PHY_REG1_bit_EXT_CAPABLE     (1)
+#define PHY_REG1_bit_JABBER_DETECT   (1)
+
+#define PHY_REG1_val_100T4           ((1) << PHY_REG1_sft_100T4          )
+#define PHY_REG1_val_100TX_FULL      ((1) << PHY_REG1_sft_100TX_FULL     )
+#define PHY_REG1_val_100TX_HALF      ((1) << PHY_REG1_sft_100TX_HALF     )
+#define PHY_REG1_val_10_FULL         ((1) << PHY_REG1_sft_10_FULL        )
+#define PHY_REG1_val_10_HALF         ((1) << PHY_REG1_sft_10_HALF        )
+#define PHY_REG1_val_100_FULL2       ((1) << PHY_REG1_sft_100_FULL2      )
+#define PHY_REG1_val_100_HALF2       ((1) << PHY_REG1_sft_100_HALF2      )
+#define PHY_REG1_val_ESTATEN         ((1) << PHY_REG1_sft_ESTATEN        )
+#define PHY_REG1_val_PRE_SUPPRESSION ((1) << PHY_REG1_sft_PRE_SUPPRESSION)
+#define PHY_REG1_val_AN_COMPLETE     ((1) << PHY_REG1_sft_AN_COMPLETE    )
+#define PHY_REG1_val_REMOTE_FAULT    ((1) << PHY_REG1_sft_REMOTE_FAULT   )
+#define PHY_REG1_val_AN_ABILITY      ((1) << PHY_REG1_sft_AN_ABILITY     )
+#define PHY_REG1_val_LINK_STAT       ((1) << PHY_REG1_sft_LINK_STAT      )
+#define PHY_REG1_val_EXT_CAPABLE     ((1) << PHY_REG1_sft_EXT_CAPABLE    )
+#define PHY_REG1_val_JABBER_DETECT   ((0) << PHY_REG1_sft_JABBER_DETECT  )
+#define PHY_REG1_val_ERCAP           ((1) << PHY_REG1_sft_ERCAP          )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 02 PHY Identifier Register 1 - PHY_REG1_ID_MSB                  */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG2_ID1                 (0x02)
+// ID_BIT[18:3]/* Mask for PHY_REG2_ID_MSB */
+
+#define PHY_REG2_sft_OUTI_MSB        (0)  /*16bit*/    /* read 0x001C */
+
+#define PHY_REG2_bit_OUTI_MSB        (0xFFFF)
+
+#define PHY_REG2_val_OUTI_MSB        ((0x001C) << PHY_REG2_sft_OUTI_MSB)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 03 PHY Identifier Register 2 - PHY_REG3_ID_LSB                  */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG3_ID2                 (0x03)
+// ID_BIT[24:19]/* Mask for PHY_REG2_ID_LSB */
+
+#define PHY_REG3_sft_OUTI_LSB        (10)  /*6bit*/    /* read 110010 */
+#define PHY_REG3_sft_OUTI_MOD        (4)   /*6bit*/    /* read 000001 */
+#define PHY_REG3_sft_OUTI_REV        (0)   /*4bit*/    /* read 0101 */
+
+#define PHY_REG3_bit_OUTI_LSB        (0x3F)
+#define PHY_REG3_bit_OUTI_MOD        (0x3F)
+#define PHY_REG3_bit_OUTI_REV        (0x0F)
+
+#define PHY_REG3_val_OUTI_LSB        ((0xC8) << PHY_REG3_sft_OUTI_LSB)
+#define PHY_REG3_val_OUTI_MOD        ((1)    << PHY_REG3_sft_OUTI_MOD)
+#define PHY_REG3_val_OUTI_REV        ((5)    << PHY_REG3_sft_OUTI_REV)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 04 Auto-Negotiation Advertisement Register(ANAR)                */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG4_ANAR                (0x04)
+
+#define PHY_REG4_sft_ANG_NP          (15)  /*1bit*/    /* read 0 */             /* NP */
+#define PHY_REG4_sft_ANG_ACK         (14)  /*1bit*/    /* read 0 */             /* ACK */
+#define PHY_REG4_sft_ANG_RF          (13)  /*1bit*/    /* read/write 0 */       /* RF */
+#define PHY_REG4_sft_ANG_TXFC        (11)  /*1bit*/    /* read 0 */             /* Try for asymetric pause */
+#define PHY_REG4_sft_ANG_RXFC        (10)  /*1bit*/    /* read/write 0 */       /* Try for pause */ /* RXFC */
+#define PHY_REG4_sft_ANG_100T4       (9)   /*1bit*/    /* read 0 */             /* T4 *//* Try for 100mbps 4k packets */
+#define PHY_REG4_sft_ANG_100TXFD     (8)   /*1bit*/    /* read/write 1 */       /* TXFD */
+#define PHY_REG4_sft_ANG_100TX       (7)   /*1bit*/    /* read/write 1 */       /* TX */
+#define PHY_REG4_sft_ANG_10FD        (6)   /*1bit*/    /* read/write 1 */       /* 10FD */
+#define PHY_REG4_sft_ANG_10T         (5)   /*1bit*/    /* read/write 1 */       /* 10 */
+#define PHY_REG4_sft_ANG_SELECTOR    (0)   /*5bit*/    /* read/write 00001 */   /* Only selector supported */
+
+#define PHY_REG4_bit_ANG_NP          (1)
+#define PHY_REG4_bit_ANG_ACK         (1)
+#define PHY_REG4_bit_ANG_RF          (1)
+#define PHY_REG4_bit_ANG_TXFC        (1)
+#define PHY_REG4_bit_ANG_RXFC        (1)
+#define PHY_REG4_bit_ANG_100T4       (1)
+#define PHY_REG4_bit_ANG_100TXFD     (1)
+#define PHY_REG4_bit_ANG_100TX       (1)
+#define PHY_REG4_bit_ANG_10FD        (1)
+#define PHY_REG4_bit_ANG_10T         (1)
+#define PHY_REG4_bit_ANG_SELECTOR    (0x1F)
+
+#define PHY_REG4_val_ANG_NP          ((1)    << PHY_REG4_sft_ANG_NP      )
+#define PHY_REG4_val_ANG_ACK         ((1)    << PHY_REG4_sft_ANG_ACK     )
+#define PHY_REG4_val_ANG_RF          ((1)    << PHY_REG4_sft_ANG_RF      )
+#define PHY_REG4_val_ANG_TXFC        ((1)    << PHY_REG4_sft_ANG_TXFC    )
+#define PHY_REG4_val_ANG_RXFC        ((1)    << PHY_REG4_sft_ANG_RXFC    )
+#define PHY_REG4_val_ANG_100T4       ((1)    << PHY_REG4_sft_ANG_100T4   )
+#define PHY_REG4_val_ANG_100TXFD     ((1)    << PHY_REG4_sft_ANG_100TXFD )
+#define PHY_REG4_val_ANG_100TX       ((1)    << PHY_REG4_sft_ANG_100TX   )
+#define PHY_REG4_val_ANG_10FD        ((1)    << PHY_REG4_sft_ANG_10FD    )
+#define PHY_REG4_val_ANG_10T         ((1)    << PHY_REG4_sft_ANG_10T     )
+#define PHY_REG4_val_ANG_SELECTOR    ((0x1F) << PHY_REG4_sft_ANG_SELECTOR)
+#define PHY_REG4_val_ANG_CSMA        ((1)    << PHY_REG4_sft_ANG_SELECTOR)
+#define PHY_REG4_val_ANG_ALL         (PHY_REG4_val_ANG_100TXFD|PHY_REG4_val_ANG_10FD|PHY_REG4_val_ANG_CSMA)
+#define PHY_REG4_val_ANG_FULL        (PHY_REG4_val_ANG_10T|PHY_REG4_val_ANG_10FD|PHY_REG4_val_ANG_100TX|PHY_REG4_val_ANG_100TXFD)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 05 Auto-Negotiation Link Partner Ability Register(ANLPAR)       */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG5_ANLPAR              (0x05)
+
+#define PHY_REG5_sft_LPA_NP          (15)  /*1bit*/    /* read 0 */             /* Next page bit               */
+#define PHY_REG5_sft_LPA_ACK         (14)  /*1bit*/    /* read 0 */             /* Link partner acked us       */
+#define PHY_REG5_sft_LPA_RF          (13)  /*1bit*/    /* read 0 */             /* Link partner faulted        */
+#define PHY_REG5_sft_LPA_TXFC        (11)  /*1bit*/    /* read 0 */             /* TX Flow Control Can pause asymetrically     */
+#define PHY_REG5_sft_LPA_RXFC        (10)  /*1bit*/    /* read 0 */             /* RX Flow Control Can pause               */
+#define PHY_REG5_sft_LPA_100T4       (9)   /*1bit*/    /* read 0 */             /* Can do 100mbps 4k packets   */
+#define PHY_REG5_sft_LPA_1000XP_ASYM (8)   /*1bit*/    /* read 0 */             /* Can do 1000BASE-X pause asym*/
+#define PHY_REG5_sft_LPA_100TXFD     (8)   /*1bit*/    /* read 0 */             /* Can do 100mbps full-duplex*/
+#define PHY_REG5_sft_LPA_100TX       (7)   /*1bit*/    /* read 0 */             /* Can do 100mbps half-duplex     */
+#define PHY_REG5_sft_LPA_1000XHD     (6)   /*1bit*/    /* read 0 */             /* Can do 1000BASE-X half-duplex */
+#define PHY_REG5_sft_LPA_10FD        (6)   /*1bit*/    /* read 0 */             /* Can do 10mbps full-duplex   */
+#define PHY_REG5_sft_LPA_1000XFD     (5)   /*1bit*/    /* read 0 */             /* Can do 1000BASE-X full-duplex */
+#define PHY_REG5_sft_LPA_10T         (5)   /*1bit*/    /* read 0 */             /* Can do 10mbps half-duplex   */
+#define PHY_REG5_sft_LPA_SELECTOR    (0)   /*5bit*/    /* read/write 00000 */   /* Only selector supported     */
+
+#define PHY_REG5_bit_LPA_NP          (1)
+#define PHY_REG5_bit_LPA_ACK         (1)
+#define PHY_REG5_bit_LPA_RF          (1)
+#define PHY_REG5_bit_LPA_TXFC        (1)
+#define PHY_REG5_bit_LPA_RXFC        (1)
+#define PHY_REG5_bit_LPA_100T4       (1)
+#define PHY_REG5_bit_LPA_100TXFD     (1)
+#define PHY_REG5_bit_LPA_100TX       (1)
+#define PHY_REG5_bit_LPA_10FD        (1)
+#define PHY_REG5_bit_LPA_10T         (1)
+#define PHY_REG5_bit_LPA_SELECTOR    (0x1F)
+
+#define PHY_REG5_val_LPA_NP          ((1)    << PHY_REG5_sft_LPA_NP      )
+#define PHY_REG5_val_LPA_ACK         ((1)    << PHY_REG5_sft_LPA_ACK     )
+#define PHY_REG5_val_LPA_RF          ((1)    << PHY_REG5_sft_LPA_RF      )
+#define PHY_REG5_val_LPA_TXFC        ((1)    << PHY_REG5_sft_LPA_TXFC    )
+#define PHY_REG5_val_LPA_RXFC        ((1)    << PHY_REG5_sft_LPA_RXFC    )
+#define PHY_REG5_val_LPA_100T4       ((1)    << PHY_REG5_sft_LPA_100T4   )
+#define PHY_REG5_val_LPA_100TXFD     ((1)    << PHY_REG5_sft_LPA_100TXFD )
+#define PHY_REG5_val_LPA_100TX       ((1)    << PHY_REG5_sft_LPA_100TX   )
+#define PHY_REG5_val_LPA_10FD        ((1)    << PHY_REG5_sft_LPA_10FD    )
+#define PHY_REG5_val_LPA_10T         ((1)    << PHY_REG5_sft_LPA_10T     )
+#define PHY_REG5_val_LPA_SELECTOR    ((0x1F) << PHY_REG5_sft_LPA_SELECTOR)
+#define PHY_REG5_val_LPA_CSMA        ((1)    << PHY_REG5_sft_LPA_SELECTOR)
+#define PHY_REG5_val_ANLPAR_DUPLEX   (PHY_REG5_val_LPA_10FD|PHY_REG5_val_LPA_100TXFD)
+#define PHY_REG5_val_ANLPAR_100      (PHY_REG5_val_LPA_100TX|PHY_REG5_val_LPA_100TXFD|PHY_REG5_val_LPA_100T4)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 06 Auto-Negotiation Expansion Register(ANER)                    */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG6_ANER                (0x06)
+
+#define PHY_REG6_sft_ANE_MLF         (4)  /*1bit*/    /* read 0 */  /* Multiple link faults detected    */
+#define PHY_REG6_sft_ANE_LP_NP_ABLE  (3)  /*1bit*/    /* read 0 */  /* Link partner supports npage */
+#define PHY_REG6_sft_ANE_NP_ABL      (2)  /*1bit*/    /* read 0 */  /* This enables npage words    */
+#define PHY_REG6_sft_ANE_PAGE_RX     (1)  /*1bit*/    /* read 0 */  /* Got new RX page code word   */
+#define PHY_REG6_sft_ANE_LP_NW_ABL   (0)  /*1bit*/    /* read 0 */  /* Can do N-way auto-nego      */
+
+#define PHY_REG6_bit_ANE_MLF         (1)
+#define PHY_REG6_bit_ANE_LP_NP_ABLE  (1)
+#define PHY_REG6_bit_ANE_NP_ABL      (1)
+#define PHY_REG6_bit_ANE_PAGE_RX     (1)
+#define PHY_REG6_bit_ANE_LP_NW_ABL   (1)
+
+#define PHY_REG6_val_ANE_MLF         ((1) << PHY_REG6_sft_ANE_MLF       )
+#define PHY_REG6_val_ANE_LP_NP_ABLE  ((1) << PHY_REG6_sft_ANE_LP_NP_ABLE)
+#define PHY_REG6_val_ANE_NP_ABL      ((1) << PHY_REG6_sft_ANE_NP_ABL    )
+#define PHY_REG6_val_ANE_PAGE_RX     ((1) << PHY_REG6_sft_ANE_PAGE_RX   )
+#define PHY_REG6_val_ANE_LP_NW_ABL   ((1) << PHY_REG6_sft_ANE_LP_NW_ABL )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 16 NWay Setup Register(NSR)                                     */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG16_NSR                (0x10)
+
+#define PHY_REG16_sft_NSR_TESTFUN    (10)  /*1bit*/    /* read/write 0 */
+#define PHY_REG16_sft_NSR_NWLPBK     (9)   /*1bit*/    /* read/write 0 */
+#define PHY_REG16_sft_NSR_FLAGABD    (2)   /*1bit*/    /* read 0 */
+#define PHY_REG16_sft_NSR_FLAGFDF    (1)   /*1bit*/    /* read 0 */
+#define PHY_REG16_sft_NSR_FLAGLSC    (0)   /*1bit*/    /* read 0 */
+
+#define PHY_REG16_bit_NSR_TESTFUN    (1)
+#define PHY_REG16_bit_NSR_NWLPBK     (1)
+#define PHY_REG16_bit_NSR_FLAGABD    (1)
+#define PHY_REG16_bit_NSR_FLAGFDF    (1)
+#define PHY_REG16_bit_NSR_FLAGLSC    (1)
+
+#define PHY_REG16_val_NSR_TESTFUN    ((1) << PHY_REG16_sft_NSR_TESTFUN)
+#define PHY_REG16_val_NSR_NWLPBK     ((1) << PHY_REG16_sft_NSR_NWLPBK )
+#define PHY_REG16_val_NSR_FLAGABD    ((1) << PHY_REG16_sft_NSR_FLAGABD)
+#define PHY_REG16_val_NSR_FLAGFDF    ((1) << PHY_REG16_sft_NSR_FLAGFDF)
+#define PHY_REG16_val_NSR_FLAGLSC    ((1) << PHY_REG16_sft_NSR_FLAGLSC)
+#define PHY_REG16_val_NSR_RESV       (0xF800)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 17 Loopback, Bypass, Receiver Error Mask Register(LBREMR)       */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG17_LBREMR             (0x11)
+
+#define PHY_REG17_sft_EMR_RPTR       (15)  /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_BP_4B5B    (14)  /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_BP_SCR     (13)  /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_LPDS       (12)  /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_ANALOGOFF  (11)  /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_BMODE_EN   (10)  /*1bit*/    /* read/write 1 */
+#define PHY_REG17_sft_EMR_DIGILBK    (9)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_FLINK_10   (8)   /*1bit*/    /* read/write 1 */
+#define PHY_REG17_sft_EMR_FLINK_100  (7)   /*1bit*/    /* read/write 1 */
+#define PHY_REG17_sft_EMR_JBEN       (6)   /*1bit*/    /* read/write 1 */
+#define PHY_REG17_sft_EMR_CODE_ERR   (5)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_PME_ERR    (4)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_LINK_ERR   (3)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_PKT_ERR    (2)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_FXMODE     (1)   /*1bit*/    /* read/write 0 */
+#define PHY_REG17_sft_EMR_SNIMODE    (0)   /*1bit*/    /* read/write 0 */
+
+#define PHY_REG17_bit_EMR_RPTR       (1)
+#define PHY_REG17_bit_EMR_BP_4B5B    (1)
+#define PHY_REG17_bit_EMR_BP_SCR     (1)
+#define PHY_REG17_bit_EMR_LPDS       (1)
+#define PHY_REG17_bit_EMR_ANALOGOFF  (1)
+#define PHY_REG17_bit_EMR_BMODE_EN   (1)
+#define PHY_REG17_bit_EMR_DIGILBK    (1)
+#define PHY_REG17_bit_EMR_FLINK_10   (1)
+#define PHY_REG17_bit_EMR_FLINK_100  (1)
+#define PHY_REG17_bit_EMR_JBEN       (1)
+#define PHY_REG17_bit_EMR_CODE_ERR   (1)
+#define PHY_REG17_bit_EMR_PME_ERR    (1)
+#define PHY_REG17_bit_EMR_LINK_ERR   (1)
+#define PHY_REG17_bit_EMR_PKT_ERR    (1)
+#define PHY_REG17_bit_EMR_FXMODE     (1)
+#define PHY_REG17_bit_EMR_SNIMODE    (1)
+
+#define PHY_REG17_val_EMR_RPTR       ((1) << PHY_REG17_sft_EMR_RPTR     )
+#define PHY_REG17_val_EMR_BP_4B5B    ((1) << PHY_REG17_sft_EMR_BP_4B5B  )
+#define PHY_REG17_val_EMR_BP_SCR     ((1) << PHY_REG17_sft_EMR_BP_SCR   )
+#define PHY_REG17_val_EMR_LPDS       ((1) << PHY_REG17_sft_EMR_LPDS     )
+#define PHY_REG17_val_EMR_ANALOGOFF  ((1) << PHY_REG17_sft_EMR_ANALOGOFF)
+#define PHY_REG17_val_EMR_BMODE_EN   ((1) << PHY_REG17_sft_EMR_BMODE_EN )
+#define PHY_REG17_val_EMR_DIGILBK    ((1) << PHY_REG17_sft_EMR_DIGILBK  )
+#define PHY_REG17_val_EMR_FLINK_10   ((1) << PHY_REG17_sft_EMR_FLINK_10 )
+#define PHY_REG17_val_EMR_FLINK_100  ((1) << PHY_REG17_sft_EMR_FLINK_100)
+#define PHY_REG17_val_EMR_JBEN       ((1) << PHY_REG17_sft_EMR_JBEN     )
+#define PHY_REG17_val_EMR_CODE_ERR   ((1) << PHY_REG17_sft_EMR_CODE_ERR )
+#define PHY_REG17_val_EMR_PME_ERR    ((1) << PHY_REG17_sft_EMR_PME_ERR  )
+#define PHY_REG17_val_EMR_LINK_ERR   ((1) << PHY_REG17_sft_EMR_LINK_ERR )
+#define PHY_REG17_val_EMR_PKT_ERR    ((1) << PHY_REG17_sft_EMR_PKT_ERR  )
+#define PHY_REG17_val_EMR_FXMODE     ((1) << PHY_REG17_sft_EMR_FXMODE   )
+#define PHY_REG17_val_EMR_SNIMODE    ((1) << PHY_REG17_sft_EMR_SNIMODE  )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 18 PHY Special Control/Status Register || RX_ER Counter(REC)    */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG18_SCSR               (0x12)
+
+// ip101/lan8700
+#define PHY_REG18_sft_RPHY_MODE      (14)  /*1bit*/    /* read/write 0 */
+// ip101
+#define PHY_REG18_sft_RES_SPEED      (14)  /*1bit*/    /* read/write 0 */
+#define PHY_REG18_sft_RES_DUPLEX     (13)  /*1bit*/    /* read/write 0 */
+#define PHY_REG18_sft_RES_AN_DONE    (11)  /*1bit*/    /* read/write 0 */
+#define PHY_REG18_sft_EMR_LPDS       (10)  /*1bit*/    /* read/write 0 */
+// rtl8200
+#define PHY_REG18_sft_RXERCNT        (0)   /*16bit*/   /* read/write 0 */
+
+// ip101/lan8700
+#define PHY_REG18_bit_RPHY_MODE      (1)
+// ip101
+#define PHY_REG18_bit_RES_SPEED      (1)
+#define PHY_REG18_bit_RES_DUPLEX     (1)
+#define PHY_REG18_bit_RES_AN_DONE    (1)
+#define PHY_REG18_bit_EMR_LPDS       (1)
+// rtl8200
+#define PHY_REG18_bit_RXERCNT        (0xFFFF)
+
+// ip101/lan8700
+#define PHY_REG18_val_RPHY_RMII      ((1)      << PHY_REG18_sft_RPHY_MODE  )
+#define PHY_REG18_val_RPHY_MII       ((0)      << PHY_REG18_sft_RPHY_MODE  )
+// ip101
+#define PHY_REG18_val_RES_SPEED      ((1)      << PHY_REG18_sft_RES_SPEED  )
+#define PHY_REG18_val_RES_DUPLEX     ((1)      << PHY_REG18_sft_RES_DUPLEX )
+#define PHY_REG18_val_RES_AN_DONE    ((1)      << PHY_REG18_sft_RES_AN_DONE)
+#define PHY_REG18_val_EMR_LPDS       ((1)      << PHY_REG18_sft_EMR_LPDS   )
+// rtl8200
+#define PHY_REG18_val_RXERCNT        ((0xFFFF) << PHY_REG18_sft_RXERCNT    )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 19 SNR Display Register                                         */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG19_SNR                (0x13)
+
+// rtl8200
+#define PHY_REG19_sft_SNR_0          (0)   /*4bit*/    /* read/write 0 */   /* Signal to Noise Ratio Value */
+
+// rtl8200
+#define PHY_REG19_bit_SNR_0          (0x0F)
+
+// rtl8200
+#define PHY_REG19_val_SNR_0          ((0x0F) << PHY_REG19_sft_SNR_0)
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 25 Test Register                                                */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG25_TESTR              (0x19)
+
+#define PHY_REG25_sft_PACKET_TYPE    (14)  /*1bit*/
+#define PHY_REG25_sft_RPHY_RXD_TRIG  (13)  /*1bit*/
+#define PHY_REG25_sft_RPHY_CLKIN     (11)  /*1bit*/
+#define PHY_REG25_sft_RPHY_MODE      (10)  /*1bit*/
+#define PHY_REG25_sft_RPHY_CRS_SEL   (9)   /*1bit*/
+#define PHY_REG25_sft_PHY_AD         (8)   /*2bit*/
+#define PHY_REG25_sft_LINK_10        (1)   /*1bit*/     /* 10T Link Established */
+#define PHY_REG25_sft_LINK_100       (0)   /*1bit*/     /* 100FX/TX Link Established */
+
+#define PHY_REG25_bit_PACKET_TYPE    (1)
+#define PHY_REG25_bit_RPHY_RXD_TRIG  (1)
+#define PHY_REG25_bit_RPHY_CLKIN     (1)
+#define PHY_REG25_bit_RPHY_MODE      (1)
+#define PHY_REG25_bit_RPHY_CRS_SEL   (1)
+#define PHY_REG25_bit_PHY_AD         (3)
+#define PHY_REG25_bit_LINK_10        (1)
+#define PHY_REG25_bit_LINK_100       (1)
+
+#define PHY_REG25_val_PACKET_TYPE    ((1) << PHY_REG25_sft_PACKET_TYPE  )
+#define PHY_REG25_val_RPHY_RXD_RISE  ((1) << PHY_REG25_sft_RPHY_RXD_TRIG)
+#define PHY_REG25_val_RPHY_RXD_FALL  ((0) << PHY_REG25_sft_RPHY_RXD_TRIG)
+#define PHY_REG25_val_RPHY_CLKIN     ((1) << PHY_REG25_sft_RPHY_CLKIN   )
+#define PHY_REG25_val_RPHY_CLKOUT    ((0) << PHY_REG25_sft_RPHY_CLKIN   )
+#define PHY_REG25_val_RPHY_RMII      ((1) << PHY_REG25_sft_RPHY_MODE    )
+#define PHY_REG25_val_RPHY_MII       ((0) << PHY_REG25_sft_RPHY_MODE    )
+#define PHY_REG25_val_RPHY_CRS_SEL   ((1) << PHY_REG25_sft_RPHY_CRS_SEL )
+#define PHY_REG25_val_PHY_AD         ((1) << PHY_REG25_sft_PHY_AD       )
+#define PHY_REG25_val_LINK_10        ((1) << PHY_REG25_sft_LINK_10      )
+#define PHY_REG25_val_LINK_100       ((1) << PHY_REG25_sft_LINK_100     )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Register 31 PHY Special Control/Status                                   */
+/*  ip101    lan8700    rtl8200                                              */
+/*   YES       YES        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_REG31_SCSR               (0x1F)
+
+#define PHY_REG31_sft_AN_DONE        (12)  /*1bit*/
+#define PHY_REG31_sft_GPO            (7)   /*2bit*/
+#define PHY_REG31_sft_EN_4B5B        (6)   /*1bit*/
+#define PHY_REG31_sft_SPEED          (2)   /*3bit*/
+#define PHY_REG31_sft_DIS_SCRBL      (0)   /*1bit*/
+// rtl8200
+#define PHY_REG31_sft_PAGE_SEL       (0)   /*2bit*/
+
+
+#define PHY_REG31_bit_AN_DONE        (1)
+#define PHY_REG31_bit_GPO            (3)
+#define PHY_REG31_bit_EN_4B5B        (1)
+#define PHY_REG31_bit_SPEED          (7)
+#define PHY_REG31_bit_DIS_SCRBL      (1)
+// rtl8200
+#define PHY_REG31_bit_PAGE_SEL       (3)
+
+#define PHY_REG31_val_AN_DONE        ((1) << PHY_REG31_sft_AN_DONE  )
+#define PHY_REG31_val_GPO            ((1) << PHY_REG31_sft_GPO      )
+#define PHY_REG31_val_EN_4B5B        ((1) << PHY_REG31_sft_EN_4B5B  )
+#define PHY_REG31_val_10M_HALF       ((1) << PHY_REG31_sft_SPEED    )
+#define PHY_REG31_val_10M_FULL       ((5) << PHY_REG31_sft_SPEED    )
+#define PHY_REG31_val_100M_HALF      ((2) << PHY_REG31_sft_SPEED    )
+#define PHY_REG31_val_100M_FULL      ((6) << PHY_REG31_sft_SPEED    )
+#define PHY_REG31_val_DIS_SCRBL      ((1) << PHY_REG31_sft_DIS_SCRBL)
+// rtl8200
+#define PHY_REG31_val_PAGE_0         ((0) << PHY_REG31_sft_PAGE_SEL )
+#define PHY_REG31_val_PAGE_1         ((1) << PHY_REG31_sft_PAGE_SEL )
+#define PHY_REG31_val_PAGE_2         ((2) << PHY_REG31_sft_PAGE_SEL )
+
+
+/* ------------------------------------------------------------------------- */
+/*  Page 1 Register 16 Interrupt Status Register                             */
+/*  ip101    lan8700    rtl8200                                              */
+/*    NO        NO        YES                                                */
+/* ------------------------------------------------------------------------- */
+#define PHY_P1_REG16_ISR             (0x10)
+
+#define PHY_P1_REG16_sft_ANERR       (15)  /*1bit*/        /* read 0 */
+#define PHY_P1_REG16_sft_LNKSTS      (14)  /*1bit*/        /* read 0 */
+#define PHY_P1_REG16_sft_DUPLEX      (13)  /*1bit*/        /* read 0 */
+
+#define PHY_P1_REG16_bit_ANERR       (1)
+#define PHY_P1_REG16_bit_LNKSTS      (1)
+#define PHY_P1_REG16_bit_DUPLEX      (1)
+
+#define PHY_P1_REG16_val_ANERR       ((1) << PHY_P1_REG16_sft_ANERR )
+#define PHY_P1_REG16_val_LNKSTS      ((1) << PHY_P1_REG16_sft_LNKSTS)
+#define PHY_P1_REG16_val_DUPLEX      ((1) << PHY_P1_REG16_sft_DUPLEX)
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_PHY_REG_H_ */
+

+ 138 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_rtl8201.c

@@ -0,0 +1,138 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_rtl8201.c
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include "gtypes.h"
+#include "gd_timer.h"
+#include "gh_gpio.h"
+#include "gd_gpio.h"
+#define PHY_RESET_GPIO_TYPE_OUTPUT  GD_GPIO_TYPE_OUTPUT_0
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_eth_phy_rtl8201.h"
+
+#include "gh_eth.h"
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+GERR GD_ETH_PHY_RTL8200_Init(void)
+{
+#if 0
+    GBOOL   ret;
+    U32     features;
+    U32     phyRegVal;
+    /* For now, I'll claim that the generic driver supports
+        * all possible port types */
+    features = (SP_TP | SP_MII | SP_AUI | SP_FIBRE | SP_BNC);
+
+    /* Do we support autonegotiation? */
+    ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_BMSR_REG1, &phyRegVal);
+    if (ret != GTRUE)
+        return GD_ERR_ETH_PHY_RW;
+
+    if (phyRegVal & ETH_BMSR_ANEG_CAPABLE)
+        features |= SP_AUTONEG;
+
+    if (phyRegVal & ETH_BMSR_100TX_FULL)
+        features |= SP_100T_FULL;
+    if (phyRegVal & ETH_BMSR_100TX_HALF)
+        features |= SP_100T_HALF;
+    if (phyRegVal & ETH_BMSR_10T_FULL)
+        features |= SP_10T_FULL;
+    if (phyRegVal & ETH_BMSR_10T_HALF)
+        features |= SP_10T_HALF;
+
+    if (phyRegVal & ETH_BMSR_ESTATEN) {
+        ret = GD_ETH_ReadPhy(pPhyDev->addr, ETH_EXPS_REG15, &phyRegVal);
+        if (ret != GTRUE) return GD_ERR_ETH_PHY_RW;
+
+        if (phyRegVal & ETH_EXPS_1000_TFULL)
+            features |= SP_1000T_FULL;
+        if (phyRegVal & ETH_EXPS_1000_THALF)
+            features |= SP_1000T_HALF;
+    }
+
+    pPhyDev->supported      = features;
+    pPhyDev->advertising    = features;
+
+    GD_ETH_PHY_ConfigANeg(pPhyDev);
+#endif
+    return GD_OK;
+}
+GERR GD_ETH_PHY_RTL8200_Open(GD_HANDLE handle)
+{
+    //GD_ETH_PHY_DEVICE_DATA_S* device = (GD_ETH_PHY_DEVICE_DATA_S*)handle;
+    return GD_OK;
+}
+GERR GD_ETH_PHY_RTL8200_Close(GD_HANDLE handle)
+{
+    return GD_OK;
+}
+GERR GD_ETH_PHY_RTL8200_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat)
+{
+    return GD_OK;
+}
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+

+ 82 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_phy_rtl8201.h

@@ -0,0 +1,82 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_eth_phy_rtl8201.h
+**
+** \version     $Id$
+**
+** \brief       1
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#ifndef _GD_ETH_PHY_RTL8201_H_
+#define _GD_ETH_PHY_RTL8201_H_
+#include "gtypes.h"
+#include "gd_eth_phy.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GERR GD_ETH_PHY_RTL8200_Init(void);
+GERR GD_ETH_PHY_RTL8200_Open(GD_HANDLE handle);
+GERR GD_ETH_PHY_RTL8200_Close(GD_HANDLE handle);
+GERR GD_ETH_PHY_RTL8200_SWReset(GD_HANDLE handle);
+GERR GD_ETH_PHY_RTL8200_GetWorkStatus(GD_HANDLE handle, GD_ETH_StatParamsT* pStat);
+GERR GD_ETH_PHY_RTL8200_GetId(GD_HANDLE handle, U32 *phy_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_PHY_RTL8201_H_ */
+

+ 126 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_eth_priv.h

@@ -0,0 +1,126 @@
+/*!
+*******************************************************************************
+**
+** \file        gd_eth_priv.h
+**
+** \version     2.0
+**
+** \date        June 09, 2013
+**
+** \author      Steven Yu
+**
+** \brief       GMAC3H Ethernet Driver.
+**
+** This application allows testing of the ethernet function.
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS.
+**
+** (C) Copyright 2002 - 2013 by Goke Microelectronics Shanghai WSC
+**
+*******************************************************************************
+*/
+#ifndef _GD_ETH_PRIV_H_
+#define _GD_ETH_PRIV_H_
+#include "gtypes.h"
+#include "gd_ethernet.h"
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Defines and Macros
+//*****************************************************************************
+//*****************************************************************************
+
+//*****************************************************************************
+//*****************************************************************************
+//** Enumerated types
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Data Structures
+//*****************************************************************************
+//*****************************************************************************
+typedef struct
+{
+    U32 lcCnt;
+    U32 RUErrorCnt;
+    U32 TUErrorCnt;
+    U32 OvfErrorCnt;
+    U32 UnfErrorCnt;
+    U32 RWTErrorCnt;
+    U32 TjtErrorCnt;
+    U32 FbeRxErrorCnt;
+    U32 FbeTxErrorCnt;
+} GD_ETH_PHY_ErrorT;
+
+typedef struct
+{
+    GD_ETH_PHY_AddrE    addr;
+    GBOOL               supJumbo;
+    GD_ETH_StatParamsT  workstat;
+    GD_ETH_Work_ModeT   workmode;
+    GD_ETH_PHY_ErrorT   error;
+    GD_ETH_MacT         macaddr;
+    GD_ETH_IpT          ipaddr;
+    GD_HANDLE           phyreset;
+    GD_HANDLE           phyhandle;
+	U8                  phyType;
+
+    U32 TxDesStartAddr;
+    U32 RxDesStartAddr;
+
+    U8 RxbufferNum;
+    U8 TxbufferNum;
+    U8 CurRxDesSite;    //the current rx description site(number)
+    U8 CurTxDesSite;    //the current tx description site(number)
+    U8 CurReadDesSite;
+    U8 CurWriteDesSite;
+
+    U8* Txbufferstart;
+    U8* Rxbufferstart;
+    U8* NetReceiveBuffer;//copy buffer
+
+    GD_ETH_StatE StopFlag;
+    U32 SizePerRxBuffer;
+    U32 SizePerTxBuffer;
+    void (*eth_rcve)(volatile U8* recbuf,U16 len);
+} GD_ETH_HandleT;
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+GD_HANDLE gd_eth_get_handle(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* _GD_ETH_PRIV_H_ */
+

+ 1452 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/emac/gd_ethernet.c

@@ -0,0 +1,1452 @@
+/*!
+*****************************************************************************
+** \file        gd_lib/GK7101/src/emac/gd_ethernet.c
+**
+** \version     $Id$
+**
+** \brief
+**
+** \attention   THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**              ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**              OMMISSIONS
+**
+** (C) Copyright 2012-2013 by GOKE MICROELECTRONICS CO.,LTD
+**
+*****************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gh_eth.h"
+#if 1//def BOARD_EVA
+#include "gh_ephy.h"
+#endif
+#include "gd_int.h"
+#include "gd_ethernet.h"
+#include "gd_eth_priv.h"
+#include "gd_eth_emac.h"
+#include "gd_eth_phy.h"
+#include "gd_timer.h"
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Defines
+//*****************************************************************************
+//*****************************************************************************
+#define MAX_RX_BUFFER_NUM               (100)
+#define MAX_TX_BUFFER_NUM               (100)
+// 2048+sizeof(GD_ETH_MAC_DesT)    (totaol size of per descriptor and buffer)
+#define MAX_SIZE_PER_DESANDBUFFER       (2064-16)//2064
+#define ALIGN                           32
+
+#define MAX_TX_MTU_SIZE                 (9*1024) //Bytes
+#define MAX_TX_BUFFER_SIZE              (MAX_SIZE_PER_DESANDBUFFER-16) //16-->description
+#define JUMBO_FRAME_RESERVED_BUFFER_NUM (MAX_TX_MTU_SIZE/MAX_TX_BUFFER_SIZE)
+
+#define WRREG(addr,value)      *(volatile unsigned long*)(addr)=(value)
+#define RDREG(addr)            *(volatile unsigned long*)(addr)
+
+//#define PERFECT_DISCARD_ALL_OTHER_MACADDR
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local structures
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Global Data
+//*****************************************************************************
+//*****************************************************************************
+
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Data
+//*****************************************************************************
+//*****************************************************************************
+static GD_HANDLE            ethIntHandle __attribute__ ((section(".nocache_buffer"))) = 0;
+static GD_HANDLE            ethHandle __attribute__ ((section(".nocache_buffer"))) = 0;
+/* driver handle array */
+static GD_ETH_HandleT   ethdevice __attribute__ ((section(".nocache_buffer")))  =
+{
+    GD_ETH_PHY_EXTERNAL_AUTO,   /*addr*/
+    GFALSE,                     /*supJumbo*/
+    {
+        GD_ETH_SPEED_AUTO,      /*workstat.speed*/
+        GD_ETH_FULL_DUPLEX,     /*workstat.duplex*/
+        GD_ETH_LOOP_OFF,        /*workstat.loopback*/
+        GD_ETH_PHY_IF_MODE_MII, /*workstat.mode*/
+        GD_ETH_LINKDOWN,        /*workstat.linkup*/
+        GD_ETH_ERR_NONE         /*workstat.error*/
+    },
+    {
+        GTRUE,                  /*workmode.bEnAutoNeg*/
+        GD_ETH_SPEED_AUTO,      /*workmode.speed*/
+        GD_ETH_FULL_DUPLEX,     /*workmode.duplex*/
+        GD_ETH_LOOP_OFF,        /*workmode.loopback*/
+        GD_ETH_PHY_IF_MODE_MII, /*workmode.mode*/
+    },
+    { 0x00 },                   /*error*/
+    { 0x3C, 0x97, 0x0E, 0x22, 0xE1, 0x14 }, /*mac addr*/
+    { 192, 168, 1, 20 },                    /*ip addr*/
+    0,                       /*phyreset*/
+    0,                       /*phyhandle*/
+    0x00,                       /*phytype*/
+    0x00000000,                 /*TxDesStartAddr*/
+    0x00000000,                 /*RxDesStartAddr*/
+    0x00000000,                 /*RxbufferNum*/
+    0x00000000,                 /*TxbufferNum*/
+    0x00000000,                 /*CurRxDesSite*/
+    0x00000000,                 /*CurTxDesSite*/
+    0x00000000,                 /*CurReadDesSite*/
+    0x00000000,                 /*CurWriteDesSite*/
+    NULL,                       /*Txbufferstart*/
+    NULL,                       /*Rxbufferstart*/
+    NULL,                       /*NetReceiveBuffer*/
+    GD_ETH_UNINITIALIZE,        /*StopFlag*/
+    0x00000000,                 /*SizePerRxBuffer*/
+    0x00000000,                 /*SizePerTxBuffer*/
+    NULL,                       /*eth_rcve*/
+};
+
+//static U32 ethReceiveBuffer[MAX_SIZE_PER_DESANDBUFFER*MAX_RX_BUFFER_NUM/4 + 8] __attribute__ ((section(".nocache_buffer")));
+static U32 ethReceiveBuffer[MAX_SIZE_PER_DESANDBUFFER*(MAX_RX_BUFFER_NUM+JUMBO_FRAME_RESERVED_BUFFER_NUM)/4 + 8] __attribute__ ((section(".nocache_buffer")));
+static U32 ethTranslateBuffer[MAX_SIZE_PER_DESANDBUFFER*MAX_TX_BUFFER_NUM/4 + 8] __attribute__ ((section(".nocache_buffer")));
+//static U32 ethReceiveBuffer[MAX_SIZE_PER_DESANDBUFFER*MAX_RX_BUFFER_NUM/4 + 8];
+//static U32 ethTranslateBuffer[MAX_SIZE_PER_DESANDBUFFER*MAX_TX_BUFFER_NUM/4 + 8];
+
+static U32 ethReceiveBuf[1600] __attribute__ ((section(".nocache_buffer")));
+
+//static U32* ethReceiveBuffer   = 0xCF000000;
+//static U32* ethTranslateBuffer = 0xCF800000;
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions Declaration
+//*****************************************************************************
+//*****************************************************************************
+static void gd_ethClearErrorCount(void);
+static void gd_eth_mac_InitRxTxBufDesc(GBOOL txtrue, GBOOL rxtrue);
+static GERR gd_eth_mac_InitRxTxBuffer(void);
+static void gd_eth_SetNetReceiveBuffer(U8* revbuf);
+
+
+//*****************************************************************************
+//*****************************************************************************
+//** API Functions
+//*****************************************************************************
+//*****************************************************************************
+/*!
+*****************************************************************************
+** \brief Initialize the Ethernet driver.
+**
+** This function initializes Ethernet driver.
+** It allocates and initializes driver handle structures as well as
+** internal buffers for succeeding GD_ETH_Open(). Currently buffers are
+** statically allocated. Setting up hardware is not part of GD_ETH_Init(),
+** but is executed in GD_ETH_Open().
+**
+** \note This function is the implementation of
+**       GD_SYS_DriverT::initDriverFunc.
+**
+** \return
+**        - #GD_OK                      On success
+**        - #GD_ERR_ALREADY_INITIALIZED Driver is already initialized
+**        - #GD_ERR_INVALID_HANDLE      Invalid handle is specified
+**        - #GD_ERR_SEMAPHORE_CREATE    Semaphore can not be created
+**        - #GD_ERR_OUT_OF_MEMORY       Memory allocation failed
+**                                        Not Implemented yet
+**
+** \sa GD_ETH_Exit()
+*****************************************************************************
+*/
+GERR GD_ETH_Init(GD_ETH_InitParamsT* pInitParams)
+{
+    S32 retval;
+    GD_INT_OPEN_PARAMS_S intOpenParams;
+    if(ethIntHandle)
+    {
+        return GD_ERR_ALREADY_INITIALIZED;
+    }
+    if(pInitParams == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    intOpenParams.type           = GD_INT_ETH_IRQ;
+    intOpenParams.sensitivity    = GD_INT_LEVEL_HIGH;
+    intOpenParams.priority       = GD_INT_MID_PRIORITY;
+    intOpenParams.active         = GD_INT_INVERT_IRQ;
+    intOpenParams.isrFct.lowPrio = GD_ETH_Isr;
+    retval =  GD_INT_Open(&intOpenParams, &ethIntHandle);
+    if (retval != GD_OK)
+    {
+        return retval;
+    }
+
+    if (pInitParams->phyreset != GD_GPIO_0)
+    {
+        GD_GPIO_Open(pInitParams->phyreset, GD_GPIO_TYPE_OUTPUT_1, NULL, &ethdevice.phyreset);
+    }
+
+    if(pInitParams->bHWReset)
+    {
+        GD_ETH_PHY_HWReset((GD_HANDLE)&ethdevice);
+    }
+    ethdevice.phyType = pInitParams->phyType;
+    GD_ETH_PHY_Init(pInitParams->phyType);
+    return retval;
+}
+
+/*!
+*****************************************************************************
+** \brief Exit the Ethernet driver.
+**
+** This function terminates Ethernet driver and deallocates internal buffers.
+**
+** \note This function is the implementation of
+**       GD_SYS_DriverT::exitDriverFunc.
+**
+** \sa GD_ETH_Init()
+*****************************************************************************
+*/
+GERR GD_ETH_Exit(void)
+{
+    if(ethIntHandle == 0)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+    GD_INT_Enable(&ethIntHandle, 0);
+    GD_INT_Close(&ethIntHandle);
+    ethIntHandle = 0;
+    if(ethdevice.phyreset)
+    {
+        GD_GPIO_Close(&ethdevice.phyreset);
+        ethdevice.phyreset = 0;
+    }
+    return GD_OK;
+}
+
+/*!
+*****************************************************************************
+** \brief Open the Ethernet driver.
+**
+** This function opens the Ethernet driver. It initializes an internal
+** handle structure depending on 'paramsPtr', and then set up underlying
+** hardware. If succeed, the ethdevice has already got running.
+**
+** Auto-negotiation will be activated if #GD_ETH_SPEED_AUTO is specified
+** in 'paramsPtr->speed'.
+** Normally, 'paramsPtr->recvCallback' should be pointed to upper-layer protocol's
+** input function. Specify NULL if it is not necessary.
+**
+** \param paramsPtr Pointer to #GD_ETH_OpenParamsT parameters.
+**                  - version:     Driver version
+**                  - devIndex:    Device index to identify Ethernet ethdevice (obsolete)
+**                  - speed:       Speed setting
+**                  - duplex:      Duplex mode setting
+**                  - loop:        Loopback mode setting. It is only for
+**                                 debugging purpose. General applications
+**                                 should specify #GD_ETH_LOOP_OFF.
+**                  - recvCallback:Callback function. It is called from
+**                                 GD_ETH_Isr() at receiving-data event.
+** \param errorCodePtr Pointer where error code should be stored or NULL if unused.
+**
+** \return
+**        - (!NULL) Valid driver handle (obsolete) on success
+**        - (NULL)  The driver can not be opened
+**
+** \sa GD_ETH_Close()
+** \sa GD_ETH_Isr()
+*****************************************************************************
+*/
+GERR GD_ETH_Open(GD_ETH_OpenParamsT* pOpenParams, GD_HANDLE* pHandle)
+{
+    U32 i;
+    GERR     gerr;
+    if(ethIntHandle == 0)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+    if(pOpenParams == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if(pHandle == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if ((pOpenParams->addr > GD_ETH_PHY_EXTERNAL_AUTO) ||
+
+        ((pOpenParams->workmode.bEnAutoNeg != GTRUE) &&
+        ((pOpenParams->workmode.speed != GD_ETH_SPEED_AUTO) &&
+        (pOpenParams->workmode.speed != GD_ETH_SPEED_10M) &&
+        (pOpenParams->workmode.speed != GD_ETH_SPEED_100M) &&
+        (pOpenParams->workmode.speed != GD_ETH_SPEED_1000M) ||
+        (pOpenParams->workmode.duplex != GD_ETH_HALF_DUPLEX) &&
+        (pOpenParams->workmode.duplex != GD_ETH_FULL_DUPLEX) ||
+        (pOpenParams->workmode.loopback != GD_ETH_LOOP_OFF) &&
+        (pOpenParams->workmode.loopback != GD_ETH_LOOP_ON_MAC) &&
+        (pOpenParams->workmode.loopback != GD_ETH_LOOP_ON_PHY))) ||
+
+        (pOpenParams->workmode.mode >= GD_ETH_PHY_IF_MODE_NONE))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if(ethHandle != 0)
+    {
+        return GD_ERR_ALREADY_OPEN;
+    }
+    
+    if(ethdevice.phyType != 0)
+    {
+        ethdevice.workmode.mode = pOpenParams->workmode.mode;
+    }
+    else
+    {
+        ethdevice.workmode.mode = GD_ETH_PHY_IF_MODE_MII;
+    }
+    
+    ethdevice.addr                  = pOpenParams->addr;
+    ethdevice.workmode.bEnAutoNeg   = pOpenParams->workmode.bEnAutoNeg;
+    ethdevice.workmode.speed        = pOpenParams->workmode.speed;
+    ethdevice.workmode.duplex       = pOpenParams->workmode.duplex;
+    ethdevice.workmode.loopback     = pOpenParams->workmode.loopback;
+    ethdevice.supJumbo              = pOpenParams->supJumbo;
+
+    // move to here for RMII mode, must config phy clk output first,
+    // otherwise, the EMAC can not work.
+    GD_TIMER_Delay(500);
+    gerr = GD_ETH_PHY_Open(&ethdevice.addr, &ethdevice.phyhandle);
+    if(gerr!=GD_OK)
+    {
+        return gerr;
+    }
+    gerr = GD_ETH_PHY_SWReset(ethdevice.phyhandle);
+    if(gerr!=GD_OK)
+    {
+        return gerr;
+    }
+    gerr = GD_ETH_PHY_SetWorkMode(ethdevice.phyhandle, ethdevice.workmode);
+    if(gerr!=GD_OK)
+    {
+        return gerr;
+    }
+
+    switch(ethdevice.workmode.mode)
+    {
+    case GD_ETH_PHY_IF_MODE_SGMII:
+    case GD_ETH_PHY_IF_MODE_GMII:
+    case GD_ETH_PHY_IF_MODE_TBI:
+    case GD_ETH_PHY_IF_MODE_RGMII:
+    case GD_ETH_PHY_IF_MODE_RGMII_ID:
+    case GD_ETH_PHY_IF_MODE_RGMII_RXID:
+    case GD_ETH_PHY_IF_MODE_RGMII_TXID:
+    case GD_ETH_PHY_IF_MODE_RTBI:
+    case GD_ETH_PHY_IF_MODE_XGMII:
+    case GD_ETH_PHY_IF_MODE_NONE:
+        return GD_ERR_BAD_PARAMETER;
+        //break;
+    case GD_ETH_PHY_IF_MODE_MII:
+        GH_EPHY_set_MII_RMII_rmii(0x0);
+        break;
+    case GD_ETH_PHY_IF_MODE_RMII:
+    default:
+        GH_EPHY_set_MII_RMII_rmii(0x1);
+        break;
+    }
+
+    /* reset emac */
+    GH_ETH_set_BMR(ETH_REG_BMR_SWRST);//reset emac all reg
+    for ( i = 0; i < 1000; i++ )
+    {
+        GD_TIMER_Delay(1);
+        if((GH_ETH_get_BMR() & ETH_REG_BMR_SWRST)!= ETH_REG_BMR_SWRST)
+           break;
+    }
+    if ( i >=1000 )
+    {
+        return GD_ERR_ETH_MAC_NOT_OK;
+    }
+
+    gd_ethClearErrorCount();
+
+    ethdevice.StopFlag = GD_ETH_UNINITIALIZE;
+
+    /*Initialise the recevie and transmit buffer, and the descriptors*/
+    gd_eth_mac_InitRxTxBuffer();
+
+    gd_eth_SetNetReceiveBuffer((U8*)((U32)&ethReceiveBuf[0]+2));
+
+#if FIX_TX_OWN
+    //small endian,one bytes dma, skip length=0, swr=0
+    //GH_ETH_set_BMR(ETH_REG_BMR_PBL1);
+    GH_ETH_set_BMR_PBL(1);
+#else
+   //small endian,32 bytes dma, skip length=0, swr=0
+    //GH_ETH_set_BMR(ETH_REG_BMR_PBL32);
+    GH_ETH_set_BMR_PBL(32);
+#endif /* FIX_TX_OWN */
+    GH_ETH_set_BMR_FB(1);
+
+    /* set MCR (Configuration resister) must be after phy initial */
+    GH_ETH_set_MCR(ethSetupMCR((GD_HANDLE)&ethdevice));
+    /* set RDLAR (Receive Descriptor base address) */
+    GH_ETH_set_RDLAR((U32)(ethdevice.RxDesStartAddr));
+    /* set TDLAR(descriptor base) current desc */
+    GH_ETH_set_TDLAR((U32)(ethdevice.TxDesStartAddr));
+#ifdef PERFECT_DISCARD_ALL_OTHER_MACADDR
+	/* set MFFR (Address Filtering)*/
+	GH_ETH_set_MFFR_PR(0);		//PM
+	GH_ETH_set_MFFR_HUC(0);		//HU
+	GH_ETH_set_MFFR_HMC(0);		//HM
+	GH_ETH_set_MFFR_IFT(0);		//DAIF
+	GH_ETH_set_MFFR_PM(0);		//PAM
+	GH_ETH_set_MFFR_DB(1);		//BFD --1:DISABLE BROADCAST FRAME
+	GH_ETH_set_MFFR_PCF(3);		//PCF--0_x:never pass any control frame  1_1:... 
+	GH_ETH_set_MFFR_SAIF(0);	//SAIF
+	GH_ETH_set_MFFR_SAF(0);		//SAF
+	GH_ETH_set_MFFR_HPF(1);		//HPF--0: Hash or perfect filter
+	GH_ETH_set_MFFR_RA(0);		//RA --receive all
+#else
+    /* set MFFR (Address Filtering)*/
+    GH_ETH_set_MFFR((U32)ETH_REG_MFFR_RA);//disable broadcast frame
+#endif	
+    /* set MHTRH (Address Filtering)*/
+    GH_ETH_set_MHTRH((U32)0xFFFFFFFF);
+    /* set MHTRL (Address Filtering)*/
+    GH_ETH_set_MHTRL((U32)0xFFFFFFFF);
+    /* set MAR0H (MAC Address)*/
+    GH_ETH_set_MAR0H(0x80000000+(pOpenParams->macaddr[5]<<8)+pOpenParams->macaddr[4]);
+    /* set MAR0L (MAC Address)*/
+    GH_ETH_set_MAR0L((pOpenParams->macaddr[3]<<24)+(pOpenParams->macaddr[2]<<16)+
+                     (pOpenParams->macaddr[1]<<8)+(pOpenParams->macaddr[0]<<0));
+    /* Setup Flow Control Register */
+    GH_ETH_set_FCR(ETH_REG_FCR_TFE| ETH_REG_FCR_RFE);
+
+
+#ifdef PRINT_ETH_LOG
+    printf("TDLAR: 0x%08x\n", ethdevice.TxDesStartAddr);
+    printf("RDLAR: 0x%08x\n", ethdevice.RxDesStartAddr);
+#endif
+
+//#if FIX_TX_OWN
+    GH_ETH_set_OMR(GH_ETH_get_OMR()|ETH_REG_OMR_SF);
+//#endif /* FIX_TX_OWN */
+
+    GD_ETH_SetEMACSpeed((GD_HANDLE)&ethdevice, pOpenParams->workmode.speed);
+
+    //set IER (Interrupt settings)
+    GH_ETH_set_IER(ETH_REG_IER_NI | ETH_REG_IER_AI | ETH_REG_IER_FBE | ETH_REG_IER_RW
+                    | ETH_REG_IER_RS | ETH_REG_IER_RU | ETH_REG_IER_RI | ETH_REG_IER_UN
+                    | ETH_REG_IER_OVF | ETH_REG_IER_TJ | ETH_REG_IER_TU | ETH_REG_IER_TS | ETH_REG_IER_TI);
+
+    /* added by waite wu */
+    /* create thread */
+
+    ethdevice.StopFlag   = GD_ETH_RX_STOP;
+    ethdevice.StopFlag  |= GD_ETH_TX_STOP;
+
+    GD_INT_Enable(&ethIntHandle, 1);
+
+    GD_ETH_StartDevice((GD_HANDLE)&ethdevice, GD_ETH_R);//make it in rx/tx state
+    //GD_ETH_StartDevice(&ethdevice, GD_ETH_W);//make it in tx state
+
+    if(gerr != GD_OK)
+    {
+#ifdef PRINT_ETH_LOG
+        printf("[%s_%d]Ethernet Initialization Failure!\n",__FUNCTION__, __LINE__);
+#endif
+        return GD_ERR_ETH_LINK_DOWN;
+    }
+#ifdef PRINT_ETH_LOG
+    printf("[%s_%d]Ethernet Initialization Succeed!\n",__FUNCTION__, __LINE__);
+#endif
+    ethHandle = (GD_HANDLE)&ethdevice;
+    *pHandle  = (GD_HANDLE)&ethdevice;
+    return GD_OK;
+}
+
+/*!
+*****************************************************************************
+** \brief Close the Ethernet driver.
+**
+** This function closes the Ethernet driver. After this function, the ethdevice
+** is stopped and its configurations are unset.
+** If stop process failed, the handle is not closed.
+**
+** \param handle Ethernet driver handle (obsolete)
+**
+** \return
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ERR_INVALID_HANDLE  Invalid handle is specified
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    This should not happen as all other
+**                                    calls to this driver should be finished
+**                                    when closing it.
+**
+** \sa GD_ETH_Open()
+*****************************************************************************
+*/
+/*lint -e{715} */
+GERR GD_ETH_Close(GD_HANDLE* pHandle)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)(*pHandle);
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    GD_INT_Enable(pHandle, 0);
+    ethHandle = 0;
+    GD_ETH_PHY_Close(&device->phyhandle);
+    return GD_OK;
+}
+
+/*!
+*****************************************************************************
+** \brief Read data over network.
+**
+** This function retrieves Ethernet frame data from the Ethernet ethdevice,
+** and store them into a buffer, pointed to by 'bufPtr'.
+** If 'size' is smaller than the one of actual frame, the left data can be
+** read by succeeding GD_ETH_Read().
+** Only if all the frame data are received successfully, #GD_ETH_FRAME_END
+** is set in 'frame'.
+**
+** \param handle Ethernet driver handle (obsolete)
+** \param bufPtr Pointer to read buffer
+** \param size   Read size
+** \param frame  Pointer to frame flag. If read process detect the end of an
+**               Ethernet frame, #GD_ETH_FRAME_END is set then return. If it
+**               is #GD_ETH_FRAME_NOTEND, read data does not contain frame
+**               end. If it is #GD_ETH_FRAME_TERM, current Ethernet frame
+**               was aborted by hardware errors. So application should discard
+**               the read data.
+**
+** \return
+**        - (>0) read data size.
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ERR_INVALID_HANDLE  Invalid handle is specified
+**        - #GD_ETH_ERR_NULL_PTR    bufPtr or frame is NULL
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by GD_ETH_Write
+**                                    used in another tasks. A task switch
+**                                    should be performed to allow the other
+**                                    task to free the lock.
+**        - #GD_ETH_ERR_DATACCESS   Unknown error on data copy
+**        - #GD_ETH_ERR_RXSTOP      Read process failed because of its
+**                                    fatal hardware errors . Application
+**                                    should reset(close and re-open)
+**                                    driver. GD_ETH_GetStat() can get
+**                                    detailed information about the error.
+** \sa GD_ETH_GetStat()
+** \sa GD_ETH_Write()
+*****************************************************************************
+*/
+/* ******************************************* */
+/* Enable profiling for the following function */
+/* ******************************************* */
+/*lint -e(961) */
+/* ******************************************* */
+/*lint -e{715} */
+S32 GD_ETH_Read(GD_HANDLE handle, char *bufPtr, S32 size, GD_ETH_FrameEndE *pframe)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    return 0;
+}
+
+/*!
+*****************************************************************************
+** \brief Write data over network.
+**
+** This function writes Ethernet frame data, pointed to by 'bufPtr',
+** into a buffer and hand it over to the Ethernet ethdevice.
+** Only if #GD_ETH_FRAME_END is specified in 'frame', the data will be actually
+** sent over network. Until then, all the data are kept in buffers.
+**
+** \param handle Ethernet driver handle (obsolete)
+** \param bufPtr Pointer to write data
+** \param size   Write size
+** \param frame  Frame flag. It should be #GD_ETH_FRAME_NOTEND or
+**               #GD_ETH_FRAME_END. If #GD_ETH_FRAME_NOTEND, the written
+**               data is stored in driver. If #GD_ETH_FRAME_END, the data
+**               stored in driver is transferred as an Ethernet frame.
+**
+** \return
+**        - (>0)                      Written data size
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ERR_INVALID_HANDLE  Invalid handle is specified
+**        - #GD_ETH_ERR_NULL_PTR    bufPtr is NULL
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by GD_ETH_Read
+**                                    used in another tasks. A task switch
+**                                    should be performed to allow the other
+**                                    task to free the lock.
+**        - #GD_ETH_ERR_DATACCESS   Unknown error on data copy
+**        - #GD_ETH_ERR_TXSTOP      Write process failed because of its
+**                                    fatal hardware errors . Application
+**                                    should  reset(close and re-open) driver.
+**                                    GD_ETH_GetStat() can get detailed
+**                                    information about the error.
+**        - #GD_ETH_ERR_AGAIN       Write process failed on some non-fatal
+**                                    errors. Try Again later.
+**
+** \sa GD_ETH_GetStat()
+** \sa GD_ETH_Read()
+*****************************************************************************
+*/
+/*lint -e{715} */
+S32 GD_ETH_Write(GD_HANDLE handle, const char* buffer, S32 len, GD_ETH_FrameEndE frame)
+{
+    U32 i;
+    U16 dlen;
+    volatile GD_ETH_MAC_DesT* p;
+    volatile U8* des;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    if(len > device->SizePerTxBuffer)
+    {
+        printf("Len too big: %d, TxBufSize: %d\n", len, device->SizePerTxBuffer);
+        return GFALSE;
+    }
+
+    /*Find a valid descriptor*/
+#if 0
+    for(i=0;i<device->TxbufferNum;i++)
+    {
+        p=(volatile GD_ETH_MAC_DesT*)((device->TxDesStartAddr) + device->CurWriteDesSite*sizeof(GD_ETH_MAC_DesT));
+        if(((p->des0)&ETH_DES_T0_OWN) == 0 )
+        {
+            break;
+        }
+        /*update the CurWriteDesSite index*/
+        if(device->CurWriteDesSite == device->TxbufferNum - 1)
+        {
+            device->CurWriteDesSite = 0;
+        }
+        else
+        {
+            device->CurWriteDesSite++;
+        }
+    }
+    if(i == device->TxbufferNum)
+    {
+        printf("No valid descriptor!\n");
+        return GFALSE;
+    }
+#else
+    GD_INT_Enable(&ethIntHandle, 0);//the isr of ethernet  may call the current function agin
+
+    p=(volatile GD_ETH_MAC_DesT*)((device->TxDesStartAddr) + device->CurWriteDesSite*sizeof(GD_ETH_MAC_DesT));
+    //printf("descriptor:0x%08x-0x%08x\n", (U32)p, GH_ETH_get_CHTDR());
+    //printf("descriptor buffer:0x%08x-0x%08x\n", (U32)(p->des2), GH_ETH_get_CHTBAR());
+    //printf("descriptor:0x%08x\n", (U32)p);
+    //printf("descriptor buffer:0x%08x\n", (U32)(p->des2));
+    //p=(volatile GD_ETH_MAC_DesT*)GH_ETH_get_CHTDR();
+    if(((p->des0)&ETH_DES_T0_OWN) != 0 )
+    {
+        //printf("No valid descriptor!\n");
+        return GFALSE;
+    }
+    /*update the CurWriteDesSite index*/
+    if(device->CurWriteDesSite == device->TxbufferNum - 1)
+    {
+        device->CurWriteDesSite = 0;
+    }
+    else
+    {
+        device->CurWriteDesSite++;
+    }
+
+#endif
+
+    p->des0=0;//ETH_DES_T0_OWN;
+    p->des1 = (p->des1)&ETH_DES_T1_TER; //(ETH_DES_T1_TBS1 & 0x0);
+    p->des3 =0;
+
+    //copy data :
+    des=(volatile U8*)(p->des2);////point to data buffer
+
+    for(i=0;i<len;i++)
+    {
+        des[i]=buffer[i];
+    }
+    i = len;
+    //add CRC check sum:
+    des[i++]=0;
+    des[i++]=0;
+    des[i++]=0;
+    des[i++]=0;
+    //dlen=len+4;
+    dlen=len;
+    //set data length:
+    /*if(dlen<64)
+    {
+        for(i=0;i<(U8)(60-len);i++)
+            des[len+i]=i;
+        p->des1 =(p->des1)|(ETH_DES_T1_TBS1 & 60); //first data buffer size
+    }
+    else*/
+        p->des1 =(p->des1)|(ETH_DES_T1_TBS1 & len);
+    p->des1 |= ETH_DES_T1_FS |ETH_DES_T1_LS| ETH_DES_T1_IC; //| ETH_DES_T1_TCH;//| ETH_DES_T1_TER; //first segment, last segment
+
+    p->des3=0;//(U32)((device->TxDesStartAddr)+1*sizeof(GD_ETH_MAC_DesT));
+    p->des0=ETH_DES_T0_OWN; //start to send
+
+    GD_ETH_StartDevice(handle, GD_ETH_W);//make it in tx state
+
+    GD_INT_Enable(&ethIntHandle, 1);//enable the interrupt of ethernet agin
+    return 0;
+}
+
+//support Jambo Frame
+S32 GD_ETH_Write_Enhance(GD_HANDLE handle, const char* buffer, S32 len, GD_ETH_FrameEndE frame)
+{
+    U32 i,j;
+    S32 dlen,buffsize;
+    volatile GD_ETH_MAC_DesT* p;
+    volatile U8* des;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    if(buffer == NULL)
+    {
+        printf("GD_ETH_Write_Enhance:Buffer is NULL!\n");
+        return GFALSE;
+    }
+
+    if(len > MAX_TX_MTU_SIZE)
+    {
+        printf("Len too big: %d, MTU Size: %dbytes\n", len, MAX_TX_MTU_SIZE);
+        return GFALSE;
+    }
+
+    i = 0;
+    dlen = len;
+    //buffsize = ethdevice.SizePerTxBuffer - 1;
+    buffsize = ethdevice.SizePerTxBuffer;//ethdevice.SizePerTxBuffer<2048
+
+    GD_INT_Enable(&ethIntHandle, 0);//the isr of ethernet  may call the current function agin
+
+    p = (volatile GD_ETH_MAC_DesT*)((device->TxDesStartAddr) + device->CurWriteDesSite*sizeof(GD_ETH_MAC_DesT));
+    while(dlen>buffsize)
+    {
+        if(((p->des0)&ETH_DES_T0_OWN) != 0 )
+        {
+            //printf("No valid descriptor!\n");
+            return GFALSE;
+        }   
+        
+        p->des1 = (p->des1)&ETH_DES_T1_TER; //clear DES1,except for bit[25]
+        
+        if(i==0)//First Frame
+        {
+            p->des1 |= ETH_DES_T1_IC | ETH_DES_T1_FS |(ETH_DES_T1_TBS1 & buffsize);//buffer0-->0x7f0  buffer1-->0
+        }
+        else//mid Frame
+        {
+            p->des1 |= ETH_DES_T1_IC |(ETH_DES_T1_TBS1 & buffsize);//buffer0-->0x7f0  buffer1-->0
+        }
+
+        //use cpu to copy data--------->memory copy or dma copy
+        des=(volatile U8*)(p->des2);////point to data buffer
+        for(j=0;j<buffsize;j++)
+        {
+            //des[j]=buffer[buffsize*i+j];
+            *des++=*buffer++;
+        }
+
+/*        memcpy((void *)des,(const void *)buffer,buffsize);
+        buffer=buffer+buffsize;*/
+        p->des3 = 0;
+        p->des0 = ETH_DES_T0_OWN;
+
+        /*update the CurWriteDesSite index*/
+        if(device->CurWriteDesSite == device->TxbufferNum - 1)
+        {
+            device->CurWriteDesSite = 0;
+            p = (volatile GD_ETH_MAC_DesT*)(device->TxDesStartAddr);
+        }
+        else
+        {
+            device->CurWriteDesSite++;
+            p++;//next descriptor
+        }
+
+        dlen -= buffsize;
+        i++;
+    }
+
+    if(((p->des0)&ETH_DES_T0_OWN) != 0 )
+    {
+        //printf("No valid descriptor!\n");
+        return GFALSE;
+    }  
+
+    if(i==0)//one buffer including the whole frame
+    {         
+        p->des1  = ((p->des1)&ETH_DES_T1_TER) | ETH_DES_T1_IC | ETH_DES_T1_FS |ETH_DES_T1_LS |(ETH_DES_T1_TBS1 & dlen);//<64bytes, stuffed by hardware automatically             
+    }
+    else//the last buffer including the last fragment of  frame
+    {       
+        p->des1 = ((p->des1)&ETH_DES_T1_TER) | ETH_DES_T1_IC |ETH_DES_T1_LS |(ETH_DES_T1_TBS1 & dlen);//buffer0-->xxx  buffer1-->0            
+    }
+
+    //use cpu to copy data--------->memory copy or dma copy
+    des=(volatile U8*)(p->des2);//point to data buffer
+    for(j=0;j<dlen;j++)
+    {
+        //des[j]=buffer[buffsize*i+j];
+        *des++=*buffer++;
+    }
+/*        memcpy((void *)des,(const void *)buffer,dlen);
+    buffer=buffer+dlen;*/
+
+    p->des3 = 0;
+    p->des0 = ETH_DES_T0_OWN;       
+    
+   /*update the CurWriteDesSite index*/
+   if(device->CurWriteDesSite == device->TxbufferNum - 1)
+   {
+       device->CurWriteDesSite = 0;
+   }
+   else
+   {
+       device->CurWriteDesSite++;
+   }
+
+    GD_ETH_StartDevice(handle, GD_ETH_W);//make it in tx state
+
+    GD_INT_Enable(&ethIntHandle, 1);//enable the interrupt of ethernet agin
+    
+    return 0;
+}
+
+
+
+#define USE_TWO_BUFFER  1
+GERR GD_ETH_Write_HD(GD_HANDLE handle, const char* HbufPtr, S32 Hsize, const char* DbufPtr, S32 Dsize, GD_ETH_FrameEndE frame)
+{
+    U32 i;
+#ifndef USE_TWO_BUFFER
+    U16 dlen;
+#endif
+    volatile GD_ETH_MAC_DesT* p;
+    volatile U8* des;
+    S32 len;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    len = Hsize + Dsize;
+    if(len > device->SizePerTxBuffer)
+    {
+        printf("Len too big: %d, TxBufSize: %d\n", len, device->SizePerTxBuffer);
+        return GD_ERR_ETH_TB_OVER;
+    }
+
+    GD_INT_Enable(&ethIntHandle, 0);//the isr of ethernet  may call the current function agin
+    
+    p=(volatile GD_ETH_MAC_DesT*)((device->TxDesStartAddr) + device->CurWriteDesSite*sizeof(GD_ETH_MAC_DesT));
+    if(((p->des0)&ETH_DES_T0_OWN) != 0 )
+    {
+        //printf("No valid descriptor!\n");
+        return GD_ERR_ETH_NO_TD;
+    }
+    /*update the CurWriteDesSite index*/
+    if(device->CurWriteDesSite == device->TxbufferNum - 1)
+    {
+        device->CurWriteDesSite = 0;
+    }
+    else
+    {
+        device->CurWriteDesSite++;
+    }
+
+    p->des0=0;//ETH_DES_T0_OWN;
+    p->des1 = (p->des1)&ETH_DES_T1_TER; //(ETH_DES_T1_TBS1 & 0x0);
+#ifdef USE_TWO_BUFFER
+    p->des3 = (U32)DbufPtr;
+#else
+    p->des3 = 0;
+#endif
+
+    //copy data :
+    des=(volatile U8*)(p->des2);////point to data buffer
+
+    for(i=0;i<Hsize;i++)
+    {
+        *des++=*HbufPtr++;
+    }
+#ifdef USE_TWO_BUFFER
+#else
+    for(i=0;i<Dsize;i++)
+    {
+        *des++=*DbufPtr++;
+    }
+#endif
+    des=(volatile U8*)(p->des2);////point to data buffer
+    i = len;
+    //add CRC check sum:
+    des[i++]=0;
+    des[i++]=0;
+    des[i++]=0;
+    des[i++]=0;
+    //set data length:
+#ifdef USE_TWO_BUFFER
+    p->des1 = (p->des1)|(ETH_DES_T1_TBS1 & Hsize) | (ETH_DES_T1_TBS2 & (Dsize<<11));
+    p->des3 = (U32)DbufPtr;//(U32)((device->TxDesStartAddr)+1*sizeof(GD_ETH_MAC_DesT));
+#else
+    //dlen=len+4;
+    dlen=len;
+    if(dlen<64)
+    {
+        for(i=0;i<(U8)(60-len);i++)
+            des[len+i]=i;
+        p->des1 =(p->des1)|(ETH_DES_T1_TBS1 & 60); //first data buffer size
+    }
+    else
+        p->des1 =(p->des1)|(ETH_DES_T1_TBS1 & len);
+    p->des3 = 0;//(U32)((device->TxDesStartAddr)+1*sizeof(GD_ETH_MAC_DesT));
+#endif
+    p->des1 |= ETH_DES_T1_FS |ETH_DES_T1_LS| ETH_DES_T1_IC; //| ETH_DES_T1_TCH;//| ETH_DES_T1_TER; //first segment, last segment
+
+    p->des0 = (U32)ETH_DES_T0_OWN; //start to send
+
+    GD_ETH_StartDevice(handle, GD_ETH_W);//make it in tx state
+
+    GD_INT_Enable(&ethIntHandle, 1);//enable the interrupt of ethernet agin
+
+    return GD_OK;
+}
+
+//HbufPtr:copy  to p->des2 (buffer1)
+//DbufPtr:use as p->des3 (buffer2)  directly without copying
+GERR GD_ETH_Write_HD_Enhance(GD_HANDLE handle, const char* HbufPtr, S32 Hsize, const char* DbufPtr, S32 Dsize, GD_ETH_FrameEndE frame)
+{
+    U32 i,j;
+#ifndef USE_TWO_BUFFER
+    U16 dlen;
+#endif
+    volatile GD_ETH_MAC_DesT* p;
+    volatile U8* des;
+    S32 len;
+    S32 buffsize;
+    
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+
+    buffsize = ethdevice.SizePerTxBuffer;    
+    len = buffsize + Dsize;//len = Hsize + Dsize;
+    if(len > MAX_TX_MTU_SIZE)
+    {
+        printf("Len too big: %d, Max frame size: %d\n", len, MAX_TX_MTU_SIZE);
+        return GD_ERR_ETH_TB_OVER;
+    }
+
+    i = 0;
+
+    GD_INT_Enable(&ethIntHandle, 0);//the ISR of ethernet  may call the current function agin
+
+    p=(volatile GD_ETH_MAC_DesT*)((device->TxDesStartAddr) + device->CurWriteDesSite*sizeof(GD_ETH_MAC_DesT));
+
+    while(len>(buffsize<<1))
+    {
+        while(((p->des0)&ETH_DES_T0_OWN) != 0 )
+        {
+            printf("No valid descriptor!\n");
+            //return GFALSE;
+        }   
+        
+        p->des1 = (p->des1)&ETH_DES_T1_TER; //clear DES1,except for bit[25]
+        
+        if(i==0)//First Frame
+        {
+            p->des1 |= ETH_DES_T1_IC | ETH_DES_T1_FS |(ETH_DES_T1_TBS1 & Hsize) | ( (ETH_DES_T1_TBS2 & (buffsize<<11)) );//buffer0-->0x7f0  buffer1-->DbufPtr
+
+            //use cpu to copy data--------->memory copy or dma copy
+            des=(volatile U8*)(p->des2);////point to data buffer
+            for(j=0;j<Hsize;j++)
+            {
+                *des++=*HbufPtr++;
+            }   
+
+            p->des3 = (U32)DbufPtr;       
+            
+        }
+        else//mid Frame
+        {
+            p->des1 |= ETH_DES_T1_IC | (ETH_DES_T1_TBS1 & buffsize) | (ETH_DES_T1_TBS2 & (buffsize<<11));//buffer0-->0x7f0  buffer1-->0x7f0
+            p->des2 = (U32)(DbufPtr+(2*i-1)*buffsize);
+            p->des3 = (U32)(DbufPtr+2*i*buffsize);
+        }
+        p->des0 = ETH_DES_T0_OWN;
+        
+        /*update the CurWriteDesSite index*/
+        if(device->CurWriteDesSite == device->TxbufferNum - 1)
+        {
+            device->CurWriteDesSite = 0;
+            p = (volatile GD_ETH_MAC_DesT*)(device->TxDesStartAddr);
+        }
+        else
+        {
+            device->CurWriteDesSite++;
+            p++;//next descriptor
+        }
+        
+        len -= (buffsize<<1);
+        i++;     
+    }
+
+    while(((p->des0)&ETH_DES_T0_OWN) != 0 )
+    {
+        printf("No valid descriptor!\n");
+        //return GFALSE;
+    }  
+
+    if(i==0)//one buffer including the whole frame
+    {
+        //>des1 = (p->des1)&ETH_DES_T1_TER; //clear DES1,except for bit[25] 
+        p->des1  = ((p->des1)&ETH_DES_T1_TER) | ETH_DES_T1_IC | ETH_DES_T1_FS | ETH_DES_T1_LS \
+                   |(ETH_DES_T1_TBS1 & Hsize) | (ETH_DES_T1_TBS2 & (Dsize<<11));//<64bytes, stuffed by hardware automatically         
+
+        //use cpu to copy data--------->memory copy or dma copy
+        des=(volatile U8*)(p->des2);////point to data buffer
+        for(j=0;j<Hsize;j++)
+        {
+            *des++=*HbufPtr++;
+        }   
+        
+        p->des3 = (U32)DbufPtr;
+    }
+    else//the last buffer including the last fragment of  frame
+    {
+        if(len<=buffsize)
+        {
+            p->des1 =  ((p->des1)&ETH_DES_T1_TER) | ETH_DES_T1_IC | ETH_DES_T1_LS \
+                        | (ETH_DES_T1_TBS1 & len);//buffer0-->len  buffer1-->0       
+            p->des2 = (U32)(DbufPtr+(2*i-1)*buffsize);
+            p->des3 = 0;                
+        }
+        else
+        {
+            p->des1 = ((p->des1)&ETH_DES_T1_TER) | ETH_DES_T1_IC | ETH_DES_T1_LS \
+                        | (ETH_DES_T1_TBS1 & buffsize) | (ETH_DES_T1_TBS2 & ((len-buffsize)<<11));//buffer0-->buffsize  buffer1-->last fragment  
+            p->des2 = (U32)(DbufPtr+(2*i-1)*buffsize);
+            p->des3 = (U32)(DbufPtr+2*i*buffsize);                        
+        }     
+    }
+    
+    p->des0 = ETH_DES_T0_OWN;   
+
+    /*update the CurWriteDesSite index*/
+    if(device->CurWriteDesSite == device->TxbufferNum - 1)
+    {
+        device->CurWriteDesSite = 0;
+    }
+    else
+    {
+        device->CurWriteDesSite++;
+    }
+
+    GD_ETH_StartDevice(handle, GD_ETH_W);//make it in tx state
+    GD_INT_Enable(&ethIntHandle, 1);//enable the interrupt of ethernet agin
+
+    return GD_OK;
+}
+
+
+GERR GD_ETH_SetEMACSpeed(GD_HANDLE handle, GD_ETH_SpeedE speed)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device->workmode.speed = speed;
+    if(device->workmode.bEnAutoNeg)
+    {
+        printf("Set MAC work in AUTO mode\n");
+    }
+    else
+    {
+        switch(speed)
+        {
+        case GD_ETH_SPEED_AUTO:
+            printf("Set MAC work in AUTO mode\n");
+            break;
+        case GD_ETH_SPEED_10M:
+            printf("Set MAC work in 10M mode\n");
+            break;
+        case GD_ETH_SPEED_100M:
+            printf("Set MAC work in 100M mode\n");
+            break;
+        case GD_ETH_SPEED_1000M:
+            printf("Set MAC work in 1000M mode\n");
+            break;
+        }
+    }
+    return GD_ETH_PHY_SetWorkMode(device->phyhandle, device->workmode);
+}
+
+/*!
+*****************************************************************************
+** \brief Set Ethernet MAC address.
+**
+** This function returns Ethernet MAC address of the ethdevice in 'macAddress'.
+** It can be called at any time after GD_ETH_Init().
+**
+** \param index      Device index to identify Ethernet ethdevice (obsolete)
+** \param macAddress Ethernet MAC address, represented as byte buffer.
+**
+** \return
+**        - #GD_OK                  On success
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ETH_ERR_NULL_PTR    macAddress is NULL
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by another tasks.
+**                                    A task switch should be performed to allow
+**                                    the other task to free the lock.
+**
+*****************************************************************************
+*/
+/*lint -e{715} */
+GERR GD_ETH_SetMacAddress(GD_HANDLE handle, GD_ETH_MacT macAddress)
+{
+    U32 i;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    /* set MAR0H (MAC Address)*/
+    GH_ETH_set_MAR0H(0x80000000+(macAddress[5]<<8)+macAddress[4]);
+    /* set MAR0L (MAC Address)*/
+    GH_ETH_set_MAR0L((macAddress[3]<<24)+(macAddress[2]<<16)+
+                     (macAddress[1]<<8)+(macAddress[0]<<0));
+    for(i=0; i<GD_ETH_MAC_ADDR_NUM; i++)
+    {
+        device->macaddr[i] = macAddress[i];
+    }
+    return GD_OK;
+}
+
+/*!
+*****************************************************************************
+** \brief Get Ethernet MAC address.
+**
+** This function returns Ethernet MAC address of the ethdevice in 'macAddress'.
+** It can be called at any time after GD_ETH_Init().
+**
+** \param index      Device index to identify Ethernet ethdevice (obsolete)
+** \param macAddress Ethernet MAC address, represented as byte buffer.
+**
+** \return
+**        - #GD_OK                  On success
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ETH_ERR_NULL_PTR    macAddress is NULL
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by another tasks.
+**                                    A task switch should be performed to allow
+**                                    the other task to free the lock.
+**
+*****************************************************************************
+*/
+/*lint -e{715} */
+GERR GD_ETH_GetMacAddress(GD_HANDLE handle, GD_ETH_MacT* pmacAddress)
+{
+    U32 i;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    if(pmacAddress == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    for(i=0; i<GD_ETH_MAC_ADDR_NUM; i++)
+    {
+       (*pmacAddress)[i] = device->macaddr[i];
+    }
+    return GD_OK;
+}
+GERR GD_ETH_SetIPAddress(GD_HANDLE handle, GD_ETH_IpT ipAddress)
+{
+    U32 i;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    for(i=0; i<GD_ETH_IP_ADDR_NUM; i++)
+    {
+        device->ipaddr[i] = ipAddress[i];
+    }
+    return GD_OK;
+}
+
+GERR GD_ETH_GetIPAddress(GD_HANDLE handle, GD_ETH_IpT* pipAddress)
+{
+    U32 i;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    if(pipAddress == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    for(i=0; i<GD_ETH_IP_ADDR_NUM; i++)
+    {
+        (*pipAddress)[i] = device->ipaddr[i];
+    }
+    return GD_OK;
+}
+
+GERR GD_ETH_GetPhyAddress(GD_HANDLE handle, U8* phy)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    if(phy == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    *phy = device->addr;
+    return GD_OK;
+}
+
+/*!
+*****************************************************************************
+** \brief Get Driver/Link status information
+**
+** This function returns information about the current ethdevice and link status.
+** If lastly-called function returned an error, you can check details
+** of error status with 'statParamsPtr->error'.
+**
+** \note Returned values are valid only if this function is called
+** after GD_ETH_Open.
+**
+** \param handle Ethernet driver handle (obsolete)
+** \param statParamsPtr Pointer to #GD_ETH_StatParamsT parameters
+**                      - speed:       Speed setting
+**                      - duplex:      Duplex mode setting
+**                      - loop:        Local loopback mode setting
+**                      - linkup:      Link is up or down
+**                      - error:       Error details
+** \return
+**        - #GD_OK                  On success
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ERR_INVALID_HANDLE  Invalid handle is specified
+**        - #GD_ETH_ERR_NULL_PTR    statParamsPtr is NULL
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by another tasks.
+**                                    A task switch should be performed to allow
+**                                    the other task to free the lock.
+**        - #GD_ETH_ERR_DATACCESS   Unknown error on data copy
+**
+** \sa GD_ETH_Read()
+** \sa GD_ETH_Write()
+*****************************************************************************
+*/
+/*lint -e{715} */
+GERR GD_ETH_GetStat(GD_HANDLE handle, GD_ETH_StatParamsT *statParamsPtr)
+{
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    return GD_ETH_PHY_GetWorkStatus(device->phyhandle, statParamsPtr);
+}
+
+/*!
+*****************************************************************************
+** \brief Check and update PHY-link status.
+**
+** This function checks and try to make the PHY-link up if it's in down-status.
+** Is is assumed to be called periodically in order to keep the internal
+** status updated.
+
+** \param handle Ethernet driver handle (obsolete)
+
+** \return
+**        - #GD_OK                  On success
+**        - #GD_ERR_NOT_INITIALIZED Ethernet driver is not initialized
+**        - #GD_ERR_INVALID_HANDLE  Invalid handle is specified
+**        - #GD_ETH_ERR_LOCK_FAIL   Handle lock failed. Try Again later.
+**                                    The handle may be locked by another tasks.
+**                                    A task switch should be performed to allow
+**                                    the other task to free the lock.
+**        - #GD_ETH_ERR_LINKDOWN    Link is still down.
+**
+** \sa GD_ETH_Open()
+*****************************************************************************
+*/
+/*lint -e{715} */
+GERR GD_ETH_CheckLink(GD_HANDLE handle)
+{
+    GERR retval;
+    GD_ETH_HandleT* device = (GD_ETH_HandleT*)handle;
+    if(device == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    retval = GD_ETH_PHY_GetWorkStatus(device->phyhandle, &device->workstat);
+    return retval;
+}
+
+GERR GD_ETH_SleepTime(U32 ulTime)
+{
+    GD_TIMER_Delay(ulTime);
+    return GD_OK;
+}
+
+void GD_ETH_SetNetReceiveFuc(void (*eth_rcve)(volatile U8* recbuf,U16 len))
+{
+    ethdevice.eth_rcve = eth_rcve;
+}
+
+//*****************************************************************************
+//*****************************************************************************
+//** Local Functions
+//*****************************************************************************
+//*****************************************************************************
+/*
+*****************************************************************************
+** \brief clear error count
+**
+** This function clears error counts.
+**
+** \param rw      Read/write direction
+**
+*****************************************************************************
+*/
+static void gd_ethClearErrorCount(void)
+{
+    ethdevice.error.lcCnt          = 0;
+    ethdevice.error.RUErrorCnt     = 0;
+    ethdevice.error.TUErrorCnt     = 0;
+    ethdevice.error.OvfErrorCnt    = 0;
+    ethdevice.error.UnfErrorCnt    = 0;
+    ethdevice.error.RWTErrorCnt    = 0;
+    ethdevice.error.TjtErrorCnt    = 0;
+    ethdevice.error.FbeRxErrorCnt  = 0;
+    ethdevice.error.FbeTxErrorCnt  = 0;
+}
+
+static void gd_eth_mac_InitRxTxBufDesc(GBOOL txtrue, GBOOL rxtrue)
+{
+    volatile GD_ETH_MAC_DesT* p = NULL;
+    U32 i;
+
+    if(rxtrue == GTRUE)
+    {
+        /* Initialize the rx description */
+        for(i = 0;i < ethdevice.RxbufferNum; i++)
+        {
+            p = (volatile GD_ETH_MAC_DesT*)((ethdevice.RxDesStartAddr) + (i * sizeof(GD_ETH_MAC_DesT)));
+            p->des0 = (U32)(ETH_DES_R0_OWN);
+            //p->des1 = ethdevice.SizePerRxBuffer - 1;//rbs1=2047,rbs2=0;
+            p->des1 = ethdevice.SizePerRxBuffer;//ethdevice.SizePerRxBuffer<2048
+            p->des2 = (U32)ethdevice.Rxbufferstart + (i *ethdevice.SizePerRxBuffer);
+            p->des3 = 0x0;
+        }
+
+        if(p != NULL)
+        {
+            /* mark the last buffer */
+            p->des1 |= ETH_DES_R1_RER;//RER=1,bit 25,last rxdesc
+        }
+    }
+
+    if(txtrue == GTRUE)
+    {
+        /* Initialize the tx description */
+        for(i = 0; i < ethdevice.TxbufferNum; i++)
+        {
+            p = (volatile GD_ETH_MAC_DesT*)((ethdevice.TxDesStartAddr) + (i * sizeof(GD_ETH_MAC_DesT)));
+            p->des0 = 0x00000000;
+            p->des1 = 0;//ETH_DES_T1_IC|ETH_DES_T1_FS|ETH_DES_T1_TCH;//0xA1000000(set IC(bit31),FS(bit29),CH1(bit24))
+            p->des2 = (U32)ethdevice.Txbufferstart + i * ethdevice.SizePerTxBuffer;
+            p->des3 = 0x0;
+        }
+
+        if(p != NULL)
+        {
+            /* mark the last buffer */
+            p->des1 |= ETH_DES_T1_TER;//TER=1,bit 25,last txdesc
+        }
+    }
+
+    return;
+
+}
+
+static GERR gd_eth_mac_InitRxTxBuffer(void)
+{
+    U32 RxAddOffset, TxAddOffset;
+
+    /* memory clear */
+    memset((void*)ethReceiveBuffer, 0, (MAX_SIZE_PER_DESANDBUFFER * MAX_RX_BUFFER_NUM + 32));
+    memset((void*)ethTranslateBuffer, 0, (MAX_SIZE_PER_DESANDBUFFER * MAX_TX_BUFFER_NUM + 32));
+
+    /* address align(32) */
+    RxAddOffset = ALIGN - (((U32)&ethReceiveBuffer[0]) % ALIGN);
+    TxAddOffset = ALIGN - (((U32)&ethTranslateBuffer[0]) % ALIGN);
+
+    /* Initialize MAC Host description */
+    ethdevice.RxbufferNum        = MAX_RX_BUFFER_NUM;
+    ethdevice.TxbufferNum        = MAX_TX_BUFFER_NUM;
+    ethdevice.SizePerRxBuffer    = MAX_SIZE_PER_DESANDBUFFER - sizeof(GD_ETH_MAC_DesT);
+    ethdevice.SizePerTxBuffer    = MAX_SIZE_PER_DESANDBUFFER - sizeof(GD_ETH_MAC_DesT);
+    ethdevice.TxDesStartAddr     = (U32)ethTranslateBuffer + TxAddOffset;
+    ethdevice.RxDesStartAddr     = (U32)ethReceiveBuffer + RxAddOffset;
+    ethdevice.Txbufferstart      = (U8*)((U32)ethdevice.TxDesStartAddr+(ethdevice.TxbufferNum)*sizeof(GD_ETH_MAC_DesT));
+    ethdevice.Rxbufferstart      = (U8*)((U32)ethdevice.RxDesStartAddr+(ethdevice.RxbufferNum)*sizeof(GD_ETH_MAC_DesT));
+    ethdevice.CurRxDesSite       = 0;
+    ethdevice.CurTxDesSite       = 0;
+    ethdevice.CurReadDesSite     = 0;
+    ethdevice.CurWriteDesSite    = 0;
+
+    /* Initialize the rx&tx buffer description */
+    gd_eth_mac_InitRxTxBufDesc(GTRUE, GTRUE);
+
+    return GD_OK;
+
+}
+
+static void gd_eth_SetNetReceiveBuffer(U8* revbuf)
+{
+    ethdevice.NetReceiveBuffer=(U8*)revbuf;
+}
+
+GD_HANDLE gd_eth_get_handle(void)
+{
+    return (GD_HANDLE)&ethdevice;
+}
+

+ 1045 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/gpio/gd_gpio.c

@@ -0,0 +1,1045 @@
+/*
+*******************************************************************************
+**
+** \file      gd_gpio.c
+**
+** \brief     GPIO driver (core functions).
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVDMAD AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \version
+**
+*******************************************************************************
+*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+
+#include <gh_gpio.h>
+#include <gh_debug_rct.h>
+
+#include "gd_int.h"
+#include "gd_gpio.h"
+
+#define GD_GPIO_PIN_COUNT 64
+#define GD_GPIO_LOW_NUM  21
+
+/*
+***********************************************************
+** local structures
+***********************************************************
+*/
+typedef struct
+{
+    U8             number;
+    GBOOL          in_use;
+    GD_GPIO_TYPE_E type;
+	GD_GPIO_INT_TRIGGER_E trigger;
+    void         (*notifier)(void);
+}GD_GPIO_HANDLE_S;
+
+enum
+{
+    GD_GPIO_IRQ_ENABLE = 1,
+    GD_GPIO_IRQ_CLEAR  = 0
+};
+
+/*
+***********************************************************
+** local variables
+***********************************************************
+*/
+static GD_GPIO_HANDLE_S gd_gpio_handle_array[GD_GPIO_PIN_COUNT];
+static GD_HANDLE        gd_gpio_int_handle = 0;
+static GD_GPIO_XREF_S   gd_gpio_xref_table[GD_GPIO_PIN_COUNT];//max maped function for each pin
+static U16              gd_Gpio_xref_table_count = 0;
+
+/*
+***********************************************************
+** local functions
+***********************************************************
+*/
+static GD_GPIO_HANDLE_S* gpioCheckHandle(GD_HANDLE handle);
+#if 1
+GISR1                    gpioIsr0();
+static GD_INT_DATA_S*    gpioIrqHandler(void);
+#endif
+static void gpioIntSetting(U8 number,GD_GPIO_INT_TRIGGER_E type);
+
+/*!
+*******************************************************************************
+**
+** \brief Initialise the driver.
+**
+** This function initialises the GPIO driver. It disables all GPIO
+** interrupts and registers the GPIO interrupt with the interrupt
+** driver.
+**
+** If the driver is already initialised,
+** #GD_ERR_ALREADY_INITIALIZED will be returned.
+**
+** \param pInitParams Pointer to an init structure GD_GPIO_INIT_PARAMS_S.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_ALREADY_INITIALIZED in case of error, already initialized
+** - #GD_ERR_BAD_PARAMTER in case of error if the given parameter structure
+**                        is invalid
+**
+** \sa GD_GPIO_Terminate()
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Init(GD_GPIO_INIT_PARAMS_S* pInitParams)
+{
+    U8 index;
+#if 1
+    GD_INT_OPEN_PARAMS_S irq;
+#endif
+    GD_HANDLE handle;
+
+    if(gd_gpio_int_handle != 0)
+    {
+        return( GD_ERR_ALREADY_INITIALIZED );
+    }
+
+    if(( pInitParams == NULL )||( pInitParams->xrefTable == NULL )||(pInitParams->xrefTableCount>(GD_GPIO_PIN_COUNT)))
+    {
+        return(GD_ERR_BAD_PARAMETER);
+    }
+
+    // set default value, and copy the gpio table.
+    for(index=0; index < GD_GPIO_PIN_COUNT; index++)
+                // open the default function mode of gpio.
+    {
+
+    // clean all status of gpio handle.
+        gd_gpio_handle_array[index].in_use   = GFALSE;
+        gd_gpio_handle_array[index].number   = 0;
+        gd_gpio_handle_array[index].type     = GD_GPIO_TYPE_UNDEFINED;
+		gd_gpio_handle_array[index].trigger  = 5;
+        gd_gpio_handle_array[index].notifier = NULL;
+    }
+    for(index=0; index < (GD_GPIO_PIN_COUNT); index++)
+    {
+        gd_gpio_xref_table[index].pin  = 0xff;  // index; ???
+        gd_gpio_xref_table[index].type = GD_GPIO_TYPE_UNDEFINED;
+    }
+    gd_Gpio_xref_table_count = pInitParams->xrefTableCount;
+    for(index=0; index < gd_Gpio_xref_table_count; index++)
+    {
+        gd_gpio_xref_table[index].pin  = pInitParams->xrefTable[index].pin;
+        gd_gpio_xref_table[index].type = pInitParams->xrefTable[index].type;
+    }
+
+    // register interrupt routine
+#if 1
+    irq.type            = GD_INT_GPIO0_IRQ;
+    irq.active          = GD_INT_INVERT_IRQ;
+    irq.sensitivity     = GD_INT_LEVEL_HIGH;
+    irq.priority        = GD_INT_LOW_PRIORITY;
+    irq.isrFct.lowPrio  = gpioIsr0;
+
+    if(pInitParams->irqPriority == GD_INT_MID_PRIORITY)
+    {
+        irq.priority        = GD_INT_MID_PRIORITY;
+        irq.isrFct.midPrio  = gpioIsr0;
+    }
+#endif
+
+    if(pInitParams && pInitParams->xrefTable)
+    {
+        for(index=0; index < GD_GPIO_PIN_COUNT; index++)
+        {
+            //gd_gpio_xref_table[index].pin  = pInitParams->xrefTable[index].pin;
+            //gd_gpio_xref_table[index].type = pInitParams->xrefTable[index].type;
+
+            if(pInitParams->xrefTable[index].type != GD_GPIO_TYPE_UNDEFINED)
+            {
+                GD_GPIO_Open(gd_gpio_xref_table[index].pin,
+                             gd_gpio_xref_table[index].type,
+                             0,
+                             &handle);
+
+                gd_gpio_handle_array[index].in_use      = GFALSE;
+                gd_gpio_handle_array[index].number      = 0;
+                gd_gpio_handle_array[index].type        = GD_GPIO_TYPE_UNDEFINED;
+                gd_gpio_handle_array[index].notifier    = NULL;
+            }
+        }
+    }
+    // this is used for gpio enable
+    GH_GPIO_set_INT_EN(1);
+	/*FIXME(heyong):gk7101  phy type*/
+	if(pInitParams->phyType == 0)//internal phy
+	{
+		GH_GPIO_set_PER_SEL((U32)0x00000002);
+	}
+	else //external phy
+	{
+		GH_GPIO_set_PER_SEL((U32)0x00000003);
+	}
+
+
+    // very special internal setting, hard wire CTS to 1
+    // this is required to start the uart later
+#if 1
+    //GH_GPIO_set_InConfig_SIGNAL(((GD_GPIO_TYPE_INPUT_UART0_CTS>>8) & 0xff)-1, 1);
+
+    if(GD_INT_Open(&irq, &gd_gpio_int_handle) != GD_OK)
+    {
+        gd_gpio_int_handle = 0;
+        return(GD_ERR_ALREADY_INITIALIZED);
+    }
+    GD_INT_SetHandler(irq.type, gpioIrqHandler);
+    GD_INT_Enable(&gd_gpio_int_handle, GD_INT_ENABLED);
+#endif
+    return(GD_OK);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief  Exits the driver.
+**
+** This function terminates the GPIO driver. It closes all open
+** GPIO lines and closes the GPIO interrupt handler with the
+** interrupt driver.
+**
+** If the driver was not initialised, #GD_OK will be returned anyway.
+**
+** \return
+** - #GD_OK if successfull
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Exit(void)
+{
+    U8 index;
+    GD_HANDLE handle;
+
+    if(gd_gpio_int_handle == 0)
+    {
+        return(GD_OK);
+    }
+
+    for(index=0; index < GD_GPIO_PIN_COUNT; index++)
+    {
+        handle = (GD_HANDLE)(&gd_gpio_handle_array[index]);
+        GD_GPIO_Close(&handle);
+
+        gd_gpio_handle_array[index].in_use      = GFALSE;
+        gd_gpio_handle_array[index].notifier    = NULL;
+    }
+    GH_GPIO_set_INT_EN_int_en(GD_GPIO_IRQ_CLEAR);
+    GD_INT_Enable(&gd_gpio_int_handle, GD_INT_DISABLED);
+    GD_INT_Close(&gd_gpio_int_handle);
+
+    gd_gpio_int_handle          = 0;
+    gd_Gpio_xref_table_count    = 0;
+    return(GD_OK);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Opens a GPIO.
+**
+** This function opens a GPIO and configures it.
+**
+** \param  number      Number of the GPIO to open.
+** \param  type        Operation type of the GPIO.
+** \param  pIntConfig  Pointer to an interrupt configuration structure.
+**                     You may pass a NULL pointer here to disable interrupt
+**                     generation for the given GPIO.
+** \param  pHandle     Pointer to a handle that shall be filled as return
+**                     value.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_ALREADY_OPEN in case of error if the given GPIO is already in use
+** - #GD_ERR_BAD_PARAMTER in case of error if either the given type is out of
+**                        range or if the given interrupt mode is not supported
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Open(U8 number, GD_GPIO_TYPE_E type, GD_GPIO_INT_CONFIG_S* pIntConfig, GD_HANDLE* pHandle)
+{
+    GD_GPIO_HANDLE_S* ph;
+    GERR gerr;
+    U32 temp_value = 0;
+    if(number >= GD_GPIO_PIN_COUNT)
+    {
+        return(GD_ERR_BAD_PARAMETER);
+    }
+
+    ph = &gd_gpio_handle_array[number];
+    if(ph->in_use == GTRUE)
+    {
+        *pHandle = (GD_HANDLE)ph;
+        return(GD_ERR_ALREADY_OPEN);
+    }
+
+    ph->number = number;
+    ph->type   = type;
+
+    ph->in_use = GTRUE;
+    gerr = GD_GPIO_SetType((GD_HANDLE)ph, type);
+    if(gerr != GD_OK)
+    {
+        ph->in_use = GFALSE;
+        return gerr;
+    }
+    ph->in_use = GFALSE;
+
+    if((GD_GPIO_GET_FUNC(type) == GD_GPIO_FUNC_IN) && (pIntConfig != NULL))
+    {
+        if(pIntConfig->enable == GFALSE)
+        {
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IE_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IE_LOW(temp_value);
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IE_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IE_HIGH(temp_value);
+            }
+            ph->notifier = NULL;
+        }
+        else
+        {
+            ph->notifier = pIntConfig->notifyFct;
+			ph->trigger  = pIntConfig->trigger;
+            gpioIntSetting(number, pIntConfig->trigger);
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IE_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IE_LOW(temp_value);
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IE_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IE_HIGH(temp_value);
+            }
+        }
+
+    }
+    else
+    {
+        ph->notifier = NULL;
+    }
+
+    ph->in_use = GTRUE;
+
+    *pHandle = (GD_HANDLE)ph;
+    return(GD_OK);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief  Opens a GPIO in function mode.
+**
+** This function opens a GPIO in function mode.
+**
+** \param  type     GPIO function type of the GPIO to open.
+** \param  pHandle  Pointer to a handle that shall be filled as return value.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_ALREADY_OPEN in case of error if the given GPIO is already in use
+** - #GD_ERR_BAD_PARAMTER in case of error if either the given type is out of
+**                        range or if the given interrupt mode is not supported
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_E type, GD_HANDLE* pHandle)
+{
+    U32 index;
+
+    for(index=0; index < gd_Gpio_xref_table_count; index++)
+    {
+        if(gd_gpio_xref_table[index].type == type)
+        {
+            return(GD_GPIO_Open( gd_gpio_xref_table[index].pin, type, 0, pHandle));
+        }
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Closes a GPIO.
+**
+** This function closes a GPIO and disables the related interrupt.
+** It shall also be used to close the special SDRAM od TSD GPIO lines.
+**
+** \param pHandle Pointer to a handle of a GPIO that shall be closed. The
+**                handle will be set to #NULL.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Close(GD_HANDLE* pHandle)
+{
+    GD_GPIO_HANDLE_S* ph;
+    U32 temp_value = 0;
+    if(pHandle == NULL)
+    {
+        return(GD_ERR_INVALID_HANDLE);
+    }
+
+    ph = gpioCheckHandle(*pHandle);
+    if(ph && (ph->in_use == GTRUE))
+    {
+
+        if(ph->number < GD_GPIO_LOW_NUM)
+        {
+            temp_value = GH_GPIO_get_IE_LOW();
+            temp_value = temp_value & (~(0x1 << ph->number));
+            GH_GPIO_set_IE_LOW(temp_value);
+        }
+        else
+        {
+            temp_value = GH_GPIO_get_IE_HIGH();
+            temp_value = temp_value & (~(0x1 << (ph->number - GD_GPIO_LOW_NUM)));
+            GH_GPIO_set_IE_HIGH(temp_value);
+        }
+        ph->in_use      = GFALSE;
+        ph->notifier    = NULL;
+        *pHandle        = 0;
+    }
+    return(GD_OK);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Closes a GPIO with type.
+**
+** This function closes a GPIO and disables the related interrupt.
+** It shall also be used to close the special SDRAM od TSD GPIO lines.
+**
+** \param type Pointer to the type of a GPIO that shall be closed.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_CloseWithType(U32 type)
+{
+    GD_GPIO_HANDLE_S* ph = NULL;
+    U16 index;
+    U32 number;
+
+    for(index=0; index < gd_Gpio_xref_table_count; index++)
+    {
+        if(gd_gpio_xref_table[index].type == type)
+        {
+            number          = gd_gpio_xref_table[index].pin;
+            ph              = &gd_gpio_handle_array[number];
+            ph->in_use      = GFALSE;
+            ph->notifier    = NULL;
+            return(GD_OK);
+        }
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+/*!
+*******************************************************************************
+**
+** \brief Changes the type of a GPIO.
+**
+** This function changes the type of an open GPIO. Note that it can
+** not be used for GPIO lines operating in function mode.
+**
+** \param  handle Handle of the GPIO to change.
+** \param  type   New type to configure.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+** - #GD_ERR_BAD_PARAMETER in case of error if the given type is out of range
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_SetType(GD_HANDLE handle, GD_GPIO_TYPE_E type)
+{
+    GD_GPIO_HANDLE_S* ph;
+
+    ph = gpioCheckHandle(handle);
+    if(!ph || (ph->in_use != GTRUE))
+    {
+        return(GD_ERR_INVALID_HANDLE);
+    }
+
+    switch(GD_GPIO_GET_FUNC(type))
+    {
+    case GD_GPIO_FUNC_OUT:     // out
+        GH_GPIO_set_OUTPUT_CFG_out_sel(ph->number, GD_GPIO_GET_OUT_SEL(type));
+        GH_GPIO_set_OUTPUT_CFG_oen_sel(ph->number, GD_GPIO_GET_OEN_SEL(type));
+        break;
+    case GD_GPIO_FUNC_IN:     // in
+        if(GD_GPIO_GET_IN_SEL(type) >= 2)
+        {
+            GH_GPIO_set_OUTPUT_CFG_out_sel(ph->number, GD_GPIO_GET_OUT_SEL(type));
+            GH_GPIO_set_OUTPUT_CFG_oen_sel(ph->number, GD_GPIO_GET_OEN_SEL(type));
+            GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(type) - 2, ph->number);
+        }
+        else
+        {
+            GH_GPIO_set_OUTPUT_CFG_out_sel(ph->number, GD_GPIO_GET_OUT_SEL(type));
+            GH_GPIO_set_OUTPUT_CFG_oen_sel(ph->number, GD_GPIO_GET_OEN_SEL(type));
+            //GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(type) - 2, ph->number);
+        }
+        break;
+    case GD_GPIO_FUNC_INOUT:     // in+out
+        // don't change, otherwise if out_sel at first might output a 0, then change to 1
+        GH_GPIO_set_INPUT_CFG_in_sel(GD_GPIO_GET_IN_SEL(type) - 2, ph->number);
+        GH_GPIO_set_OUTPUT_CFG_oen_sel(ph->number, GD_GPIO_GET_OEN_SEL(type));
+        GH_GPIO_set_OUTPUT_CFG_out_sel(ph->number, GD_GPIO_GET_OUT_SEL(type));
+        break;
+    default:
+        return(GD_ERR_BAD_PARAMETER);
+    }
+    if(GD_GPIO_GET_OEN_INVERT(type))
+    {
+        GH_GPIO_set_OUTPUT_CFG_oen_invert(ph->number, GD_GPIO_GET_OEN_INVERT(type));
+    }
+    GH_GPIO_set_OUTPUT_CFG_out_invert(ph->number, GD_GPIO_GET_OUT_INVERT(type));
+    // Pull up/down & 2mA......
+
+    if(GD_GPIO_GET_IOCTRL(type))
+    {
+        if(ph->number<40)
+        {
+            switch(ph->number%4)
+            {
+            case 0:
+                GH_PLL_set_IOCTRL_GPIO_io3((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 1:
+                GH_PLL_set_IOCTRL_GPIO_io0((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 2:
+                GH_PLL_set_IOCTRL_GPIO_io2((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 3:
+                GH_PLL_set_IOCTRL_GPIO_io1((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            }
+        }
+        else if(ph->number<44)
+        {
+            switch(ph->number%4)
+            {
+            case 0:
+                GH_PLL_set_IOCTRL_GPIO_io3((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 1:
+                GH_PLL_set_IOCTRL_GPIO_io1((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 2:
+                GH_PLL_set_IOCTRL_GPIO_io0((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            case 3:
+                GH_PLL_set_IOCTRL_GPIO_io2((ph->number)/4 + 3, GD_GPIO_GET_IOCTRL(type));
+                break;
+            }
+        }
+    }
+
+    ph->type = type; // add by francis
+    return(GD_OK);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Read a GPIO bit.
+**
+** This function reads the GPIO data bit given by the number element inside
+** the given handl.
+**
+** \param  handle Handle of the GPIO to read.
+** \param  pBit   Pointer to a data field which shall be filled.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+** - #GD_ERR_BAD_PARAMTER in case of error if the given type is not an input
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Read(GD_HANDLE handle, U8 *pBit)
+{
+    GD_GPIO_HANDLE_S* ph = gpioCheckHandle(handle);
+    U32 shift;
+    U32 bits;
+
+    if(!ph || (ph->in_use != GTRUE))
+    {
+        return(GD_ERR_INVALID_HANDLE);
+    }
+
+    if(GD_GPIO_GET_FUNC(ph->type) == GD_GPIO_FUNC_IN)
+    {
+        if(ph->number < GD_GPIO_LOW_NUM)
+        {
+            shift = ph->number;
+            bits  = GH_GPIO_get_DIN_LOW();
+        }
+        else
+        {
+            shift = ph->number - GD_GPIO_LOW_NUM;
+            bits  = GH_GPIO_get_DIN_HIGH();
+        }
+        *pBit = (U8)((bits >> shift) & 1);
+        return(GD_OK);
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Write a GPIO bit.
+**
+** This function writes the GPIO data bit given by the number element inside
+** the given handl.
+**
+** \param  handle   Handle of the GPIO to write.
+** \param  bit      Data bit to write.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+** - #GD_ERR_BAD_PARAMTER in case of error if the given type is not an output
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_Write(GD_HANDLE handle, U8 bit)
+{
+    GD_GPIO_HANDLE_S* ph = gpioCheckHandle(handle);
+
+    if(!ph || (ph->in_use != GTRUE))
+    {
+        return( GD_ERR_INVALID_HANDLE );
+    }
+
+    if(GD_GPIO_GET_FUNC(ph->type) == GD_GPIO_FUNC_OUT)
+    {
+        GH_GPIO_set_OUTPUT_CFG_out_sel(ph->number, bit&0x1);
+        return(GD_OK);
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Invert the GPIO output data.
+**
+** This function invert the GPIO data bit given by the number element inside
+** the given handl.
+**
+** \param  handle   Handle of the GPIO to invert.
+** \param  modeValue      Normal mode or invert mode.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+** - #GD_ERR_BAD_PARAMTER in case of error if the given type is not an output
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_ControlInvertData(GD_HANDLE handle, U8 modeValue)
+{
+    GD_GPIO_HANDLE_S* ph = gpioCheckHandle(handle);
+
+    if(!ph || (ph->in_use != GTRUE ))
+    {
+        return(GD_ERR_INVALID_HANDLE);
+    }
+
+    if(GD_GPIO_GET_FUNC(ph->type) == GD_GPIO_FUNC_OUT)
+    {
+        GH_GPIO_set_OUTPUT_CFG_out_invert(ph->number, modeValue);
+        return(GD_OK);
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Invert the GPIO enable mode.
+**
+** This function invert the GPIO enable mode given by the number element inside
+** the given handl.
+**
+** \param  handle   Handle of the GPIO to invert.
+** \param  modeValue      Normal mode or invert mode.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_INVALID_HANDLE in case of error if the given handle is invalid
+** - #GD_ERR_BAD_PARAMTER in case of error if the given type is not an output
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_ControlInvertEnable(GD_HANDLE handle, U8 modeValue)
+{
+    GD_GPIO_HANDLE_S* ph = gpioCheckHandle(handle);
+
+    if(!ph || (ph->in_use != GTRUE))
+    {
+        return(GD_ERR_INVALID_HANDLE);
+    }
+
+    if(GD_GPIO_GET_FUNC(ph->type) == GD_GPIO_FUNC_OUT)
+    {
+        GH_GPIO_set_OUTPUT_CFG_oen_invert(ph->number, modeValue);
+        return(GD_OK);
+    }
+    return(GD_ERR_BAD_PARAMETER);
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Enables an interrupt.
+**
+** This function enables a GPIO interrupt.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_BAD_PARAMETER in case of error, gpio not initialize
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_EnableInterrupt(void)
+{
+    if(gd_gpio_int_handle == 0)
+    {
+        return(GD_ERR_BAD_PARAMETER);
+    }
+    GH_GPIO_set_INT_EN_int_en(GD_GPIO_IRQ_ENABLE);
+    return(GD_OK );
+}
+
+/*!
+*******************************************************************************
+**
+** \brief Disables an interrupt.
+**
+** This function disables a GPIO interrupt.
+**
+** \param handle Handle of the GPIO to disable its interrupt.
+**
+** \return
+** - #GD_OK if successfull
+** - #GD_ERR_BAD_PARAMETER in case of error, gpio not initialize
+**
+*******************************************************************************
+*/
+GERR GD_GPIO_DisableInterrupt(void)
+{
+    if(gd_gpio_int_handle == 0)
+    {
+        return(GD_ERR_BAD_PARAMETER);
+    }
+    GH_GPIO_set_INT_EN_int_en(GD_GPIO_IRQ_CLEAR);
+    return(GD_OK);
+}
+
+/*
+*******************************************************************************
+**
+** \brief Check a given GPIO handle
+**
+** This function checks whether a given handle is valid.
+**
+** \param handle The GPIO handle to be checked
+**
+** \return
+** - non-NULL if the given handle is ok
+** - NULL in case of error if the given handle is invalid
+**
+*******************************************************************************
+*/
+static GD_GPIO_HANDLE_S* gpioCheckHandle(GD_HANDLE handle)
+{
+    GD_GPIO_HANDLE_S* check = (GD_GPIO_HANDLE_S*)handle;
+
+    if(check && ( check == &gd_gpio_handle_array[check->number]))
+    {
+        return(check);
+    }
+    return(0);
+}
+
+/*
+********************************************************************************
+**
+** GPIO interrupt handler function
+**
+********************************************************************************
+*/
+
+GISR1 gpioIsr0(void)
+{
+    GD_INT_HANDLER_F Handler;
+    GD_INT_DATA_S* intDataP;
+
+    Handler = GD_INT_GetHandler(GD_INT_GPIO0_IRQ);
+    intDataP = Handler();
+    if(intDataP->processor)
+    {
+        intDataP->processor(intDataP->data);
+    }
+}
+
+static GD_INT_DATA_S* gpioIrqHandler(void)
+{
+    static GD_INT_DATA_S intData;
+    U8 index = 0;
+
+    U32 gpioStatusHigh = 0;
+    U32 gpioStatusLow = 0;
+
+    intData.length      = 0;
+    intData.data        = NULL;
+    intData.processor   = NULL;
+
+
+    GD_GPIO_DisableInterrupt();
+
+    gpioStatusHigh = GH_GPIO_get_MIS_HIGH();
+    gpioStatusLow = GH_GPIO_get_MIS_LOW();
+
+    for(index=0; index < GD_GPIO_PIN_COUNT; index++)
+    {
+        if(index < GD_GPIO_LOW_NUM)
+        {
+            if((gpioStatusLow & (0x1 << index)) != 0)
+            {
+                if(gd_gpio_handle_array[index].notifier)
+                {
+                    gd_gpio_handle_array[index].notifier();
+                }
+            }
+        }
+        else
+        {
+            if((gpioStatusHigh & (0x1 << (index - GD_GPIO_LOW_NUM))) != 0)
+            {
+                if(gd_gpio_handle_array[index].notifier)
+                {
+                    gd_gpio_handle_array[index].notifier();
+                }
+            }
+        }
+    }
+    GH_GPIO_set_IC_HIGH(0xFFFFFFFF);
+    GH_GPIO_set_IC_LOW(0xFFFFFFFF);
+    GD_GPIO_EnableInterrupt();
+
+    return( &intData );
+}
+
+static void gpioIntSetting(U8 number,GD_GPIO_INT_TRIGGER_E type)
+{
+    U32 temp_value = 0;
+
+    switch(type)
+    {
+        case GD_GPIO_INT_TRIGGER_LOW_LEVEL:
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IS_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IS_LOW(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IEV_LOW(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IBE_LOW(temp_value);
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IS_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IS_HIGH(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IEV_HIGH(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IBE_HIGH(temp_value);
+
+            }
+            break;
+        case GD_GPIO_INT_TRIGGER_HIGH_LEVEL:
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IS_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IS_LOW(temp_value);
+
+				temp_value = GH_GPIO_get_IBE_LOW();
+				temp_value = temp_value & (~(0x1 <<number));
+				GH_GPIO_set_IBE_LOW(temp_value);
+
+                temp_value = GH_GPIO_get_IEV_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IEV_LOW(temp_value);
+
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IS_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IS_HIGH(temp_value);
+
+				temp_value = GH_GPIO_get_IBE_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+				GH_GPIO_set_IBE_HIGH(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IEV_HIGH(temp_value);
+
+            }
+            break;
+        case GD_GPIO_INT_TRIGGER_RISING_EDGE:
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IS_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IS_LOW(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IBE_LOW(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IEV_LOW(temp_value);
+
+
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IS_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IS_HIGH(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IBE_HIGH(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IEV_HIGH(temp_value);
+
+
+            }
+            break;
+        case GD_GPIO_INT_TRIGGER_FALLING_EDGE:
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IS_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IS_LOW(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IBE_LOW(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IEV_LOW(temp_value);
+
+
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IS_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IS_HIGH(temp_value);
+
+                temp_value = GH_GPIO_get_IBE_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IBE_HIGH(temp_value);
+
+
+                temp_value = GH_GPIO_get_IEV_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IEV_HIGH(temp_value);
+
+
+            }
+            break;
+        case GD_GPIO_INT_TRIGGER_BOTH_EDGE:
+            if(number < GD_GPIO_LOW_NUM)
+            {
+                temp_value = GH_GPIO_get_IS_LOW();
+                temp_value = temp_value & (~(0x1 << number));
+                GH_GPIO_set_IS_LOW(temp_value);
+
+
+                temp_value = GH_GPIO_get_IBE_LOW();
+                temp_value = temp_value | (0x1 << number);
+                GH_GPIO_set_IBE_LOW(temp_value);
+
+            }
+            else
+            {
+                temp_value = GH_GPIO_get_IS_HIGH();
+                temp_value = temp_value & (~(0x1 << (number - GD_GPIO_LOW_NUM)));
+                GH_GPIO_set_IS_HIGH(temp_value);
+
+
+                temp_value = GH_GPIO_get_IBE_HIGH();
+                temp_value = temp_value | (0x1 << (number - GD_GPIO_LOW_NUM));
+                GH_GPIO_set_IBE_HIGH(temp_value);
+
+            }
+            break;
+        default:
+            break;
+    }
+
+    return;
+}
+
+

+ 697 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/i2c/gd_i2c.c

@@ -0,0 +1,697 @@
+/******************************************************************************
+**
+** \file      gh_i2c.c
+**
+** \brief     I2C.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include <gtypes.h>
+
+#include "gd_i2c.h"
+#include "gd_gpio.h"
+#include "gd_int.h"
+#include "gd_timer.h"
+#include "gh_i2c.h"
+#ifndef GD_I2C_SOFTWARE /* do we use HW or SW I2C driver ?????? */
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+//#define I2C_START   0x04    //old
+//#define I2C_OPT     0x00     //old
+//#define I2C_RESPOND 0x02   //old
+//#define I2C_STOP    0x08      //old
+#define I2C_START   0x02
+#define I2C_OPT     0x00
+#define I2C_RESPOND_TURBO 0x010  //
+#define I2C_RESPOND 0x08  //
+#define I2C_STOP    0x01
+#define I2C_ACK     0x04
+//#define I2C_ACK     0x01     //old
+#define I2C_NO_ACK  0x00
+
+#define I2C_BLOCK_COUNT     2
+#define I2C_TIME_OUT        1000
+
+typedef     GD_INT_DATA_S* (*GD_I2C_ISR_T)(U8 channelIndex);
+typedef enum
+{
+    GD_I2C_STATE_IDLE       = 0,
+    GD_I2C_STATE_START_WRITE= 1,
+    GD_I2C_STATE_WRITE      = 2,
+    GD_I2C_STATE_START_READ = 3,
+    GD_I2C_STATE_READ       = 4,
+    GD_I2C_STATE_STOP       = 5,
+}gd_i2c_state_e;
+typedef struct
+{
+    U32                 channel;
+    U32                 using;
+    GD_I2C_SPEED_E      speed;
+    GD_I2C_MODE_E       mode;
+    GD_HANDLE           i2cHandle;      /* INT handle */
+
+    GBOOL               lock;
+    gd_i2c_state_e      eState;
+    GERR                i2cErrorState;  /* error state of block */
+
+    U8                  address;        /* i2c address */
+    U8*                 ReadBufferP;    /* read buffer pointer */
+    U8*                 WriteBufferP;   /* write buffer pointer */
+    U32                 rxLength;       /* read buffer length */
+    U32                 txLength;       /* write buffer length */
+
+    GD_I2C_ISR_T        i2cIsr;         /* ISR of the block */
+} GD_I2C_STATE_MACHINE_S;
+
+volatile GD_I2C_STATE_MACHINE_S i2c_state_machine_data[I2C_BLOCK_COUNT] = {0};
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+static U8                       I2cInitDone = 0;  //is or not already initialized
+
+static GISR1 gd_i2c_isr0(void)
+{
+    GD_INT_HANDLER_F Handler;
+    GD_INT_DATA_S*   intDataP;
+    Handler  = GD_INT_GetHandler( GD_INT_IDC_IRQ );
+    intDataP = Handler();
+    if ( intDataP->processor )
+        intDataP->processor( intDataP->data );
+}
+
+static GISR1 gd_i2c_isr1(void)
+{
+    GD_INT_HANDLER_F Handler;
+    GD_INT_DATA_S*   intDataP;
+    Handler  = GD_INT_GetHandler( GD_INT_IDC2_IRQ );
+    intDataP = Handler();
+    if ( intDataP->processor )
+        intDataP->processor( intDataP->data );
+}
+
+/*!
+*******************************************************************************
+**
+** \brief   This function processes the I2C interrupt (normal operation).
+**
+** \sa      FI_I2C_LowISR() <br>
+**          FI_I2C_MidISR()
+**
+******************************************************************************/
+static GD_INT_DATA_S* i2cHandler_0(void)
+{
+
+    GD_INT_DATA_S* intDataPtr = NULL;
+
+    intDataPtr = i2c_state_machine_data[GD_I2C_CHANNEL_ONE].i2cIsr(GD_I2C_CHANNEL_ONE);
+
+    return( intDataPtr );
+}
+
+/*!
+*******************************************************************************
+**
+** \brief   This function processes the I2C interrupt (normal operation).
+**
+** \sa      FI_I2C_LowISR() <br>
+**          FI_I2C_MidISR()
+**
+******************************************************************************/
+static GD_INT_DATA_S* i2cHandler_1(void)
+{
+
+    GD_INT_DATA_S* intDataPtr = NULL;
+
+    intDataPtr = i2c_state_machine_data[GD_I2C_CHANNEL_TWO].i2cIsr(GD_I2C_CHANNEL_TWO);
+
+    return( intDataPtr );
+}
+
+static GERR gd_i2c_ack(U32 channel, U8 ack)
+{
+    U32     timeout;
+    timeout = I2C_TIME_OUT;
+    while(timeout&&((GH_I2C_get_CONTROL(channel)&ack)!=ack))
+    {
+        timeout--;
+    }
+    if((timeout == 0) && ((GH_I2C_get_CONTROL(channel)&ack)!=ack))
+    {
+        return GD_ERR_I2C_NOACK;
+    }
+    return GD_OK;
+}
+
+static GD_INT_DATA_S* i2cHandler_AM(U8 channelIndex)
+{
+    static GD_INT_DATA_S intData;
+    volatile GD_I2C_STATE_MACHINE_S* i2c_handle_ptr = NULL;
+
+    intData.length      = 0;
+    intData.data        = NULL;
+    intData.processor   = NULL;
+
+    if (channelIndex >= I2C_BLOCK_COUNT)
+    {
+        return  &intData;
+    }
+    i2c_handle_ptr = &i2c_state_machine_data[channelIndex];
+
+    //status_reg = GH_I2C_get_STATUS(i2c_handle_ptr->channel);
+    //control_reg = GH_I2C_get_CONTROL(i2c_handle_ptr->channel);
+
+    switch(i2c_handle_ptr->eState)
+    {
+    case GD_I2C_STATE_START_WRITE:
+        if(gd_i2c_ack(i2c_handle_ptr->channel, I2C_RESPOND|I2C_ACK) == GD_OK)
+        {
+            GH_I2C_set_DATA_Data(i2c_handle_ptr->channel,*i2c_handle_ptr->WriteBufferP++);
+            i2c_handle_ptr->txLength--;
+            i2c_handle_ptr->eState = GD_I2C_STATE_WRITE;
+            GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+        }
+        else
+        {
+			GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT|I2C_STOP);
+            i2c_handle_ptr->i2cErrorState  = GD_ERR_I2C_START_NOACK;
+        }
+        break;
+    case GD_I2C_STATE_WRITE:
+        if(gd_i2c_ack(i2c_handle_ptr->channel, I2C_RESPOND|I2C_ACK) == GD_OK)
+        {
+            if(i2c_handle_ptr->txLength)
+            {
+                GH_I2C_set_DATA_Data(i2c_handle_ptr->channel,*i2c_handle_ptr->WriteBufferP++);
+                i2c_handle_ptr->txLength--;
+                GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+            }
+            else
+            {
+                if(i2c_handle_ptr->rxLength)
+                {
+                    GH_I2C_set_DATA(i2c_handle_ptr->channel,i2c_handle_ptr->address | 0x01);
+                    i2c_handle_ptr->eState = GD_I2C_STATE_START_READ;
+                    GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_START);
+                }
+                else
+                {
+                    i2c_handle_ptr->eState = GD_I2C_STATE_STOP;
+                    i2c_handle_ptr->i2cErrorState  = GD_OK;
+                    GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_STOP);
+                }
+            }
+        }
+        else
+        {
+			GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+            i2c_handle_ptr->i2cErrorState  = GD_ERR_I2C_NOACK;
+        }
+        break;
+    case GD_I2C_STATE_START_READ:
+        if(gd_i2c_ack(i2c_handle_ptr->channel, I2C_RESPOND|I2C_ACK) == GD_OK)
+        {
+            i2c_handle_ptr->eState = GD_I2C_STATE_READ;
+            i2c_handle_ptr->rxLength--;
+            if(i2c_handle_ptr->rxLength)
+            {
+                GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+            }
+            else
+            {
+                GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT|I2C_ACK);
+            }
+        }
+        else
+        {
+			GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT|I2C_STOP);
+            i2c_handle_ptr->i2cErrorState  = GD_ERR_I2C_READ_NOACK;
+        }
+        break;
+    case GD_I2C_STATE_READ:
+        if(i2c_handle_ptr->rxLength)
+        {
+            if(gd_i2c_ack(i2c_handle_ptr->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+            {
+				GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+                i2c_handle_ptr->i2cErrorState  = GD_ERR_I2C_READ_NOACK;
+                break;
+            }
+            i2c_handle_ptr->rxLength--;
+            *i2c_handle_ptr->ReadBufferP++ = GH_I2C_get_DATA_Data(i2c_handle_ptr->channel);
+
+            if(i2c_handle_ptr->rxLength)
+            {
+                GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+            }
+            else
+            {
+                GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT|I2C_ACK);
+            }
+        }
+        else
+        {
+            if(gd_i2c_ack(i2c_handle_ptr->channel, I2C_RESPOND|I2C_NO_ACK) != GD_OK)
+            {
+				GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_OPT);
+                i2c_handle_ptr->i2cErrorState  = GD_ERR_I2C_READ_NOACK;
+                break;
+            }
+            *i2c_handle_ptr->ReadBufferP++ = GH_I2C_get_DATA_Data(i2c_handle_ptr->channel);
+
+            i2c_handle_ptr->eState = GD_I2C_STATE_STOP;
+            i2c_handle_ptr->i2cErrorState  = GD_OK;
+            GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_STOP);
+        }
+        break;
+    case GD_I2C_STATE_STOP:
+        i2c_handle_ptr->eState = GD_I2C_STATE_IDLE;
+        i2c_handle_ptr->i2cErrorState  = GD_OK;
+        break;
+    case GD_I2C_STATE_IDLE:
+        i2c_handle_ptr->i2cErrorState  = GD_OK;
+        break;
+    }
+    return( &intData );
+}
+
+static GERR i2cHandleCheck( GD_HANDLE pHandle )
+{
+    U32                ii;
+    /* check if handle is valid */
+    for (ii = 0; ii < I2C_BLOCK_COUNT; ii++)
+    {
+        if ((pHandle == (GD_HANDLE)(&i2c_state_machine_data[ii])) && (i2c_state_machine_data[ii].using))
+        {
+            return GD_OK;
+        }
+    }
+    if (ii >= I2C_BLOCK_COUNT)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    return GD_OK;
+}
+
+GERR GD_I2C_Init( GD_I2C_INIT_PARAMS_S* paramsP )
+{
+    U32     i;
+    GERR    ret;
+    GD_INT_OPEN_PARAMS_S    paramsInt;
+    GD_HANDLE               i2cHandle  = 0;
+
+    /* check if already initialized */
+    if(I2cInitDone != 0)
+    {
+        return GD_ERR_ALREADY_INITIALIZED;
+    }
+
+    for (i = 0; i < I2C_BLOCK_COUNT; i++)
+    {
+        i2c_state_machine_data[i].channel       = 0;
+        i2c_state_machine_data[i].speed         = GD_I2C_100KBPS;  // 100kbps
+        i2c_state_machine_data[i].using         = 0;
+        i2c_state_machine_data[i].lock          = GFALSE;
+    }
+    /* Open the I2C interrupt */
+    paramsInt.active      = GD_INT_NO_INVERT_IRQ;
+    paramsInt.priority    = paramsP->priority;
+    paramsInt.sensitivity = GD_INT_LEVEL_HIGH;
+
+    paramsInt.type        = GD_INT_IDC_IRQ;
+    paramsInt.isrFct.lowPrio = gd_i2c_isr0;
+    ret = GD_INT_Open(&paramsInt, &i2cHandle);
+    i2c_state_machine_data[GD_I2C_CHANNEL_ONE].i2cHandle = i2cHandle;
+    if (ret != GD_OK)
+        return GD_ERR_I2C_INT_ERR;
+    GD_INT_SetHandler( paramsInt.type, i2cHandler_0);
+
+    paramsInt.type        = GD_INT_IDC2_IRQ;
+    paramsInt.isrFct.lowPrio = gd_i2c_isr1;
+    ret = GD_INT_Open(&paramsInt, &i2cHandle);
+    i2c_state_machine_data[GD_I2C_CHANNEL_TWO].i2cHandle = i2cHandle;
+    if (ret != GD_OK)
+        return GD_ERR_I2C_INT_ERR;
+    GD_INT_SetHandler( paramsInt.type, i2cHandler_1);
+    GD_INT_Enable(&i2cHandle, GD_INT_DISABLED);
+
+    I2cInitDone = 1;
+
+    return GD_OK;
+}
+
+
+GERR GD_I2C_Exit( void )
+{
+    U32            ii;
+
+    if( I2cInitDone == 0 )
+        return( GD_ERR_NOT_INITIALIZED );
+
+    for (ii = 0; ii < I2C_BLOCK_COUNT; ii++)
+    {
+        i2c_state_machine_data[ii].using    = 0;
+    }
+    I2cInitDone = 0;
+
+    return( GD_OK );
+}
+
+GERR GD_I2C_Open( GD_I2C_OPEN_PARAMS_S *openParamsP, GD_HANDLE* pHandle  )
+{
+    U16             prescale;
+    GD_HANDLE       Gpiohandle;
+
+    if((openParamsP == NULL) || (openParamsP->speed == 0))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    switch(openParamsP->channel)
+    {
+    case GD_I2C_CHANNEL_ONE:
+        GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_INOUT_I2C_DATA, &Gpiohandle);
+        GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_INOUT_I2C_CLK, &Gpiohandle);
+        break;
+    case GD_I2C_CHANNEL_TWO:
+        GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_INOUT_I2C_DATA2, &Gpiohandle);
+        GD_GPIO_OpenFunctionMode(GD_GPIO_TYPE_INOUT_I2C_CLK2, &Gpiohandle);
+        break;
+        //GH_GPIO_set_AFSEL(1, GH_GPIO_get_AFSEL() | 0x10);
+    }
+    if(i2c_state_machine_data[openParamsP->channel].using)
+    {
+        return GD_ERR_DEVICE_BUSY;
+    }
+    i2c_state_machine_data[openParamsP->channel].channel      = openParamsP->channel;
+    i2c_state_machine_data[openParamsP->channel].using        = GTRUE;
+    i2c_state_machine_data[openParamsP->channel].speed        = openParamsP->speed;
+    i2c_state_machine_data[openParamsP->channel].mode         = openParamsP->mode;
+
+    // IDC period = (IDC_clk) / (4*(prescale[15:0]+1) + 2)
+    // (prescale[15:0] = ((IDC_clk / period - 2) / 4) - 1
+    prescale = ((GD_GET_APB_ClkHz()/(U32)openParamsP->speed - 2) >> 2) - 1;
+    // enable
+    GH_I2C_set_ENABLE_en(openParamsP->channel, 0);
+
+    GH_I2C_set_PRESCALEL_scale(openParamsP->channel, (prescale & 0xFF));
+    GH_I2C_set_PRESCALEH_scale(openParamsP->channel, (prescale & 0xFF00)>>8);
+    GH_I2C_set_ENABLE_en(openParamsP->channel, 1);
+
+    // clear the DR
+    i2c_state_machine_data[openParamsP->channel].i2cIsr = i2cHandler_AM;
+
+    //
+    *pHandle = (GD_HANDLE)(&i2c_state_machine_data[openParamsP->channel]);
+    return( GD_OK );
+}
+
+GERR GD_I2C_Close( GD_HANDLE *pHandle )
+{
+    GERR            ret;
+    GD_I2C_STATE_MACHINE_S    *device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device = (GD_I2C_STATE_MACHINE_S *)(*pHandle);
+
+    ret = i2cHandleCheck(*pHandle);
+    if (GD_OK != ret)
+    {
+        return ret;
+    }
+
+    device->using = GFALSE;
+    pHandle = NULL;
+
+    GH_I2C_set_ENABLE_en(device->channel, 0);
+    return( GD_OK );
+}
+
+GERR GD_I2C_Process( GD_HANDLE* pHandle, U8 address, U8* writeDataP, U32 wrDataLen, U8* readDataP, U32 rdDataLen )
+{
+    U32     stTime, endTime;
+    S32     diff, timeOut;
+    GD_I2C_STATE_MACHINE_S    *i2c_handle_ptr;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    i2c_handle_ptr = (GD_I2C_STATE_MACHINE_S *)(*pHandle);
+
+    if( i2c_handle_ptr->i2cErrorState == GD_ERR_I2C_BUSY )
+        return GD_ERR_I2C_BUSY;
+    if (i2c_handle_ptr->speed == GD_I2C_100KBPS)
+        timeOut = ((wrDataLen+rdDataLen)<<4)/100 + I2C_TIME_OUT;
+    else
+        timeOut = ((wrDataLen+rdDataLen)<<4)/400 + I2C_TIME_OUT;
+
+    //GD_INT_Enable(&i2c_handle_ptr->i2cHandle, GD_INT_ENABLED);
+    /* set pointer buffer for ISR */
+    i2c_handle_ptr->WriteBufferP = writeDataP;
+    i2c_handle_ptr->ReadBufferP  = readDataP;
+    i2c_handle_ptr->txLength     = wrDataLen;
+    i2c_handle_ptr->rxLength     = rdDataLen;
+    i2c_handle_ptr->address      = address;
+
+	if(writeDataP && (wrDataLen > 0))//dx8 chip only do write opreation when need. youbo,20170926
+	{
+	    GH_I2C_set_DATA(i2c_handle_ptr->channel,address & 0xFE);
+	    i2c_handle_ptr->eState = GD_I2C_STATE_START_WRITE;
+	}
+	else
+	{
+        GH_I2C_set_DATA(i2c_handle_ptr->channel,address | 0x01);
+	    i2c_handle_ptr->eState = GD_I2C_STATE_START_READ;
+	}
+	
+    i2c_handle_ptr->i2cErrorState= GD_ERR_I2C_BUSY;
+
+    GH_I2C_set_CONTROL(i2c_handle_ptr->channel,I2C_START);
+
+    GD_INT_Enable(&i2c_handle_ptr->i2cHandle, GD_INT_ENABLED);
+
+    stTime = GD_TIMER_ReadTimerStamp();
+    endTime= GD_TIMER_ReadTimerStamp();
+    do
+    {
+        endTime= GD_TIMER_ReadTimerStamp();
+        diff = endTime - stTime;
+        if(stTime > endTime) /* check overflow */
+            diff = ((diff < 0L) ? -diff : diff); /* C-LIB code for labs() */
+    }while((i2c_handle_ptr->i2cErrorState  == GD_ERR_I2C_BUSY) && (diff < timeOut));
+
+    if (i2c_handle_ptr->i2cErrorState  == GD_ERR_I2C_BUSY)
+        i2c_handle_ptr->i2cErrorState  = GD_ERR_TIMEOUT;
+    /* disable IRQ mask */
+    GD_INT_Enable(&(i2c_handle_ptr->i2cHandle), GD_INT_DISABLED);
+
+    return i2c_handle_ptr->i2cErrorState ;
+}
+
+GERR GD_I2C_Write( GD_HANDLE *pHandle,U8 address,U8* buffer, U32 bytes )
+{
+    GERR            ret;
+    GD_I2C_STATE_MACHINE_S    *device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device = (GD_I2C_STATE_MACHINE_S *)(*pHandle);
+    /* check if handle is valid */
+    ret = i2cHandleCheck(*pHandle);
+    if (GD_OK != ret)
+    {
+        return ret;
+    }
+    switch(device->mode)
+    {
+    case GD_I2C_TURBO_MODE:
+        //if(bytes >= 63)
+        //{
+        //    return GD_ERR_I2C_FIFO_OVERFLOW;
+        //}
+        GD_INT_Enable(&device->i2cHandle, GD_INT_DISABLED);
+        GH_I2C_set_FMCONTROL(device->channel,I2C_START);
+        GH_I2C_set_FMDATA(device->channel,address & 0xFE);
+		//GH_I2C_set_FMCONTROL(device->channel,I2C_START);
+
+        while(bytes)
+        {
+        	//GM_Printf("turbo write: 0x%x\n", *buffer);
+            GH_I2C_set_FMDATA(device->channel,*buffer++);
+			//GD_TIMER_Delay(5);
+            bytes--;
+        }
+		//GD_TIMER_Delay(20);
+        GH_I2C_set_FMCONTROL(device->channel,I2C_STOP|I2C_RESPOND_TURBO);
+        //if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+        //{
+        //    return GD_ERR_I2C_SL_NACK;
+        //}
+        //GD_TIMER_Delay(20);
+        // clear FIFO
+        GH_I2C_set_CONTROL(device->channel,0x10);
+        break;
+    case GD_I2C_INTERRUPT:
+        return GD_I2C_Process(pHandle, address, buffer, bytes, NULL, 0);
+    case GD_I2C_NORMAL:
+    default:
+        GD_INT_Enable(&device->i2cHandle, GD_INT_DISABLED);
+
+		GH_I2C_set_DATA(device->channel,address & 0xFE);
+        GH_I2C_set_CONTROL(device->channel,I2C_START);
+        if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+        {
+            return GD_ERR_I2C_START_NOACK;
+        }
+        while(bytes)
+        {
+            GH_I2C_set_DATA_Data(device->channel,*buffer++);
+            GH_I2C_set_CONTROL(device->channel,I2C_OPT);
+            bytes--;
+            if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+            {
+                return GD_ERR_I2C_DATA_NOACK;
+            }
+        }
+        GH_I2C_set_CONTROL(device->channel,I2C_STOP);
+        break;
+    }
+    return( GD_OK );
+}
+
+GERR GD_I2C_Read( GD_HANDLE* pHandle, U8 address, U8* regbuffer,U32 regbytes,U8* buffer, U32 bytes )
+{
+    GERR    ret;
+    GD_I2C_STATE_MACHINE_S    *device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device = (GD_I2C_STATE_MACHINE_S *)(*pHandle);
+    /* check if handle is valid */
+    ret = i2cHandleCheck(*pHandle);
+    if (GD_OK != ret)
+    {
+        return ret;
+    }
+    switch(device->mode)
+    {
+    case GD_I2C_INTERRUPT:
+        return GD_I2C_Process(pHandle, address, regbuffer, regbytes, buffer, bytes);
+    case GD_I2C_TURBO_MODE:  // write operation only.
+    case GD_I2C_NORMAL:
+    default:
+        GD_INT_Enable(&device->i2cHandle, GD_INT_DISABLED);
+
+		if(regbytes)//dx8 chip only do write opreation when need. youbo,20170926
+		{
+	        GH_I2C_set_DATA(device->channel,address & 0xFE);
+	        GH_I2C_set_CONTROL(device->channel,I2C_START);
+	        if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+	        {	
+	            return GD_ERR_I2C_START_NOACK;
+	        }
+		}
+		
+        while(regbytes)
+        {
+            GH_I2C_set_DATA_Data(device->channel,*regbuffer++);
+            GH_I2C_set_CONTROL(device->channel,I2C_OPT);
+            regbytes--;
+            if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+            {
+                return GD_ERR_I2C_ADDR_NOACK;
+            }
+        }
+
+        GH_I2C_set_DATA(device->channel,address | 0x01);
+        GH_I2C_set_CONTROL(device->channel,I2C_START);
+        if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+        {
+            return GD_ERR_I2C_RESTART_NOACK;
+        }
+        while(bytes)
+        {
+            bytes--;
+            if(bytes)
+            {
+                GH_I2C_set_CONTROL(device->channel,I2C_OPT);
+                if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_ACK) != GD_OK)
+                {
+                    return GD_ERR_I2C_READ_NOACK;
+                }
+            }
+            else
+            {
+                GH_I2C_set_CONTROL(device->channel,I2C_OPT|I2C_ACK);
+                if(gd_i2c_ack(device->channel, I2C_RESPOND|I2C_NO_ACK) != GD_OK)
+                {
+                    return GD_ERR_I2C_READ_NOACK;
+                }
+            }
+            *buffer++ = GH_I2C_get_DATA_Data(device->channel);
+        }
+        GH_I2C_set_CONTROL(device->channel,I2C_STOP);
+        break;
+    }
+    return( GD_OK );
+}
+
+GERR GD_I2C_SetOperationMode(GD_I2C_CHANNEL_E channel,GD_I2C_OPEN_MODE_E operationMode)
+{
+    return GD_OK;
+}
+
+GERR GD_I2C_SetProtocol(GD_HANDLE *handleP,GD_I2C_PROTOCOL_E protocol)
+{
+    return GD_OK;
+}
+
+GERR GD_I2C_SetMode(GD_HANDLE *pHandle, GD_I2C_MODE_E Mode)
+{
+    GERR            ret;
+    GD_I2C_STATE_MACHINE_S    *device;
+    if(pHandle == NULL)
+    {
+        return GD_ERR_INVALID_HANDLE;
+    }
+    device = (GD_I2C_STATE_MACHINE_S *)(*pHandle);
+    /* check if handle is valid */
+    ret = i2cHandleCheck(*pHandle);
+    if (GD_OK != ret)
+    {
+        return ret;
+    }
+    switch(Mode)
+    {
+    case GD_I2C_TURBO_MODE:
+        device->mode = GD_I2C_TURBO_MODE;
+        break;
+    case GD_I2C_INTERRUPT:
+        device->mode = GD_I2C_INTERRUPT;
+        break;
+    case GD_I2C_NORMAL:
+    default:
+        device->mode = GD_I2C_NORMAL;
+        break;
+    }
+    return GD_OK;
+}
+
+#endif
+/*----------------------------------------------------------------------------*/
+/* end of file                                                                */
+/*----------------------------------------------------------------------------*/
+

+ 918 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/i2c/gd_i2c_sw.c

@@ -0,0 +1,918 @@
+/******************************************************************************
+**
+** \file      gd_i2c_sw.c
+**
+** \brief     I2C driver.
+**
+**            (C) Goke Microelectronics China 2002 - 2007
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+**            This file implements the I2C API in software and replaces the
+**            I2C hardware driver (\c gd_i2c.c). The driver uses a software
+**            I2C protocol where the GPIO pins are accessed directly.
+**
+** \note      You can only use hardware or software I2C. The option is
+**            toggeled via compiler switch \c "CFLAGS += -DGD_I2C_SOFTWARE".
+**
+** \version   \$Id: gd_i2c_sw.c,v 1.17 2010/07/21 13:14:00 benny Exp $
+**
+******************************************************************************/
+/* to enable the software I2C (by using gpio read/write) instead of hardware */
+/* I2C modify makfile via:                                                   */
+/*       CFLAGS_USER += -DGD_I2C_SOFTWARE                                    */
+/* and do not change the source code                                         */
+
+/*---------------------------------------------------------------------------*/
+/* include files                                                             */
+/*---------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <string.h>
+
+#include "gtypes.h"
+#include "gd_int.h"
+#include "gd_i2c.h"
+#include "gd_gpio.h"
+#include "gd_timer.h"
+
+#ifdef GD_I2C_SOFTWARE /* do we use HW or SW I2C driver ?????? */
+//#define GD_I2C_SW_DELAYS          1
+/*---------------------------------------------------------------------------*/
+/* local defines                                                             */
+/*---------------------------------------------------------------------------*/
+#define SI2C_BUS_FREE_TIME        0x080 // Bus free for 4,7  or 1,3 us
+
+#ifdef GD_I2C_SW_DELAYS
+#define SI2C_SDA_START_TIME       0x040 // hold time at start for 4,0 or 0,6
+#define SI2C_SCL_START_TIME       0x040 // low time after start for 4,45 or 1,2
+#define SI2C_SETUP_STOP_TIME      0x040 // low time after start for 4,0  or 0,6
+#define SI2C_SETUP_DATA_TIME      0x003 // low time after start for 0,25 or 0,1
+#define SI2C_HIGH_HOLD_TIME       0x040 // hold time at start for 4,0  or 0,6
+#define SI2C_LOW_HOLD_TIME        0x070 // Bus free for 4,7  or 1,3
+#else
+#define SI2C_SDA_START_TIME       0x00 // hold time at start for 4,0 or 0,6
+#define SI2C_SCL_START_TIME       0x00 // low time after start for 4,45 or 1,2
+#define SI2C_SETUP_STOP_TIME      0x00 // low time after start for 4,0  or 0,6
+#define SI2C_SETUP_DATA_TIME      0x00 // low time after start for 0,25 or 0,1
+#define SI2C_HIGH_HOLD_TIME       0x00 // hold time at start for 4,0  or 0,6
+#define SI2C_LOW_HOLD_TIME        0x00 // Bus free for 4,7  or 1,3
+#endif
+
+#define MAX_CHECK_WRA             0x40000
+#define MAX_DATA_LENGTH           0xF000
+
+#define I2C_SW_SDA_HIGH_HOLD_TIME 0x002 // low time after start for 4,0  or 0,6
+#define I2C_SW_SDA_LOW_HOLD_TIME  0x003 // low time after start for 0,25 or 0,1
+#define I2C_SW_SCL_HIGH_HOLD_TIME 0x050 // hold time at start for 4,0  or 0,6
+#define I2C_SW_SCL_LOW_HOLD_TIME  0x001 // low time after start for 4,45 or 1,2
+
+#define I2C_DATA_TYPE_OUTPUT_0  GD_GPIO_TYPE_OUTPUT_0
+#define I2C_DATA_TYPE_OUTPUT_1  GD_GPIO_TYPE_OUTPUT_1
+#define I2C_DATA_TYPE_INPUT     GD_GPIO_TYPE_INPUT_0
+#define I2C_CLK_TYPE_OUTPUT_0   GD_GPIO_TYPE_OUTPUT_0
+#define I2C_CLK_TYPE_OUTPUT_1   GD_GPIO_TYPE_OUTPUT_1
+#define I2C_CLK_TYPE_INPUT      GD_GPIO_TYPE_INPUT_0
+
+/*---------------------------------------------------------------------------*/
+/* local data                                                                */
+/*---------------------------------------------------------------------------*/
+static U8        i2c_cvs_revision[] = "$Revision: 1.17 $";
+static GBOOL     i2c_initialized    = GFALSE;
+static GD_HANDLE i2c_sda_handle     = NULL;
+static GD_HANDLE i2c_scl_handle     = NULL;
+static S8        i2c_sda_pin        = -1;
+static S8        i2c_scl_pin        = -1;
+static S8        i2c_sda_pin2       = -1;
+static S8        i2c_scl_pin2       = -1;
+
+
+/*---------------------------------------------------------------------------*/
+/* local functions                                                           */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_writeSDA(U16 waitTime, U8 data);
+GERR I2C_SW_writeSDAnoCheck(U16 waitTime, U8 data);
+GERR I2C_SW_writeSCL(U16 waitTime, U8 data);
+void I2C_SW_readSCL(U8 *pScl);
+void I2C_SW_readSDA(U8 *pSda);
+void I2C_SW_gpioIicStart();
+GERR I2C_SW_gpioIicReStart();
+GERR I2C_SW_gpioIicStop();
+
+GERR I2C_SW_gpioIicRdAck();
+GERR I2C_SW_gpioIicWrAck();
+GERR I2C_SW_gpioIicWrNoAck();
+GERR I2C_SW_gpioIicWrByte(U8 Data);
+GERR I2C_SW_gpioIicRdByte(U8 *pData);
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Cancel the write/read process of I2C bus.
+**
+** \sa      GD_I2C_Read() <br>
+**          GD_I2C_Write()
+**
+******************************************************************************/
+void GD_I2C_CancelProcess(GD_HANDLE *handleP)
+{
+    GERR gerr;
+    int i;
+
+    if (i2c_initialized == GFALSE)
+        return; // GD_ERR_NOT_INITIALIZED;
+
+    GD_GPIO_Close(&i2c_sda_handle);
+    GD_GPIO_Close(&i2c_scl_handle);
+    gerr = GD_GPIO_Open(i2c_sda_pin, I2C_DATA_TYPE_OUTPUT_1, NULL, &i2c_sda_handle);
+    gerr = GD_GPIO_Open(i2c_scl_pin, I2C_CLK_TYPE_OUTPUT_1, NULL, &i2c_scl_handle);
+    GD_GPIO_Write(i2c_sda_handle, 1);            // set SDA to high
+    GD_GPIO_Write(i2c_scl_handle, 1);            // set SCL to high
+
+    for (i = 0;i < SI2C_BUS_FREE_TIME;i++); // delay loop
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Closes an I2C channel.
+**
+** \param  handleP Pointer to handle which can be used to control the hardware.
+**
+** \return Possible return codes:
+**         - \c #GD_OK
+**         - \c #GD_ERR_NOT_INITIALIZED
+**
+** \sa     GD_I2C_Open()
+**
+******************************************************************************/
+GERR GD_I2C_Close(GD_HANDLE *handleP)
+{
+    if (i2c_initialized == GFALSE)
+        return GD_ERR_NOT_INITIALIZED;
+    if(i2c_sda_handle)
+    {
+        GD_GPIO_Close(&i2c_sda_handle);        // set SDA to high
+        i2c_sda_handle = NULL;
+    }
+    if(i2c_scl_handle)
+    {
+        GD_GPIO_Close(&i2c_scl_handle);        // set SDA to high
+        i2c_scl_handle = NULL;
+    }
+
+    *handleP = NULL;
+    return GD_OK;
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Get the current driver version.
+**
+** \return Pointer to the version string.
+**
+******************************************************************************/
+U8 *GD_I2C_GetRevisionString(void)
+{
+    return(i2c_cvs_revision);
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Initializes the driver.
+**
+**         This function initializes the driver. It is called only once
+**         during boot time. It sets the ISR and the dedicated GPIO pins
+**         for SDA and SCL.
+**
+**         The GPIO pins must be i2c_initialized in this function for each channel.
+**         With the open function you are able to select different channels
+**         driving multiple devices on each channel using different slave
+**         adresses.
+**
+**         Currently the driver supports only one channel.
+**
+** \note   If you are using the software I2C driver (\c gd_i2c_sw.c) you have
+**         to assign GPIO pins for SDA and SCL of the dedicated channel.
+**         If you are using the hardware driver (\c gd_i2c.c) the GPIO pins
+**         are autmatically assigned (only SmartMPEG and SmartMPEG-E).
+**
+** \note   SmartMPEG-L has no hardware I2C and therefore can not not use the
+**         driver (\c gd_i2c.c).
+**
+** \param  paramsP  Pointer to init parameter structure.
+**
+** \return Possible return codes:
+**         - \c #GD_OK
+**         - \c #GD_ERR_ALREADY_INITIALIZED
+**         - \c #GD_ERR_I2C_INT_ERR
+**         - \c #GD_ERR_BAD_PARAMETER
+**
+** \sa     GD_I2C_Open()
+** \sa     \c GD_I2C_INIT_PARAMS_S
+**
+******************************************************************************/
+GERR GD_I2C_Init(GD_I2C_INIT_PARAMS_S* paramsP)
+{
+    GERR gerr;
+
+    if( i2c_initialized == GTRUE )
+        return  GD_ERR_ALREADY_INITIALIZED;
+
+    i2c_sda_pin  = paramsP->gpioSdaPinCh1;
+    i2c_scl_pin  = paramsP->gpioSclPinCh1;
+    i2c_sda_pin2 = paramsP->gpioSdaPinCh2;
+    i2c_scl_pin2 = paramsP->gpioSclPinCh2;
+
+    i2c_initialized = GTRUE;
+
+    if ((paramsP->mode != GD_I2C_AUTO_MASTER_MODE)&&
+        (paramsP->mode != GD_I2C_GENERIC_MASTER_MODE))
+        return GD_ERR_BAD_PARAMETER;
+
+    return GD_OK;
+}
+
+GERR GD_I2C_Exit( void )
+{
+    if( i2c_initialized == 0 )
+        return( GD_ERR_NOT_INITIALIZED );
+
+    i2c_sda_pin        = -1;
+    i2c_scl_pin        = -1;
+    i2c_sda_pin2       = -1;
+    i2c_scl_pin2       = -1;
+    i2c_initialized = GFALSE;
+
+    return( GD_OK );
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Opens an I2C channel.
+**
+**         Here we set the datarate of the selected channel.
+**         Currently only one channel is supported.
+**
+** \param  parameterP Pointer to the structure containing the settings for a
+**                    specific I2C request.
+** \param  handleP    Pointer to handle which can be used to control the hardware.
+**
+** \return Possible return codes:
+**         - \c #GD_OK
+**
+** \sa     GD_I2C_Close()
+**
+******************************************************************************/
+GERR GD_I2C_Open(GD_I2C_OPEN_PARAMS_S *parameterP, GD_HANDLE *handleP)
+{
+    int i;
+    GERR gerr;
+    if (i2c_initialized == GFALSE)
+        return GD_ERR_NOT_INITIALIZED;
+    if((parameterP == NULL) || (parameterP->speed == 0))
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+
+    *handleP = parameterP->speed;
+
+    /* Reset the SCL & SDA pin of I2C */
+    switch(parameterP->channel)
+    {
+    case GD_I2C_CHANNEL_ONE:
+        if((i2c_sda_pin == -1) || (i2c_scl_pin == -1))
+        {
+            return GD_ERR_BAD_PARAMETER;
+        }
+        gerr = GD_GPIO_Open(i2c_sda_pin, I2C_DATA_TYPE_OUTPUT_1, NULL, &i2c_sda_handle);
+        if (gerr != GD_OK)
+            return GD_ERR_I2C_INT_ERR;
+
+        gerr = GD_GPIO_Open(i2c_scl_pin, I2C_CLK_TYPE_OUTPUT_1, NULL, &i2c_scl_handle);
+        if (gerr != GD_OK)
+            return GD_ERR_I2C_INT_ERR;
+        break;
+    case GD_I2C_CHANNEL_TWO:
+        if((i2c_sda_pin2 == -1) || (i2c_scl_pin2 == -1))
+        {
+            return GD_ERR_BAD_PARAMETER;
+        }
+        gerr = GD_GPIO_Open(i2c_sda_pin2, I2C_DATA_TYPE_OUTPUT_1, NULL, &i2c_sda_handle);
+        if (gerr != GD_OK)
+            return GD_ERR_I2C_INT_ERR;
+
+        gerr = GD_GPIO_Open(i2c_scl_pin2, I2C_CLK_TYPE_OUTPUT_1, NULL, &i2c_scl_handle);
+        if (gerr != GD_OK)
+            return GD_ERR_I2C_INT_ERR;
+        break;
+    }
+
+    GD_GPIO_Write(i2c_sda_handle, 1);        // set SDA to high
+    GD_GPIO_Write(i2c_scl_handle, 1);        // set SCL to high
+
+    for (i = 0;i < SI2C_BUS_FREE_TIME;i++); // delay loop
+    return GD_OK;
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Read data from an I2C channel.
+**
+**         This function reads data from an I2C channel.
+**         Two mode are support:
+**         - Direct receive of \c rdDataLen bytes (set \c wrDataLen = 0).
+**         - First transmit (\c wrDataLen +1) bytes, then restart and
+**           receive \c rdDataLen bytes.
+**
+** \param  handleP     Pointer to handle which can be used to control the hardware.
+** \param  msSlaveAddr Slave address of external I2C device.
+** \param  writeDataP  Pointer to data to be transmitted to I2C device.
+** \param  wrDataLen   Length of transmit data.
+** \param  readDataP   Pointer to data to be received from I2C device.
+** \param  rdDataLen   Length of receive data.
+**
+** \return Possible return codes:
+**         - \c #GD_OK
+**         - \c #GD_ERR_BAD_PARAMETER
+**         - \c #GD_ERR_I2C_BUSY
+**         - \c #GD_ERR_TIMEOUT
+**
+** \sa      GD_I2C_Open() <br>
+**          GD_I2C_CancelProcess() <br>
+**          GD_I2C_Write()
+**
+******************************************************************************/
+GERR GD_I2C_Read(GD_HANDLE *handleP, U8 msSlaveAddr, U8* writeDataP,
+                            U32 wrDataLen, U8* readDataP, U32 rdDataLen)
+{
+    GERR gerr;
+    int  ix;
+    U8   Data;
+
+    if (i2c_initialized == GFALSE)
+        return GD_ERR_NOT_INITIALIZED;
+
+    gerr = 0;
+    if (wrDataLen)
+    {
+        I2C_SW_gpioIicStart();
+        gerr = I2C_SW_gpioIicWrByte(msSlaveAddr);
+        if (gerr != GD_OK)
+        {
+          I2C_SW_gpioIicRdAck();          // generate one more clock and quit
+          I2C_SW_gpioIicStop();           // send IIC Stop condition
+          return(gerr);
+        }
+        gerr = I2C_SW_gpioIicRdAck();     // test acknowledge
+        if (gerr != GD_OK)
+        {
+          I2C_SW_gpioIicStop();           // send IIC Stop condition
+          return(gerr);
+        }
+        for (ix = 0; ix < wrDataLen; ix++)
+        {
+            Data  = *writeDataP ++;             // get TX-Data
+            gerr = I2C_SW_gpioIicWrByte(Data);
+            if (gerr != GD_OK)
+            {
+              I2C_SW_gpioIicRdAck();          // generate one more clock and quit
+              I2C_SW_gpioIicStop();           // send IIC Stop condition
+              return(gerr);
+            }
+            gerr = I2C_SW_gpioIicRdAck();      // test acknowledge
+            if (gerr != GD_OK)
+            {
+              I2C_SW_gpioIicStop();           // send IIC Stop condition
+              return(gerr);
+            }
+        }
+        gerr = I2C_SW_gpioIicReStart();        // make "Repeated"-Start
+        if (gerr != GD_OK)
+        {
+          I2C_SW_gpioIicStop();           // send IIC Stop condition
+          return(gerr);
+        }
+    }
+    //--- direct read ----
+    else
+    {
+        I2C_SW_gpioIicStart();
+    }
+    gerr = I2C_SW_gpioIicWrByte(msSlaveAddr|0x0001);
+    if (gerr != GD_OK)
+    {
+      I2C_SW_gpioIicRdAck();          // generate one more clock and quit
+      I2C_SW_gpioIicStop();           // send IIC Stop condition
+      return(gerr);
+    }
+    gerr = I2C_SW_gpioIicRdAck();     // test acknowledge
+    if (gerr != GD_OK)
+    {
+      I2C_SW_gpioIicStop();           // send IIC Stop condition
+      return(gerr);
+    }
+
+    while ((rdDataLen--)&&(!gerr))
+    {
+        gerr = I2C_SW_gpioIicRdByte(readDataP);// read Data
+        if (gerr != GD_OK)
+        {
+            I2C_SW_gpioIicWrNoAck();            // Send NoAcknowledge
+            I2C_SW_gpioIicStop();               // send IIC Stop condition
+            return(gerr);
+        }
+        readDataP++;                            // next data
+        if (rdDataLen)
+            gerr = I2C_SW_gpioIicWrAck();       // Send Acknowledge
+        else
+            gerr = I2C_SW_gpioIicWrNoAck();     // Send NoAcknowledge
+        if (gerr != GD_OK)
+        {
+            I2C_SW_gpioIicStop();               // send IIC Stop condition
+            return(gerr);
+        }
+    }
+    gerr = I2C_SW_gpioIicStop();                       // send IIC Stop condition
+    return gerr;
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  This function resets SCL/SDA line.
+**
+******************************************************************************/
+void GD_I2C_Reset(GD_HANDLE *handleP)
+{
+    GERR gerr;
+    int i;
+
+    if (i2c_initialized == GFALSE)
+        return; // GD_ERR_NOT_INITIALIZED;
+
+    GD_GPIO_Close(&i2c_sda_handle);
+    GD_GPIO_Close(&i2c_scl_handle);
+
+    gerr = GD_GPIO_Open(i2c_sda_pin, I2C_DATA_TYPE_OUTPUT_1, NULL, &i2c_sda_handle);
+    gerr = GD_GPIO_Open(i2c_scl_pin, I2C_CLK_TYPE_OUTPUT_1, NULL, &i2c_scl_handle);
+
+    GD_GPIO_Write(i2c_sda_handle, 1);            // set SDA to high
+    GD_GPIO_Write(i2c_scl_handle, 1);            // set SCL to high
+
+    for (i = 0;i<SI2C_BUS_FREE_TIME;i++);   // delay loop
+}
+
+
+/*!
+*******************************************************************************
+**
+** \brief  Write data to I2C channel.
+**
+**         This function writes data to an I2C channel.
+**         Transmit (\c dataLen + 1) bytes.
+**
+** \param  handleP     Pointer to handle which can be used to control the hardware.
+** \param  msSlaveAddr Slave address of external I2C device.
+** \param  dataP       Pointer to data to be transmitted to I2C device
+**                     including subaddress if needed.
+** \param  dataLen     Length of transmit data.
+**
+** \return Possible return codes:
+**         - \c #GD_OK
+**         - \c #GD_ERR_BAD_PARAMETER
+**         - \c #GD_ERR_I2C_BUSY
+**         - \c #GD_ERR_TIMEOUT
+**
+** \sa      GD_I2C_Open() <br>
+**          GD_I2C_CancelProcess() <br>
+**          GD_I2C_Read()
+**
+******************************************************************************/
+GERR GD_I2C_Write(GD_HANDLE *handleP,U8 msSlaveAddr,U8* writeDataP,U32 dataLen)
+{
+    GERR gerr;
+    int ix, nTotData;
+
+    if (i2c_initialized == GFALSE)
+        return GD_ERR_NOT_INITIALIZED;
+    if (((dataLen + 1) > MAX_DATA_LENGTH)||(writeDataP == NULL)||(dataLen == 0))
+        return GD_ERR_BAD_PARAMETER;
+
+    nTotData = (dataLen);
+    if (nTotData >= MAX_DATA_LENGTH)
+        return GD_ERR_BAD_PARAMETER;
+    gerr = 0;
+
+    I2C_SW_gpioIicStart();
+    gerr = I2C_SW_gpioIicWrByte(msSlaveAddr);
+    if (gerr != GD_OK)
+    {
+      I2C_SW_gpioIicRdAck();          // generate one more clock and quit
+      I2C_SW_gpioIicStop();           // send IIC Stop condition
+      return(gerr);
+    }
+    gerr = I2C_SW_gpioIicRdAck();          // test acknowledge
+    if (gerr != GD_OK)
+    {
+      I2C_SW_gpioIicStop();           // send IIC Stop condition
+      return(gerr);
+    }
+
+    for (ix = 0; ix < nTotData; ix++)
+    {
+        gerr = I2C_SW_gpioIicWrByte((writeDataP[ix]));
+        if (gerr != GD_OK)
+        {
+          I2C_SW_gpioIicRdAck();          // generate one more clock and quit
+          I2C_SW_gpioIicStop();           // send IIC Stop condition
+          return(gerr);
+        }
+        gerr = I2C_SW_gpioIicRdAck();      // test acknowledge
+        if (gerr != GD_OK)
+        {
+          I2C_SW_gpioIicStop();           // send IIC Stop condition
+          return(gerr);
+        }
+    }
+    gerr = I2C_SW_gpioIicStop();
+    return gerr;
+}
+GERR GD_I2C_SetOperationMode(GD_I2C_CHANNEL_E channel,GD_I2C_OPEN_MODE_E operationMode)
+{
+    return GD_OK;
+}
+GERR GD_I2C_SetProtocol(GD_HANDLE *handleP,GD_I2C_PROTOCOL_E protocol)
+{
+    return GD_OK;
+}
+GERR GD_I2C_SetMode(GD_HANDLE *handleP,GD_I2C_MODE_E Mode)
+{
+    return GD_OK;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*  Read acknowledge condition at IIC-Bus                                    */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicRdAck()
+{
+    U8 SDA_LEVEL;
+    GERR gerr;
+
+    gerr = I2C_SW_writeSDAnoCheck(SI2C_HIGH_HOLD_TIME,   1);      // set SDA to high
+    if (gerr != GD_OK)
+        return(gerr);
+    gerr = I2C_SW_writeSCL(1,   1);                 // set SCL to high
+    if (gerr != GD_OK)
+        return(gerr);
+    /* read SDA level */
+    I2C_SW_readSDA(&SDA_LEVEL);
+    I2C_SW_writeSCL(SI2C_LOW_HOLD_TIME,  0);        // set SCL to low
+    if (SDA_LEVEL)
+        return GD_ERR_I2C_SL_NACK;                  // check SDA level
+    return GD_OK;
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Read one Byte from IIC-Bus                                               */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicRdByte(U8 *pReadData)
+{
+
+    U16   Mask;
+    U8    Data;                                       // read data
+    U8    SDA_LEVEL;
+    GERR  gerr;
+
+    Data = 0;
+    Mask = 0x0080;
+    while (Mask)
+    {
+        gerr = I2C_SW_writeSCL(SI2C_HIGH_HOLD_TIME,   1);  // set SCL to high
+        if (gerr != GD_OK)
+            return (gerr);
+        I2C_SW_readSDA(&SDA_LEVEL);
+        if (SDA_LEVEL) Data |= Mask;                // read SDA level
+        I2C_SW_writeSCL(SI2C_LOW_HOLD_TIME,  0);    // set SCL to low
+        Mask >>= 1;                                 // shift mask one bit right
+    }
+    *pReadData = Data;
+    return GD_OK;
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Send ReStart condition to IIC-Bus                                        */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicReStart()
+{
+    GERR gerr;
+    gerr = I2C_SW_writeSDA(SI2C_SDA_START_TIME,   1);      // set SDA to High
+    if (gerr != GD_OK)
+        return (gerr);
+    gerr = I2C_SW_writeSCL(SI2C_SCL_START_TIME,   1);      // set SCL to High
+    if (gerr != GD_OK)
+        return (gerr);
+    I2C_SW_writeSDA(SI2C_SDA_START_TIME,   0);      // set SDA to low
+    I2C_SW_writeSCL(SI2C_SCL_START_TIME,   0);      // set SCL to low
+    return (GD_OK);
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Send Start condition to IIC-Bus                                          */
+/*---------------------------------------------------------------------------*/
+void I2C_SW_gpioIicStart()
+{
+    I2C_SW_writeSDA(SI2C_SDA_START_TIME,  0);       // set SDA to low
+    I2C_SW_writeSCL(SI2C_SCL_START_TIME,  0);       // set SCL to low
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Send Stop condition to IIC-Bus                                           */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicStop()
+{
+    U16 i;
+    GERR gerr;
+
+    I2C_SW_writeSDA(1,   0);                            // set SDA to low
+    gerr = I2C_SW_writeSCL(SI2C_SETUP_STOP_TIME,   1);  // set SCL to high
+    if (gerr != GD_OK)
+        return (gerr);
+    gerr = I2C_SW_writeSDA(SI2C_SETUP_STOP_TIME,   1);         // set SDA to high
+    for (i = 0;i < SI2C_BUS_FREE_TIME;i++); // delay loop
+    return (gerr);
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Write acknowledge condition at IIC-Bus                                   */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicWrAck()
+{
+    GERR  gerr;
+
+    I2C_SW_writeSDA(SI2C_LOW_HOLD_TIME,   0);       // set SDA to low
+    /* generate clock pulse */
+    gerr = I2C_SW_writeSCL(1,   1);                 // set SCL to high
+    if (gerr != GD_OK)
+        return (gerr);
+    I2C_SW_writeSCL(SI2C_LOW_HOLD_TIME,  0);        // set SCL to low
+
+    gerr = I2C_SW_writeSDA(SI2C_HIGH_HOLD_TIME,   1);      // set SDA to high
+    return (gerr);
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Write one Byte to IIC-Bus                                                */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicWrByte(U8 Data)
+{
+    U16  Mask;
+    #ifdef GD_I2C_SW_DELAYS
+    int  i;
+    #endif
+    GERR gerr;
+
+    Mask = 0x0080;
+    #ifdef GD_I2C_SW_DELAYS
+    for (i = 0; i < SI2C_HIGH_HOLD_TIME; i++);          // delay loop
+    #endif
+    while (Mask)
+    {
+        if (Data & Mask)
+        {
+            gerr = I2C_SW_writeSDA(I2C_SW_SDA_HIGH_HOLD_TIME,1); // set SDA to high
+            if (gerr != GD_OK)
+                return (gerr);
+        }
+        else
+            I2C_SW_writeSDA(I2C_SW_SDA_LOW_HOLD_TIME, 0); // set SDA to low
+        gerr = I2C_SW_writeSCL(I2C_SW_SCL_HIGH_HOLD_TIME, 1);  // set SCL to high
+        if (gerr != GD_OK)
+            return (gerr);
+        I2C_SW_writeSCL(I2C_SW_SCL_LOW_HOLD_TIME,  0);  // set SCL to low
+        Mask >>= 1;                                     // shift mask one bit right
+    }
+    return GD_OK;
+}
+
+/*---------------------------------------------------------------------------*/
+/*  Write no acknowledge condition at IIC-Bus                                */
+/*---------------------------------------------------------------------------*/
+GERR I2C_SW_gpioIicWrNoAck()
+{
+    U8   SDA_LEVEL;
+    GERR gerr;
+
+    gerr = I2C_SW_writeSDAnoCheck(SI2C_HIGH_HOLD_TIME,   1);        // set SDA to high
+    if (gerr != GD_OK)
+        return (gerr);
+    I2C_SW_readSDA(&SDA_LEVEL);
+    if (!(SDA_LEVEL))
+        return GD_ERR_I2C_BUSY;                       // check SDA level
+    gerr = I2C_SW_writeSCL(SI2C_HIGH_HOLD_TIME,   1); // set SCL to high
+    if (gerr != GD_OK)
+        return (gerr);
+    I2C_SW_writeSCL(I2C_SW_SCL_LOW_HOLD_TIME,  0);    // set SCL to low
+    return GD_OK;
+}
+
+void I2C_SW_readSCL(U8 *pScl)
+{
+    GD_GPIO_SetType(i2c_scl_handle, I2C_CLK_TYPE_INPUT);
+    GD_GPIO_Read(i2c_scl_handle, pScl);
+}
+
+void I2C_SW_readSDA(U8 *pSda)
+{
+    #ifdef GD_I2C_SW_DELAYS
+    U16 i;
+    #endif
+    GD_GPIO_SetType(i2c_sda_handle, I2C_DATA_TYPE_INPUT);
+    #ifdef GD_I2C_SW_DELAYS
+    for (i = 0; i < 10; i++);             // delay loop
+    #endif
+    GD_GPIO_Read(i2c_sda_handle, pSda);
+}
+
+GERR I2C_SW_writeSCL(U16 waitTime, U8 data)
+{
+    U32 i;
+    U8  SCL_LEVEL;
+
+    if (data > 0)
+    {
+      GD_GPIO_SetType(i2c_scl_handle, I2C_CLK_TYPE_OUTPUT_1);
+      GD_GPIO_Write(i2c_scl_handle, 1);      // set SCL to high
+      i = MAX_CHECK_WRA;
+      /*I2C_SW_readSCL(&SCL_LEVEL);
+      while ((SCL_LEVEL != 1) && (i > 0))
+      {
+          //GD_GPIO_SetType(i2c_scl_handle, I2C_GPIO_TYPE_OUTPUT_1);
+          //GD_GPIO_Write(i2c_scl_handle, 1);      // set SCL to high
+          I2C_SW_readSCL(&SCL_LEVEL);
+          i--;                                  // wait high level at SCL
+      }*/
+      if (!i)
+          return GD_ERR_TIMEOUT;
+    }
+    else
+    {
+      GD_GPIO_SetType(i2c_scl_handle, I2C_CLK_TYPE_OUTPUT_0);
+      GD_GPIO_Write(i2c_scl_handle, 0);         // set SCL to low
+      i = MAX_CHECK_WRA;
+      /*I2C_SW_readSCL(&SCL_LEVEL);
+      while ((SCL_LEVEL != 0) && (i > 0))
+      {
+          GD_GPIO_SetType(i2c_scl_handle, I2C_GPIO_TYPE_OUTPUT_0);
+          GD_GPIO_Write(i2c_scl_handle, 0);      // set SCL to high
+          I2C_SW_readSCL(&SCL_LEVEL);
+          i--;                                  // wait high level at SCL
+      }*/
+      if (!i)
+          return GD_ERR_TIMEOUT;
+    }
+    #ifdef GD_I2C_SW_DELAYS
+    for (i = 0; i < waitTime; i++);             // delay loop
+    #endif
+    return (GD_OK);
+}
+
+GERR I2C_SW_writeSDA(U16 waitTime, U8 data)
+{
+    U32 i;
+    U8  SDA_LEVEL;
+
+    if (data > 0)
+    {
+        GD_GPIO_SetType(i2c_sda_handle, I2C_DATA_TYPE_OUTPUT_1);
+        GD_GPIO_Write(i2c_sda_handle, 1);        // set SDA to high
+        i = MAX_CHECK_WRA;
+        /*I2C_SW_readSDA(&SDA_LEVEL);
+        while ((SDA_LEVEL != 1) && (i > 0))
+        {
+            GD_GPIO_SetType(i2c_sda_handle, I2C_GPIO_TYPE_OUTPUT_1);
+            GD_GPIO_Write(i2c_sda_handle, 1);        // set SDA to high
+            I2C_SW_readSDA(&SDA_LEVEL);
+            i--;                                  // wait high level at SDA
+        }*/
+        if (!i)
+            return GD_ERR_TIMEOUT;
+    }
+    else
+    {
+        GD_GPIO_SetType(i2c_sda_handle, I2C_DATA_TYPE_OUTPUT_0);
+        GD_GPIO_Write(i2c_sda_handle, 0);        // set SDA to low
+        i = MAX_CHECK_WRA;
+        /*I2C_SW_readSDA(&SDA_LEVEL);
+        while ((SDA_LEVEL != 0) && (i > 0))
+        {
+            GD_GPIO_SetType(i2c_sda_handle, I2C_GPIO_TYPE_OUTPUT_0);
+            GD_GPIO_Write(i2c_sda_handle, 0);        // set SDA to high
+            I2C_SW_readSDA(&SDA_LEVEL);
+            i--;                                  // wait high level at SDA
+        }*/
+        if (!i)
+            return GD_ERR_TIMEOUT;
+    }
+    #ifdef GD_I2C_SW_DELAYS
+    for (i = 0; i < waitTime; i++);             // delay loop
+    #endif
+    return (GD_OK);
+}
+
+GERR I2C_SW_writeSDAnoCheck(U16 waitTime, U8 data)
+{
+    U32 i;
+    U8  SDA_LEVEL;
+
+    if (data > 0)
+    {
+        GD_GPIO_SetType(i2c_sda_handle, I2C_DATA_TYPE_OUTPUT_1);
+        GD_GPIO_Write(i2c_sda_handle, 1);        // set SDA to high
+    }
+    else
+    {
+        GD_GPIO_SetType(i2c_sda_handle, I2C_DATA_TYPE_OUTPUT_0);
+        GD_GPIO_Write(i2c_sda_handle, 0);        // set SDA to low
+    }
+    #ifdef GD_I2C_SW_DELAYS
+    for (i = 0; i < waitTime; i++);             // delay loop
+    #endif
+    return (GD_OK);
+}
+
+#endif  /* GD_I2C_SOFTWARE  */
+
+
+/* Version History */
+/******************************************************************************
+
+$Log: gd_i2c_sw.c,v $
+Revision 1.18  2010/07/21 13:31:00  benny
+[LEV 2] Porting H10,H20C,H20B,H01 together, use macro to control PCR sync and soft sync
+
+Revision 1.17  2009/06/16 13:14:00  sgehre
+[LEV 2] extended defines for SmartMPEG-C to also include SmartMPEG-M
+
+Revision 1.16  2007/08/15 08:03:22  skau
+I2C_SW_writeSDA caused problem while checking SDA
+level at acknowledge. Extra function without check option added.
+
+Revision 1.15  2007/07/04 14:06:54  mneuma
+Check level in I2C_SW_writeSDA() was done on clk and not data line.
+
+Revision 1.14  2007/01/31 06:43:26  shelle
+Copyright updated
+
+Revision 1.13  2006/10/06 10:58:52  skau
+RN: input/output pin configuration order changed to overcome
+SmartMPEG-L's limitation to push pull buffers. Handling of error feedback
+from subroutines improved.
+
+Revision 1.12  2006/08/01 12:45:14  jrende
+RN: Corrected wrong clock and data pin settings.
+
+Revision 1.11  2006/04/21 12:39:23  shelle
+Version history corrected.
+
+Revision 1.10  2006/03/08 13:13:12  wlaris
+Adjusted for GNU compiler usage.
+
+Revision 1.9  2005/12/28 14:32:17  mneuma
+Doxygen updated.
+
+Revision 1.8  2005/12/15 13:38:58  mneuma
+RN: Init structure extended for I2C GPIO assignment.
+
+Revision 1.6  2005/11/18 11:28:02  mneuma
+GPIO handling for Smart-L added.
+
+Revision 1.5  2004/03/30 16:33:22  shelle
+BOOL, TRUE, FALSE replaced by GBOOL, GTRUE and GFALSE.
+
+Revision 1.4  2004/03/22 15:25:51  mneuma
+use GD_GPIO_TYPE_OUTPUT_OPEN_DRAIN instead
+GD_GPIO_TYPE_OUTPUT_PUSH_PULL
+
+Revision 1.3  2004/03/09 16:28:05  mneuma
+clean-up
+
+Revision 1.2  2004/03/08 16:06:10  mneuma
+function calls reordered
+
+Revision 1.1  2004/03/08 16:01:50  mneuma
+initial version by Terence
+******************************************************************************/

+ 831 - 0
bsp/gkipc/libraries/drv/7102C/gd/src/i2s/gd_i2s.c

@@ -0,0 +1,831 @@
+/******************************************************************************
+**
+** \file      gh_i2s.c
+**
+** \brief     I2S.
+**
+**            Copyright:   2012 - 2013 (C) GoKe Microelectronics ShangHai Branch
+**
+** \attention THIS SAMPLE CODE IS PROVIDED AS IS. GOKE MICROELECTRONICS
+**            ACCEPTS NO RESPONSIBILITY OR LIABILITY FOR ANY ERRORS OR
+**            OMMISSIONS.
+**
+** \note      Do not modify this file as it is generated automatically.
+**
+******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+
+#include "gh_i2s.h"
+	
+#include "gd_dma.h"
+#include "gd_i2s.h"
+#include "gd_timer.h"
+
+
+#define I2S_DEBUG
+#ifdef I2S_DEBUG
+#define I2S_PRINTF(args...) printf(args)
+#else
+#define I2S_PRINTF(args...)
+#endif
+
+#define I2S_STATE_DISABLE  0
+#define I2S_STATE_ENABLE   1
+#define I2S_STATE_RUNNING  2
+#define I2S_STATE_WAITING  3
+
+#define I2S_DEV_ID        (0x00533249)  //'I2S'
+#define I2S_DEV_RX_ID     (0x52533249)  //'I2SR'
+#define I2S_DEV_TX_ID     (0x54533249)  //'I2ST'
+#define I2S_DEV_MIN_FRAME (2)    				 //minimum frame number which device supported.
+#define I2S_DEV_MAX_FRAME (DMA_CHAN_MAX_DESC)	 //maximum frame number which device supported.
+#define I2S_DEV_MAX_BUFF  (I2S_DEV_MAX_FRAME*512)
+#define I2S_BUF_MIN_FRAME (2)                    //data level  
+
+typedef struct
+{
+	U32       subDevID;
+	U32       state;
+	U32       event;
+	GD_HANDLE dmaHandle;
+	GD_I2S_Notifier notifier;	
+	U32       frameNumber;
+	U32       frameSize;
+	U32       nextDescriptor;
+	U32      *dmaReportBuffer;
+	U8       *dmaFrameBuffer;
+	U8       *rdPointer;
+	U8       *wrPointer;
+	U8       *rearPointer;
+}SUB_DEVICE_S;
+
+typedef struct
+{
+    U32                 devID;
+	GBOOL               master;
+	GBOOL               directMode;         //rx --> tx
+    GD_I2S_CHANNEL_E    channel;
+    GD_I2S_MODE_E       mode;
+    GD_I2S_SPEED_E      speed;
+    GD_I2S_WLEN_E       wlen;  
+	SUB_DEVICE_S        rx;
+	SUB_DEVICE_S        tx;
+} I2S_DEVICE_S;
+
+static I2S_DEVICE_S i2sDev __attribute__ ((section(".nocache_buffer")));
+static U32 rxReportBuffer[I2S_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static U32 txReportBuffer[I2S_DEV_MAX_FRAME] __attribute__ ((section(".nocache_buffer")));
+static U8 rxDmaBuffer[I2S_DEV_MAX_BUFF] __attribute__ ((aligned(DMA_BUFF_ADDR_ALIGN),section(".nocache_buffer")));
+static U8 txDmaBuffer[I2S_DEV_MAX_BUFF] __attribute__ ((aligned(DMA_BUFF_ADDR_ALIGN),section(".nocache_buffer")));
+static SUB_DEVICE_S * const prxDev = &i2sDev.rx;
+static SUB_DEVICE_S * const ptxDev = &i2sDev.tx;
+
+
+static void rx_int_handler(void)
+{
+	U32 curDescriptor = 0;
+	U32 dmaStatus     = 0;
+	U32 revFrameNumber = 0;
+	U8 *frameReadPointer = 0;
+	U8 *frameWritePointer = 0;	
+	SUB_DEVICE_S * pDev = prxDev;
+	
+	curDescriptor = pDev->nextDescriptor;
+	pDev->nextDescriptor++;
+	if(pDev->nextDescriptor >= pDev->frameNumber)
+	{
+		pDev->nextDescriptor = 0;
+	}	
+
+	dmaStatus = pDev->dmaReportBuffer[curDescriptor];	
+	if(dmaStatus & DMA_CHAN_STATE_DD)
+	{
+	
+	}	
+	
+	if(dmaStatus & DMA_CHAN_STATE_OD) /* DO NOT verify this field, report buffer will not refresh after DMA int sometimes. */
+	{
+		pDev->wrPointer += pDev->frameSize;
+		if(pDev->wrPointer >= pDev->rearPointer)
+		{
+			pDev->wrPointer = pDev->dmaFrameBuffer;
+		}
+
+		pDev->dmaReportBuffer[curDescriptor] &= ~(DMA_CHAN_STATE_OD|DMA_CHAN_STATE_DN);
+		
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_FRAME);
+		}
+	}
+	else /* not expected interrupt */
+	{
+		pDev->event = I2S_EVENT_UNDEFINED;		  //for debug only.
+		pDev->notifier(I2S_EVENT_UNDEFINED);
+	}
+
+	frameReadPointer  = pDev->rdPointer;
+	frameWritePointer = pDev->wrPointer;
+	if(frameReadPointer <= frameWritePointer)
+	{
+		revFrameNumber = (frameWritePointer - frameReadPointer) / pDev->frameSize;
+	}
+	else
+	{
+		revFrameNumber = pDev->frameNumber -(frameReadPointer - frameWritePointer) / pDev->frameSize;
+	}
+	if(revFrameNumber >= pDev->frameNumber - I2S_BUF_MIN_FRAME)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_WILL_OVERFLOW);
+		}
+		pDev->event = I2S_EVENT_WILL_OVERFLOW;
+	}
+	if(revFrameNumber == 0)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_ALREADY_OVERFLOW);
+		}
+		pDev->event =I2S_EVENT_ALREADY_OVERFLOW;
+	}		
+
+}
+
+static void tx_int_handler(void)
+{
+	U32 curDescriptor = 0;
+	U32 dmaStatus     = 0;
+	U32 revFrameNumber = 0;
+	U8 *frameReadPointer = 0;
+	U8 *frameWritePointer = 0;	
+	SUB_DEVICE_S * pDev = ptxDev;
+	
+	curDescriptor = pDev->nextDescriptor;
+	pDev->nextDescriptor++;
+	if(pDev->nextDescriptor >= pDev->frameNumber)
+	{
+		pDev->nextDescriptor = 0;
+	}
+
+	dmaStatus = pDev->dmaReportBuffer[curDescriptor];
+	if(dmaStatus & DMA_CHAN_STATE_DD)
+	{
+		
+	}
+
+	
+	if(dmaStatus & DMA_CHAN_STATE_OD) /* DO NOT verify this field, report buffer will not refresh after DMA int sometimes. */
+	{
+		pDev->rdPointer += pDev->frameSize;
+		if(pDev->rdPointer >= pDev->rearPointer)
+		{
+			pDev->rdPointer = pDev->dmaFrameBuffer;
+		}
+
+		pDev->dmaReportBuffer[curDescriptor] &= ~(DMA_CHAN_STATE_OD|DMA_CHAN_STATE_DN);
+
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_FRAME);
+		}
+	}		
+	else /* not expected interrupt */
+	{
+		pDev->event = I2S_EVENT_UNDEFINED;         //for debug only.
+		pDev->notifier(I2S_EVENT_UNDEFINED);
+	}
+
+
+	frameReadPointer  = pDev->rdPointer;
+	frameWritePointer = pDev->wrPointer;
+	if(frameReadPointer <= frameWritePointer)
+	{
+		revFrameNumber = (frameWritePointer - frameReadPointer) / pDev->frameSize;
+	}
+	else
+	{
+		revFrameNumber = pDev->frameNumber -(frameReadPointer - frameWritePointer) / pDev->frameSize;
+	}
+
+	if(revFrameNumber <= 0)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_ALREADY_UNDERFLOW);
+		}
+		pDev->event = I2S_EVENT_ALREADY_UNDERFLOW;
+
+		GH_I2S_set_Initreg_te(0);
+		pDev->state = I2S_STATE_WAITING;
+	}		
+	else if(revFrameNumber <= I2S_BUF_MIN_FRAME)
+	{
+		if(pDev->notifier != NULL)
+		{
+			pDev->notifier(I2S_EVENT_WILL_UNDERFLOW);
+		}
+		pDev->event = I2S_EVENT_WILL_UNDERFLOW;
+	}
+}
+
+
+static GERR dma_open(SUB_DEVICE_S *dev)
+{
+	U32 i = 0;
+	U32 align_offset = 0;
+	GERR err = GD_OK;
+	GD_DMA_DESCRIPTOR_S dmaDescriptor;
+	GD_DMA_OPEN_PARAM_S dmaOpenParam;
+		
+	if(dev->frameNumber<=0 || dev->frameSize<=0)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	////////////////////////////////
+	//config descriptor
+	////////////////////////////////
+	
+	if(dev->subDevID == I2S_DEV_RX_ID)
+	{
+		dev->dmaFrameBuffer  = rxDmaBuffer;
+		dev->dmaReportBuffer = rxReportBuffer;
+		dev->nextDescriptor  = 0;
+		dev->rdPointer       = dev->dmaFrameBuffer;
+		dev->wrPointer       = dev->dmaFrameBuffer;
+		dev->rearPointer     = dev->dmaFrameBuffer + dev->frameNumber*dev->frameSize;	
+		
+		dmaOpenParam.channel = DMA_CHAN_I2S_RX;
+		dmaOpenParam.mode    = DMA_MODE_DESCRIPTOR;
+		dmaOpenParam.intNotifier = rx_int_handler;
+	}
+	else /* I2S_DEV_TX_ID */
+	{
+		dev->dmaFrameBuffer  = txDmaBuffer;
+		dev->dmaReportBuffer = txReportBuffer;
+		dev->nextDescriptor  = 0;
+		dev->rdPointer       = dev->dmaFrameBuffer;
+		dev->wrPointer       = dev->dmaFrameBuffer;
+		dev->rearPointer     = dev->dmaFrameBuffer + dev->frameNumber*dev->frameSize;
+		
+		dmaOpenParam.channel = DMA_CHAN_I2S_TX;
+		dmaOpenParam.mode	 = DMA_MODE_DESCRIPTOR;
+		dmaOpenParam.intNotifier = tx_int_handler;
+	}
+	I2S_PRINTF("[GD_I2S]dmaFrameBuffer:0x%08X\n", dev->dmaFrameBuffer);
+	
+	err = GD_DMA_Open(&dmaOpenParam, &dev->dmaHandle);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	////////////////////////////////
+	//config descriptor
+	////////////////////////////////	
+	for(i=0; i<dev->frameNumber; i++)
+	{
+		if(dev->subDevID == I2S_DEV_RX_ID)
+		{
+			dmaDescriptor.srcAddr  = DMA_RX_REG;
+			dmaDescriptor.dstAddr  = (U32)dev->dmaFrameBuffer + i * dev->frameSize;
+			dmaDescriptor.descAttr = DMA_DESC_WM|DMA_DESC_NI|DMA_DESC_TS_4B /*|DMA_DESC_EOC*/
+				                   |DMA_DESC_BLK_8B|DMA_DESC_ID|DMA_DESC_IE|DMA_DESC_ST;
+		}
+		else /* I2S_DEV_TX_ID */
+		{
+			dmaDescriptor.srcAddr  = (U32)dev->dmaFrameBuffer + i * dev->frameSize;
+			dmaDescriptor.dstAddr  = DMA_TX_REG;
+			dmaDescriptor.descAttr = DMA_DESC_RM|DMA_DESC_NI|DMA_DESC_TS_4B /*|DMA_DESC_EOC*/
+				                   |DMA_DESC_BLK_8B|DMA_DESC_ID|DMA_DESC_IE|DMA_DESC_ST;		
+		}
+
+		dmaDescriptor.dataLength = dev->frameSize;
+		dmaDescriptor.reportAddr = (U32)(dev->dmaReportBuffer + i);
+		dmaDescriptor.next       = NULL;
+
+		err = GD_DMA_AddDescriptor(dev->dmaHandle, &dmaDescriptor);
+		if(err != GD_OK)
+		{
+			return err;
+		}		
+	} 
+
+	return GD_OK;	
+}
+
+static GERR dma_close(SUB_DEVICE_S *dev)
+{
+	if(dev == NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	////////////////////////////////
+	//disable DMA
+	////////////////////////////////	
+	GD_DMA_Stop(dev->dmaHandle);
+	GD_DMA_Close(dev->dmaHandle);
+
+	return GD_OK;
+}
+
+GERR GD_I2S_RX_Open(GD_I2S_OPEN_PARAM_S *openParams)
+{
+	U32  frameNumber = 0;
+	U32  frameSize = 0;
+	GERR err = GD_OK;
+	SUB_DEVICE_S *pDev = prxDev;
+
+    if(openParams == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+
+    if(openParams->frameSize <= 0)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if(i2sDev.devID == 0)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+	if(pDev->subDevID == I2S_DEV_RX_ID)
+	{
+		return GD_ERR_ALREADY_OPEN;
+	}
+
+	frameSize   = openParams->frameSize;
+	frameNumber = I2S_DEV_MAX_BUFF / frameSize;
+	if(frameNumber < I2S_DEV_MIN_FRAME)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+	if(frameNumber > I2S_DEV_MAX_FRAME)
+	{
+		frameNumber = I2S_DEV_MAX_FRAME;
+	}	
+
+	pDev->frameNumber     = frameNumber;
+	pDev->frameSize       = frameSize;
+	pDev->notifier        = openParams->notifier;
+	pDev->subDevID        = I2S_DEV_RX_ID;
+	pDev->state           = I2S_STATE_DISABLE;
+	I2S_PRINTF("[GD_I2S]RX frame: number %d, size 0x%08X\n", frameNumber, frameSize);
+
+	err = dma_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}	
+
+	GH_I2S_set_RxContr(0x00);
+	GH_I2S_set_RxContr_rwi(1);
+	if(i2sDev.master == GTRUE)
+	{
+		GH_I2S_set_RxContr_rwm(1);
+	}
+	else
+	{	
+		GH_I2S_set_RxContr_rwm(0);
+	}		
+
+    return GD_OK;
+}
+
+GERR GD_I2S_RX_Enable(void)
+{
+	SUB_DEVICE_S *pDev = prxDev;
+
+	if(pDev->state==I2S_STATE_ENABLE || pDev->state==I2S_STATE_RUNNING)
+	{
+		return GD_ERR_I2S_BUSY;
+	}		
+	
+    GH_I2S_set_MultipMode_en(0x1);
+    GH_I2S_set_RxFifoGth(0x10);
+    GH_I2S_set_Initreg_re(1);
+
+	memset(pDev->dmaFrameBuffer, 0, pDev->frameNumber*pDev->frameSize);
+	pDev->nextDescriptor = 0;
+	pDev->rdPointer = pDev->dmaFrameBuffer;
+	pDev->wrPointer = pDev->dmaFrameBuffer;	
+	pDev->state = I2S_STATE_ENABLE;
+	
+	GD_DMA_Start(pDev->dmaHandle, 0);	
+	pDev->state = I2S_STATE_RUNNING;
+
+	return GD_OK;
+}
+
+GERR GD_I2S_RX_Disable(void)
+{
+	SUB_DEVICE_S *pDev = prxDev;
+
+	GD_DMA_Stop(pDev->dmaHandle);
+	pDev->state = I2S_STATE_DISABLE;
+
+	return GD_OK;
+}
+
+GERR GD_I2S_RX_Read_Frame(U8 *data, U32 *length)
+{
+	U32 revFrameNumber = 0;
+	SUB_DEVICE_S *pDev = prxDev;
+	U8 *frameReadPointer = NULL; 
+	U8 *frameWritePointer = NULL;
+	
+	if(data==NULL || length==NULL)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+
+	if(pDev->state == I2S_STATE_DISABLE)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}	
+
+	if(pDev->event == I2S_EVENT_ALREADY_OVERFLOW)
+	{
+		// TODO: overflow.
+	}	
+
+	frameReadPointer = pDev->rdPointer; 
+	frameWritePointer = pDev->wrPointer;
+
+	if(frameWritePointer == frameReadPointer)
+	{
+		return GD_ERR_I2S_WAIT;
+	}		
+
+	memcpy(data, frameReadPointer, pDev->frameSize);
+
+	pDev->rdPointer += pDev->frameSize;
+	if(pDev->rdPointer >= pDev->rearPointer)
+	{
+		pDev->rdPointer = pDev->dmaFrameBuffer;
+	}
+
+	*length = pDev->frameSize;
+    return GD_OK;
+}
+
+
+GERR GD_I2S_RX_Close(void)
+{
+	GERR err = GD_OK;
+    SUB_DEVICE_S *pDev = prxDev;
+	
+    if(pDev->subDevID != I2S_DEV_RX_ID)
+    {
+        return GD_ERR_NOT_ALLOWED;
+    }
+	
+	err = dma_close(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	GD_TIMER_Delay(5);
+	GD_I2S_RX_Disable();
+    memset((void *)pDev, 0, sizeof(SUB_DEVICE_S));
+	
+    return GD_OK;
+}
+
+
+GERR GD_I2S_TX_Open(GD_I2S_OPEN_PARAM_S *openParams)
+{
+	U32  frameNumber = 0;
+	U32  frameSize = 0;
+	GERR err = GD_OK;
+	SUB_DEVICE_S *pDev = ptxDev;
+
+    if(openParams == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+
+    if(openParams->frameSize <= 0)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+    if(i2sDev.devID == 0)
+    {
+        return GD_ERR_NOT_INITIALIZED;
+    }
+	if(pDev->subDevID == I2S_DEV_TX_ID)
+	{
+		return GD_ERR_ALREADY_OPEN;
+	}
+
+	frameSize   = openParams->frameSize;
+	frameNumber = I2S_DEV_MAX_BUFF / frameSize;
+	if(frameNumber < I2S_DEV_MIN_FRAME)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}
+	if(frameNumber > I2S_DEV_MAX_FRAME)
+	{
+		frameNumber = I2S_DEV_MAX_FRAME;
+	}	
+
+	pDev->frameNumber     = frameNumber;
+	pDev->frameSize       = frameSize;
+	pDev->notifier        = openParams->notifier;
+	pDev->subDevID        = I2S_DEV_TX_ID;
+	pDev->state           = I2S_STATE_DISABLE;
+	I2S_PRINTF("[GD_I2S]TX frame: number %d, size 0x%08X\n", frameNumber, frameSize);
+
+	err = dma_open(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}	
+
+	GH_I2S_set_TxContr(0x00);
+	GH_I2S_set_TxContr_twi(1);
+	if(i2sDev.master == GTRUE)
+	{
+		GH_I2S_set_TxContr_twm(1);
+	}
+	else
+	{	
+		GH_I2S_set_TxContr_twm(0);
+	}	
+
+    return GD_OK;
+}
+
+
+GERR GD_I2S_TX_Enable(void)
+{
+	SUB_DEVICE_S *pDev = ptxDev;
+
+	if(pDev->state==I2S_STATE_ENABLE || pDev->state==I2S_STATE_RUNNING)
+	{
+		return GD_ERR_I2S_BUSY;
+	}	
+
+    GH_I2S_set_MultipMode_en(0x1);
+    GH_I2S_set_TxFifoLth(0x10);
+    GH_I2S_set_Initreg_te(1);
+
+	memset(pDev->dmaFrameBuffer, 0, pDev->frameNumber*pDev->frameSize);
+	pDev->nextDescriptor = 0;
+	pDev->rdPointer = pDev->dmaFrameBuffer;
+	pDev->wrPointer = pDev->dmaFrameBuffer;
+	pDev->state = I2S_STATE_ENABLE;
+
+	return GD_OK;
+}
+
+GERR GD_I2S_TX_Disable(void)
+{
+	SUB_DEVICE_S *pDev = ptxDev;
+
+	GD_DMA_Stop(pDev->dmaHandle);
+	pDev->state = I2S_STATE_DISABLE;
+
+	return GD_OK;
+}
+
+GERR GD_I2S_TX_Mute(void)
+{
+	GH_I2S_set_TxContr_mute(1);
+	return GD_OK;
+}
+
+GERR GD_I2S_TX_Unmute(void)
+{
+	GH_I2S_set_TxContr_mute(0);
+	return GD_OK;
+}
+
+GERR GD_I2S_TX_Write_Frame(U8 *data, U32 length)
+{
+	U32 revFrameNumber = 0;
+	GERR err = GD_OK;
+	SUB_DEVICE_S *pDev = ptxDev;
+	U8 *frameReadPointer = pDev->rdPointer; 
+	U8 *frameWritePointer = pDev->wrPointer;
+	
+	if(data == NULL || length <=0 || length > pDev->frameSize)
+	{
+		return GD_ERR_BAD_PARAMETER;
+	}
+	
+	if(pDev->state == I2S_STATE_DISABLE)
+	{
+		return GD_ERR_FEATURE_NOT_SUPPORTED;
+	}		
+
+	if(((frameWritePointer-pDev->dmaFrameBuffer)/pDev->frameSize+1)%pDev->frameNumber == 
+		(frameReadPointer-pDev->dmaFrameBuffer)/pDev->frameSize)
+	{
+		return GD_ERR_I2S_BUSY;
+	}	
+
+	memset(frameWritePointer, 0, pDev->frameSize);
+	memcpy(frameWritePointer, data, length);
+
+	pDev->wrPointer += pDev->frameSize;
+	if(pDev->wrPointer >= pDev->rearPointer)
+	{
+		pDev->wrPointer = pDev->dmaFrameBuffer;
+	}
+
+
+	if(pDev->state==I2S_STATE_ENABLE || pDev->state==I2S_STATE_WAITING)
+	{
+		if(frameReadPointer <= frameWritePointer)
+		{
+			revFrameNumber = (frameWritePointer - frameReadPointer) / pDev->frameSize;
+		}
+		else
+		{
+			revFrameNumber = pDev->frameNumber - (frameReadPointer - frameWritePointer) / pDev->frameSize;
+		}
+
+		if(revFrameNumber>=I2S_BUF_MIN_FRAME && pDev->state==I2S_STATE_ENABLE)
+		{
+			err = GD_DMA_Start(pDev->dmaHandle, 0);
+			if(err != GD_OK)
+			{
+				return err;
+			}
+			pDev->state = I2S_STATE_RUNNING;
+		}
+		if(revFrameNumber>=I2S_BUF_MIN_FRAME && pDev->state==I2S_STATE_WAITING)
+		{
+			GH_I2S_set_Initreg_te(1);
+			pDev->state = I2S_STATE_RUNNING;
+		}		
+	}
+
+	return GD_OK;
+}
+
+
+GERR GD_I2S_TX_Close(void)
+{
+	GERR err = GD_OK;
+    SUB_DEVICE_S *pDev = prxDev;
+	
+    if(pDev->subDevID != I2S_DEV_RX_ID)
+    {
+        return GD_ERR_NOT_ALLOWED;
+    }
+	
+	err = dma_close(pDev);
+	if(err != GD_OK)
+	{
+		return err;
+	}
+
+	GD_TIMER_Delay(5);
+	GD_I2S_RX_Disable();
+    memset((void *)pDev, 0, sizeof(SUB_DEVICE_S));
+	
+    return GD_OK;
+}
+
+GERR GD_I2S_SetClock(GD_I2S_SPEED_E speed)
+{
+    U32 i2s_clk = 0;
+    U32 clk_div = 0;
+	U32 bit_num = 0;
+	I2S_DEVICE_S *pDev = &i2sDev;
+	
+	if(pDev->wlen == GD_I2S_16BIT)
+	{
+		bit_num = 16;
+	}
+	else
+	{
+		bit_num = 32;
+	}
+
+	
+    i2s_clk = GD_GET_I2S_ClkHz();
+	clk_div = i2s_clk/(speed*bit_num)/2/2 - 1; /* div = (clk_au / (2*clk_i2s)) - 1 */
+	GH_I2S_set_Clock_clk_div(clk_div); 
+
+	pDev->speed = speed;
+    return GD_OK;
+}
+
+GERR GD_I2S_SetWlen(GD_I2S_WLEN_E wlen)
+{
+    I2S_DEVICE_S *pDev = &i2sDev;
+    
+    GH_I2S_set_WlReg(wlen-1);	
+
+	pDev->wlen = wlen;
+    return GD_OK;
+}
+
+GERR GD_I2S_SetMode(GD_I2S_MODE_E mode)
+{
+    I2S_DEVICE_S *pDev = &i2sDev;
+	
+    GH_I2S_set_Mode_MODE(mode);
+
+	pDev->mode = mode;
+    return GD_OK;
+}
+
+GERR GD_I2S_SetChannel(GD_I2S_CHANNEL_E channel)
+{
+    I2S_DEVICE_S *pDev = &i2sDev;
+    	
+	GH_I2S_set_ChanSlect(channel);
+
+	pDev->channel = channel;
+    return GD_OK;
+}
+
+GERR GD_I2S_Init(GD_I2S_INIT_PARAM_S *initParams)
+{
+	I2S_DEVICE_S *pDev = &i2sDev;
+
+    if(initParams == NULL)
+    {
+        return GD_ERR_BAD_PARAMETER;
+    }
+
+	memset(pDev, 0, sizeof(I2S_DEVICE_S));
+	pDev->master  = initParams->master;
+    pDev->channel = initParams->channel;
+    pDev->mode    = initParams->mode;
+    pDev->wlen    = initParams->wlen;
+    pDev->speed   = initParams->speed;
+    pDev->devID   = I2S_DEV_ID;
+
+	GH_I2S_set_Clock(0x00);
+	GH_I2S_set_Clock_rsp(1);
+	GH_I2S_set_Clock_tsp(1);
+	if(pDev->master == GTRUE)
+	{
+		GH_I2S_set_Clock_ss(1);
+		GH_I2S_set_Clock_soe(1);
+		GH_I2S_set_Clock_woe(1);
+	}	
+	
+	GD_I2S_SetMode(pDev->mode);
+	GD_I2S_SetClock(pDev->speed);
+	GD_I2S_SetWlen(pDev->wlen);
+	GD_I2S_SetChannel(pDev->channel);
+		
+    return GD_OK;
+}
+
+GERR GD_I2S_Bind_Rx2Tx(void)
+{
+	I2S_DEVICE_S *pDev = &i2sDev;
+
+	if(pDev->directMode == GTRUE)
+	{
+		return GD_OK;
+	}
+
+	GD_I2S_RX_Disable();
+	GD_I2S_TX_Disable();
+	GD_TIMER_Delay(10);
+	GH_I2S_set_TxContr_loopback(1);	
+	GH_I2S_set_Initreg_re(1);
+	GH_I2S_set_Initreg_te(1);
+	
+	pDev->directMode  = GTRUE;
+    return GD_OK;
+}
+
+GERR GD_I2S_Unbind_Rx2Tx(void)
+{
+	I2S_DEVICE_S *pDev = &i2sDev;
+	
+	if(pDev->directMode == GFALSE)
+	{
+		return GD_OK;
+	}
+
+	GH_I2S_set_TxContr_loopback(0);
+	GD_I2S_RX_Enable();
+	GD_I2S_TX_Enable();
+	
+	pDev->directMode  = GFALSE;
+    return GD_OK;
+}
+
+
+GERR GD_I2S_Exit(void)
+{
+	memset(&i2sDev, 0, sizeof(I2S_DEVICE_S));
+	
+    return GD_OK;
+}
+

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff