Bladeren bron

add raspi2 and raspi3 BSP

bigmagic 5 jaren geleden
bovenliggende
commit
fdde8ab198
100 gewijzigde bestanden met toevoegingen van 11818 en 3 verwijderingen
  1. 0 0
      bsp/raspberry-pi/raspi2/.config
  2. 28 0
      bsp/raspberry-pi/raspi2/Kconfig
  3. 0 0
      bsp/raspberry-pi/raspi2/README.md
  4. 0 0
      bsp/raspberry-pi/raspi2/SConscript
  5. 1 1
      bsp/raspberry-pi/raspi2/SConstruct
  6. 0 0
      bsp/raspberry-pi/raspi2/applications/SConscript
  7. 0 0
      bsp/raspberry-pi/raspi2/applications/main.c
  8. 0 0
      bsp/raspberry-pi/raspi2/applications/mnt.c
  9. 0 0
      bsp/raspberry-pi/raspi2/driver/Kconfig
  10. 0 0
      bsp/raspberry-pi/raspi2/driver/SConscript
  11. 0 0
      bsp/raspberry-pi/raspi2/driver/bcm283x.h
  12. 0 0
      bsp/raspberry-pi/raspi2/driver/board.c
  13. 0 0
      bsp/raspberry-pi/raspi2/driver/board.h
  14. 0 0
      bsp/raspberry-pi/raspi2/driver/drv_uart.c
  15. 0 0
      bsp/raspberry-pi/raspi2/driver/drv_uart.h
  16. 0 0
      bsp/raspberry-pi/raspi2/figures/raspi2.png
  17. 0 0
      bsp/raspberry-pi/raspi2/figures/raspi_uart.png
  18. BIN
      bsp/raspberry-pi/raspi2/kernel7.img
  19. 0 0
      bsp/raspberry-pi/raspi2/link.lds
  20. 0 0
      bsp/raspberry-pi/raspi2/rtconfig.h
  21. 2 2
      bsp/raspberry-pi/raspi2/rtconfig.py
  22. 427 0
      bsp/raspberry-pi/raspi3-32/.config
  23. 0 0
      bsp/raspberry-pi/raspi3-32/Kconfig
  24. 153 0
      bsp/raspberry-pi/raspi3-32/README.md
  25. 14 0
      bsp/raspberry-pi/raspi3-32/SConscript
  26. 28 0
      bsp/raspberry-pi/raspi3-32/SConstruct
  27. 9 0
      bsp/raspberry-pi/raspi3-32/applications/SConscript
  28. 18 0
      bsp/raspberry-pi/raspi3-32/applications/main.c
  29. 29 0
      bsp/raspberry-pi/raspi3-32/applications/mnt.c
  30. 462 0
      bsp/raspberry-pi/raspi3-32/applications/test_device.c
  31. 0 0
      bsp/raspberry-pi/raspi3-32/cpu/SConscript
  32. 74 0
      bsp/raspberry-pi/raspi3-32/cpu/armv7.h
  33. 183 0
      bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S
  34. 168 0
      bsp/raspberry-pi/raspi3-32/cpu/cp15.h
  35. 147 0
      bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S
  36. 91 0
      bsp/raspberry-pi/raspi3-32/cpu/cpu.c
  37. 186 0
      bsp/raspberry-pi/raspi3-32/cpu/interrupt.c
  38. 18 0
      bsp/raspberry-pi/raspi3-32/cpu/interrupt.h
  39. 188 0
      bsp/raspberry-pi/raspi3-32/cpu/mmu.c
  40. 51 0
      bsp/raspberry-pi/raspi3-32/cpu/mmu.h
  41. 72 0
      bsp/raspberry-pi/raspi3-32/cpu/stack.c
  42. 459 0
      bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S
  43. 219 0
      bsp/raspberry-pi/raspi3-32/cpu/trap.c
  44. 51 0
      bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S
  45. 103 0
      bsp/raspberry-pi/raspi3-32/driver/Kconfig
  46. 31 0
      bsp/raspberry-pi/raspi3-32/driver/SConscript
  47. 182 0
      bsp/raspberry-pi/raspi3-32/driver/board.c
  48. 29 0
      bsp/raspberry-pi/raspi3-32/driver/board.h
  49. 508 0
      bsp/raspberry-pi/raspi3-32/driver/drv_fb.c
  50. 60 0
      bsp/raspberry-pi/raspi3-32/driver/drv_fb.h
  51. 318 0
      bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c
  52. 42 0
      bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h
  53. 238 0
      bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c
  54. 43 0
      bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h
  55. 301 0
      bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c
  56. 21 0
      bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h
  57. 580 0
      bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c
  58. 253 0
      bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h
  59. 287 0
      bsp/raspberry-pi/raspi3-32/driver/drv_spi.c
  60. 102 0
      bsp/raspberry-pi/raspi3-32/driver/drv_spi.h
  61. 154 0
      bsp/raspberry-pi/raspi3-32/driver/drv_timer.c
  62. 27 0
      bsp/raspberry-pi/raspi3-32/driver/drv_timer.h
  63. 183 0
      bsp/raspberry-pi/raspi3-32/driver/drv_uart.c
  64. 41 0
      bsp/raspberry-pi/raspi3-32/driver/drv_uart.h
  65. 117 0
      bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c
  66. 26 0
      bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h
  67. 54 0
      bsp/raspberry-pi/raspi3-32/driver/mbox.c
  68. 63 0
      bsp/raspberry-pi/raspi3-32/driver/mbox.h
  69. 432 0
      bsp/raspberry-pi/raspi3-32/driver/raspi.h
  70. BIN
      bsp/raspberry-pi/raspi3-32/figures/GPIO-Pinout-Diagram-2.png
  71. BIN
      bsp/raspberry-pi/raspi3-32/figures/raspberrypi-console.png
  72. BIN
      bsp/raspberry-pi/raspi3-32/figures/raspi3_b.jpg
  73. BIN
      bsp/raspberry-pi/raspi3-32/figures/raspi3_f.jpg
  74. 149 0
      bsp/raspberry-pi/raspi3-32/link.lds
  75. 391 0
      bsp/raspberry-pi/raspi3-32/rtconfig.h
  76. 52 0
      bsp/raspberry-pi/raspi3-32/rtconfig.py
  77. 418 0
      bsp/raspberry-pi/raspi3-64/.config
  78. 125 0
      bsp/raspberry-pi/raspi3-64/.cproject
  79. 54 0
      bsp/raspberry-pi/raspi3-64/.project
  80. 29 0
      bsp/raspberry-pi/raspi3-64/Kconfig
  81. 100 0
      bsp/raspberry-pi/raspi3-64/README.md
  82. 14 0
      bsp/raspberry-pi/raspi3-64/SConscript
  83. 30 0
      bsp/raspberry-pi/raspi3-64/SConstruct
  84. 9 0
      bsp/raspberry-pi/raspi3-64/applications/SConscript
  85. 19 0
      bsp/raspberry-pi/raspi3-64/applications/main.c
  86. 16 0
      bsp/raspberry-pi/raspi3-64/applications/mnt.c
  87. 45 0
      bsp/raspberry-pi/raspi3-64/applications/test/gpio.h
  88. 103 0
      bsp/raspberry-pi/raspi3-64/applications/test/uart.c
  89. 29 0
      bsp/raspberry-pi/raspi3-64/applications/test/uart.h
  90. 112 0
      bsp/raspberry-pi/raspi3-64/driver/Kconfig
  91. 32 0
      bsp/raspberry-pi/raspi3-64/driver/SConscript
  92. 575 0
      bsp/raspberry-pi/raspi3-64/driver/bcm283x.c
  93. 641 0
      bsp/raspberry-pi/raspi3-64/driver/bcm283x.h
  94. 298 0
      bsp/raspberry-pi/raspi3-64/driver/board.c
  95. 29 0
      bsp/raspberry-pi/raspi3-64/driver/board.h
  96. 523 0
      bsp/raspberry-pi/raspi3-64/driver/drv_fb.c
  97. 60 0
      bsp/raspberry-pi/raspi3-64/driver/drv_fb.h
  98. 473 0
      bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c
  99. 42 0
      bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h
  100. 177 0
      bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c

+ 0 - 0
bsp/raspi2/.config → bsp/raspberry-pi/raspi2/.config


+ 28 - 0
bsp/raspberry-pi/raspi2/Kconfig

@@ -0,0 +1,28 @@
+mainmenu "RT-Thread Project 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"
+
+config BCM2836_SOC
+    bool
+    select ARCH_ARM_CORTEX_A7
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    default y
+
+source "driver/Kconfig"

+ 0 - 0
bsp/raspi2/README.md → bsp/raspberry-pi/raspi2/README.md


+ 0 - 0
bsp/raspi2/SConscript → bsp/raspberry-pi/raspi2/SConscript


+ 1 - 1
bsp/raspi2/SConstruct → bsp/raspberry-pi/raspi2/SConstruct

@@ -22,7 +22,7 @@ Export('RTT_ROOT')
 Export('rtconfig')
 
 # prepare building environment
-objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=True)
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
 
 # make a building
 DoBuilding(TARGET, objs)

+ 0 - 0
bsp/raspi2/applications/SConscript → bsp/raspberry-pi/raspi2/applications/SConscript


+ 0 - 0
bsp/raspi2/applications/main.c → bsp/raspberry-pi/raspi2/applications/main.c


+ 0 - 0
bsp/raspi2/applications/mnt.c → bsp/raspberry-pi/raspi2/applications/mnt.c


+ 0 - 0
bsp/raspi2/driver/Kconfig → bsp/raspberry-pi/raspi2/driver/Kconfig


+ 0 - 0
bsp/raspi2/driver/SConscript → bsp/raspberry-pi/raspi2/driver/SConscript


+ 0 - 0
bsp/raspi2/driver/bcm283x.h → bsp/raspberry-pi/raspi2/driver/bcm283x.h


+ 0 - 0
bsp/raspi2/driver/board.c → bsp/raspberry-pi/raspi2/driver/board.c


+ 0 - 0
bsp/raspi2/driver/board.h → bsp/raspberry-pi/raspi2/driver/board.h


+ 0 - 0
bsp/raspi2/driver/drv_uart.c → bsp/raspberry-pi/raspi2/driver/drv_uart.c


+ 0 - 0
bsp/raspi2/driver/drv_uart.h → bsp/raspberry-pi/raspi2/driver/drv_uart.h


+ 0 - 0
bsp/raspi2/figures/raspi2.png → bsp/raspberry-pi/raspi2/figures/raspi2.png


+ 0 - 0
bsp/raspi2/figures/raspi_uart.png → bsp/raspberry-pi/raspi2/figures/raspi_uart.png


BIN
bsp/raspberry-pi/raspi2/kernel7.img


+ 0 - 0
bsp/raspi2/link.lds → bsp/raspberry-pi/raspi2/link.lds


+ 0 - 0
bsp/raspi2/rtconfig.h → bsp/raspberry-pi/raspi2/rtconfig.h


+ 2 - 2
bsp/raspi2/rtconfig.py → bsp/raspberry-pi/raspi2/rtconfig.py

@@ -8,13 +8,13 @@ CROSS_TOOL  ='gcc'
 if os.getenv('RTT_ROOT'):
     RTT_ROOT = os.getenv('RTT_ROOT')
 else:
-    RTT_ROOT = r'../..'
+    RTT_ROOT = r'../../..'
 
 if os.getenv('RTT_CC'):
     CROSS_TOOL = os.getenv('RTT_CC')
 
 PLATFORM    = 'gcc'
-EXEC_PATH   = r'/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
+EXEC_PATH   = r'/opt/gcc-arm-none-eabi-5_4-2016q3/bin'
 
 if os.getenv('RTT_EXEC_PATH'):
     EXEC_PATH = os.getenv('RTT_EXEC_PATH')

+ 427 - 0
bsp/raspberry-pi/raspi3-32/.config

@@ -0,0 +1,427 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Project Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+CONFIG_RT_USING_SMP=y
+CONFIG_RT_CPUS_NR=4
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=256
+# CONFIG_RT_USING_TIMER_SOFT is not set
+CONFIG_RT_DEBUG=y
+CONFIG_RT_DEBUG_COLOR=y
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
+
+#
+# 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=y
+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=y
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_DEVICE_OPS=y
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
+CONFIG_RT_VER_NUM=0x40002
+CONFIG_ARCH_ARM=y
+# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_ARM_CORTEX_A=y
+CONFIG_ARCH_ARM_CORTEX_A7=y
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# 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_ECHO_DISABLE_DEFAULT is not set
+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=y
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=16
+# CONFIG_RT_USING_DFS_MNTTABLE is not set
+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 is not set
+# 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=y
+CONFIG_RT_DFS_ELM_USE_LFN=3
+CONFIG_RT_DFS_ELM_MAX_LFN=255
+CONFIG_RT_DFS_ELM_DRIVES=2
+CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
+# 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_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 is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_PIPE_BUFSZ=512
+# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_SERIAL_USING_DMA is not set
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# CONFIG_RT_USING_CAN is not set
+CONFIG_RT_USING_HWTIMER=y
+# CONFIG_RT_USING_CPUTIME is not set
+CONFIG_RT_USING_I2C=y
+# CONFIG_RT_USING_I2C_BITOPS is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_PM is not set
+CONFIG_RT_USING_RTC=y
+# CONFIG_RT_USING_ALARM is not set
+# CONFIG_RT_USING_SOFT_RTC is not set
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_SDIO_STACK_SIZE=512
+CONFIG_RT_SDIO_THREAD_PRIORITY=15
+CONFIG_RT_MMCSD_STACK_SIZE=1024
+CONFIG_RT_MMCSD_THREAD_PREORITY=22
+CONFIG_RT_MMCSD_MAX_PARTITION=16
+# CONFIG_RT_SDIO_DEBUG is not set
+CONFIG_RT_USING_SPI=y
+# CONFIG_RT_USING_QSPI is not set
+# CONFIG_RT_USING_SPI_MSD is not set
+# CONFIG_RT_USING_SFUD 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_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH is not set
+# CONFIG_RT_USING_HWCRYPTO is not set
+# 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 is not set
+CONFIG_RT_USING_POSIX=y
+# CONFIG_RT_USING_POSIX_MMAP is not set
+# CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+# CONFIG_RT_USING_SAL is not set
+
+#
+# Network interface device
+#
+# CONFIG_RT_USING_NETDEV is not set
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+# CONFIG_RT_USING_LWP is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET 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_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_FREEMODBUS 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
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER 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_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ADBD is not set
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_PERSIMMON is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_LCD_DRIVERS is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_LIBANN is not set
+CONFIG_BCM2836_SOC=y
+
+#
+# Hardware Drivers Config
+#
+
+#
+# BCM Peripheral Drivers
+#
+CONFIG_BSP_USING_UART=y
+# CONFIG_RT_USING_UART0 is not set
+CONFIG_RT_USING_UART1=y
+CONFIG_BSP_USING_PIN=y
+CONFIG_BSP_USING_SYSTIMER=y
+CONFIG_RT_USING_SYSTIMER1=y
+CONFIG_RT_USING_SYSTIMER3=y
+CONFIG_BSP_USING_I2C=y
+CONFIG_BSP_USING_I2C0=y
+CONFIG_BSP_USING_I2C1=y
+CONFIG_BSP_USING_SPI=y
+CONFIG_BSP_USING_SPI0_BUS=y
+CONFIG_BSP_USING_SPI0_DEVICE0=y
+CONFIG_BSP_USING_SPI0_DEVICE1=y
+CONFIG_BSP_USING_WDT=y
+CONFIG_BSP_USING_RTC=y
+# CONFIG_BSP_USING_ALARM is not set
+CONFIG_BSP_USING_SDIO=y
+CONFIG_BSP_USING_SDIO0=y
+CONFIG_BSP_USING_HDMI=y

+ 0 - 0
bsp/raspi2/Kconfig → bsp/raspberry-pi/raspi3-32/Kconfig


+ 153 - 0
bsp/raspberry-pi/raspi3-32/README.md

@@ -0,0 +1,153 @@
+# Raspberry PI 3B(32位)板级支持包说明
+
+## 1. 简介
+
+树莓派由注册于英国的慈善组织“Raspberry Pi 基金会”开发,莓派3采用4核Broadcom BCM2837 (ARMv8)芯片、双核VideoCore IV GPU和1GB内存。
+
+这份RT-Thread BSP是针对 Raspberry Pi 3B (32位)的一份移植,树莓派价格便宜, 使用者甚众,是研究和运行RT-Thread的可选平台之一。
+
+随着RT-Thread的发展,它越来越多的向一些Cortex-A等AP类处理器提供支持,例如全志的ARM9、Cortex-A处理器,Xilinx的Zynq处理器等。
+
+而RT-Thread也是一套高度社区化发展的操作系统,所以在一些方向推进上希望以社区化方式,大家一起来推动的方式向前发展,在这个过程中RT-Thread得到了不同开发者、不同领域的应用,一步步把RT-Thread推向成熟。而在Cortex-A平台上,目前最流行的硬件平台是树莓派,分树莓派[2B](https://www.raspberrypi.org/products/raspberry-pi-2-model-b/)、[3B](https://www.raspberrypi.org/products/raspberry-pi-3-model-b/)以及最新的[4B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/)等。
+
+RT-Thread对树莓派的支持主要从树莓派2B开始,它是一个四核Cortex-A7的平台,以32位单核的模式运行。后续将推动着RT-Thread向树莓派3,四核Cortex-A53 64位模式发展(中间当然也可能出现四核Cortex-A7模式执行的过渡性版本)。
+
+![raspi3_f](figures/raspi3_f.jpg)
+
+![raspi3_b](figures/raspi3_b.jpg)
+
+当前Raspberry Pi 3B对应的硬件特性:
+
+| 硬件   | 描述 |
+|------- | ------------------------------- |
+|  CPU   | quad-core ARM Cortex A53(ARMv8) |
+|  主频  | 1.2 GHz |
+| GPU | VideoCore IV |
+| GPU频率 | 400MHz |
+| Memory | 1GB  (0x0000000 - 0x40000000) |
+| | 其中0x3f000000 - 0x40000000为peripheral |
+
+硬件引脚分布情况
+
+![GPIO-Pinout-Diagram-2](figures/GPIO-Pinout-Diagram-2.png)
+
+## 2. 编译说明
+
+Windows环境下推荐使用[env工具][1]进行编译。
+
+Linux下推荐使用gcc工具 [gcc-arm-none-eabi-4_8-2014q1_linux][2],如果还没有编译工具,下载后,解开文件。
+
+```
+tar vxf gcc-arm-none-eabi-4_8-2014q1_linux.tar.bz2
+```
+
+Linux环境下需要修改编译器目录设置,修改`bsp/raspi3-32/rtconfig.py`中的
+
+```
+EXEC_PATH = r'/opt/gcc-arm-none-eabi-4_8-2014q1_gri/bin'
+```
+
+为编译工具的实际所在目录,这里注意要加上后缀 `/bin`
+
+进入到`rt-thread/bsp/raspi3-32`目录中,运行以下命令:
+
+```
+scons
+```
+
+来编译这个板级支持包。如果编译正确无误,会产生rtthread.elf、kernel7.img文件。
+kernel7.img即是要cp到raspberry SD卡中根目录的文件
+
+### 2.1 eclipse 编码环境 ###
+第一步: 安装 eclipse cdt 
+第二步: 打开 eclipse cdt 设置workspace ,推荐设置于xxx\xxx\rt-thread\bsp
+第三步: Import 工程 General-> Existing Peojects into Workspace 然后 Browse.. 你的raspi3目录,点击Finish
+
+btw:编译依旧使用scons,目前不支持qemu debug,后期如果有大佬实现ARM JTAG调试
+
+## 3. 执行
+
+### 3.1 下载[raspbian镜像][3],生成可以运行的raspbian SD卡
+
+Windows下,去[etcher.io][4]下载etcher,这是个可以烧写img的工具
+
+解开下载的镜像文件, linux下使用如下的命令
+
+```
+unzip 2018-06-27-raspbian-stretch-lite.zip
+```
+
+准备一张空SD卡,linux环境下,插入电脑并执行
+
+```
+sudo dd if=2018-06-27-raspbian-stretch-lite.img of=/dev/xxx bs=32M conv=fsync
+```
+
+**注意: /dev/xxx 要换成真实环境中的SD卡所在设置,千万不要弄错。**
+
+Windows环境下,执行etcher选择解压后的2018-06-27-raspbian-stretch-lite.img文件和SD卡就可以开始烧写了。
+
+最后把kernel7.img放入SD boot分区,覆盖原来的文件。
+
+### 3.2 准备好串口线
+
+目前版本是使用raspi3的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示:
+
+
+
+![raspberrypi-console](figures/raspberrypi-console.png)
+
+串口参数: 115200 8N1 ,硬件和软件流控为关。
+
+按上面的方法做好SD卡后,插入树莓派3B,通电可以在串口上看到如下所示的输出信息:
+
+```text
+heap: 0x0005d784 - 0x0045d784
+
+ \ | /
+- RT -     Thread Operating System
+ / | \     4.0.2 build Jan  9 2020
+ 2006 - 2019 Copyright by rt-thread team
+[I/I2C] I2C bus [i2c0] registered
+[I/I2C] I2C bus [i2c1] registered
+[I/SDIO] SD card capacity 15558144 KB.
+found part[0], begin: 1048576, size: 63.0MB
+found part[1], begin: 67108864, size: 14.793GB
+file system initialization done!
+boot cpu:3
+msh />cpu = 0x00000003
+cpu 3 startup.
+start OK: CPU 3
+boot cpu:2
+cpu = 0x00000002
+cpu 2 startup.
+start OK: CPU 2
+boot cpu:1
+cpu = 0x00000001
+cpu 1 startup.
+start OK: CPU 1
+Hello RT-Thread!
+
+msh />
+```
+
+## 4. 支持情况
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | ----  | :------:  |
+| UART | 支持 | UART0|
+| GPIO | 支持 | |
+| IIC | 支持 | |
+| SPI | 支持 | |
+| CPU Timer | 支持 | |
+| SD卡驱动 | 支持 | |
+
+## 5. 联系人信息
+
+维护人:[bernard][5]
+
+[1]: https://www.rt-thread.org/page/download.html
+[2]: https://launchpad.net/gcc-arm-embedded/4.8/4.8-2014-q1-update/+download/gcc-arm-none-eabi-4_8-2014q1-20140314-linux.tar.bz2
+[3]: https://downloads.raspberrypi.org/raspbian_lite_latest
+[4]: https://etcher.io
+[5]: https://github.com/BernardXiong

+ 14 - 0
bsp/raspberry-pi/raspi3-32/SConscript

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

+ 28 - 0
bsp/raspberry-pi/raspi3-32/SConstruct

@@ -0,0 +1,28 @@
+import os
+import sys
+import rtconfig
+
+from rtconfig import RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+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 = False)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 9 - 0
bsp/raspberry-pi/raspi3-32/applications/SConscript

@@ -0,0 +1,9 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd, str(Dir('#'))]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 18 - 0
bsp/raspberry-pi/raspi3-32/applications/main.c

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30     bernard       the first version
+ */
+
+#include <rtthread.h>
+
+int main(int argc, char** argv)
+{
+    rt_kprintf("Hello RT-Thread!\n");
+
+    return 0;
+}

+ 29 - 0
bsp/raspberry-pi/raspi3-32/applications/mnt.c

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30     bernard       the first version
+ */
+
+#include <rtthread.h>
+
+#ifdef BSP_USING_SDIO0
+#include <dfs_fs.h>
+
+int mnt_init(void)
+{
+    rt_thread_delay(RT_TICK_PER_SECOND);
+
+    if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
+    {
+        rt_kprintf("file system initialization done!\n");
+    }
+
+    return 0;
+}
+INIT_ENV_EXPORT(mnt_init);
+#endif
+

+ 462 - 0
bsp/raspberry-pi/raspi3-32/applications/test_device.c

@@ -0,0 +1,462 @@
+/*
+ * File      : test_driver.h
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rthw.h>
+#include <string.h>
+#include <drivers/hwtimer.h>
+#include "raspi.h"
+
+#ifdef BSP_USING_HDMI
+#include "drv_fb.h"
+#endif
+
+void test_hdmi()
+{
+    rt_kprintf("Hello Test hdmi!\n");
+#ifdef BSP_USING_HDMI
+    print_fb_info();
+#ifdef BSP_USING_HDMI_DISPLAY
+    rt_kprintf("hdmi is tested!\n");
+#else
+    rt_console_set_device("hdmi");
+    rt_kprintf("hdmi is testing!\n");
+#endif
+    rt_kprintf("search hdmi device");
+    rt_device_t hdmi = rt_device_find("hdmi");
+    if (hdmi == RT_NULL)
+    {
+        rt_kprintf("cannot find hdmi device");
+    }
+    int color = COLOR_YELLOW;
+    rt_kprintf("begin test hdmi deivice");
+    rt_graphix_ops(hdmi) -> set_pixel((char *)&color, 5, 5);
+
+    rt_graphix_ops(hdmi) -> get_pixel((char *)&color, 5, 5);
+    rt_kprintf("color is %x\n",color);
+    rt_graphix_ops(hdmi) -> draw_hline((char *)&color, 10, 100, 10);
+    color = COLOR_GREEN;
+    rt_graphix_ops(hdmi) -> draw_vline((char *)&color, 10, 10, 100);
+    int colors[100];
+    int i=0;
+    for (; i < 20; i++)  colors[i] = COLOR_RED;
+    rt_graphix_ops(hdmi) -> blit_line((char *)colors, 20, 20, 20);
+    
+#endif
+}
+
+#ifdef RT_USING_SMP
+#define _CPUS_NR                RT_CPUS_NR
+#else
+#define _CPUS_NR                1
+#endif
+
+#ifdef RT_USING_SMP
+static rt_uint8_t rt_thread_stack[_CPUS_NR][128];
+static struct rt_thread smp[_CPUS_NR];
+void smp_test_entry()
+{
+    rt_kprintf("cpu %d is running.\n",rt_hw_cpu_id());
+}
+#endif
+
+void test_cpusmp(void)
+{
+    rt_kprintf("Hello Test SMP!\n");
+#ifdef RT_USING_SMP
+    int i;    
+    char test_name[RT_NAME_MAX]; 
+    for (i = 0; i < _CPUS_NR; i++)
+    {
+        rt_sprintf(test_name, "smp%d", i);
+        rt_thread_init(&smp[i],
+                test_name,
+                smp_test_entry,
+                RT_NULL,
+                &rt_thread_stack[i][0],
+                sizeof(rt_thread_stack[i]),
+                RT_THREAD_PRIORITY_MAX - 2,
+                32);
+        rt_thread_control(&smp[i], RT_THREAD_CTRL_BIND_CPU, (void*)i);
+        /* startup */
+        rt_thread_startup(&smp[i]);
+        rt_thread_delay(RT_TICK_PER_SECOND);
+    }
+#endif
+}
+
+#ifdef BSP_USING_PIN
+#define TEST_PIN_OUT 33
+#define TEST_PIN_IN 37
+
+void gpio_rising_test()
+{
+     rt_kprintf("gpio rising irq function ok!\n");
+}
+#endif
+
+void test_gpio(void)
+{
+#ifdef BSP_USING_PIN
+    rt_uint32_t ret;
+    rt_kprintf("Hello Test GPIO!\n");
+
+    rt_pin_mode(TEST_PIN_OUT, PIN_MODE_OUTPUT);
+    rt_pin_write(TEST_PIN_OUT, PIN_HIGH);
+    rt_pin_mode(TEST_PIN_IN, PIN_MODE_INPUT);
+
+    ret = rt_pin_read(TEST_PIN_IN);
+    rt_kprintf("common high input test read result: %d\n",ret);
+
+    rt_pin_write(TEST_PIN_OUT, PIN_LOW);
+    ret = rt_pin_read(TEST_PIN_IN);
+    rt_kprintf("common low input test read result: %d\n",ret);
+
+    rt_pin_mode(TEST_PIN_IN, PIN_MODE_INPUT_PULLDOWN);
+    rt_pin_attach_irq(TEST_PIN_IN, PIN_IRQ_MODE_RISING, gpio_rising_test, RT_NULL);
+    rt_pin_irq_enable(TEST_PIN_IN, PIN_IRQ_ENABLE);
+    rt_pin_write(TEST_PIN_OUT, PIN_HIGH);
+
+    rt_pin_irq_enable(TEST_PIN_IN, PIN_IRQ_DISABLE);
+#endif
+}
+
+#ifdef BSP_USING_I2C1
+#define DS3231_I2C_BUS_NAME      "i2c1"
+#define DS3231_ADDR               0x68
+struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
+{
+    struct rt_i2c_msg msgs;
+    msgs.addr = DS3231_ADDR;
+    msgs.flags = RT_I2C_RD;
+    msgs.buf = buf;
+    msgs.len = len;
+
+    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
+        return RT_EOK;
+    else
+        return -RT_ERROR;
+}
+#endif
+
+void test_i2c(void)
+{
+#ifdef BSP_USING_I2C1
+    rt_kprintf("Hello Test I2C!\n");
+    char name[RT_NAME_MAX];
+    rt_uint8_t  buf[]={0x00,0x00,0x43,0x15,0x05,0x01,0x03,0x19};
+
+    rt_strncpy(name, DS3231_I2C_BUS_NAME, RT_NAME_MAX);
+    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
+    if (i2c_bus == RT_NULL)
+        rt_kprintf("can't find %s device!\n", name);
+    else
+    {
+    	read_regs(i2c_bus, 7, buf);
+    	buf[0] = buf[0]&0x7F; //sec
+    	buf[1] = buf[1]&0x7F; //min
+    	buf[2] = buf[2]&0x3F; //hour
+    	buf[3] = buf[3]&0x07; //week
+    	buf[4] = buf[4]&0x3F; //day
+    	buf[5] = buf[5]&0x1F; //mouth
+    	//year/month/day
+    	rt_kprintf("20%02x-%02x-%02x ",buf[6],buf[5],buf[4]);
+    	//hour:minute/second
+    	rt_kprintf("%02x:%02x:%02x \n",buf[2],buf[1],buf[0]);
+    }
+#endif
+}
+
+#define W25Q_SPI_DEVICE_NAME     "spi0.0"
+void test_spi(void)
+{
+#ifdef BSP_USING_SPI
+    rt_kprintf("Hello Test SPI!\n");
+    struct rt_spi_device *spi0_dev0;
+    struct rt_spi_device *spi0_dev1;
+
+    char name0[RT_NAME_MAX];
+    char name1[RT_NAME_MAX];
+
+    rt_uint8_t w25x_read_id = 0x90;
+    rt_uint8_t id[5] = {0};
+
+    rt_strncpy(name0, "spi0.0", RT_NAME_MAX);
+    rt_strncpy(name1, "spi0.1", RT_NAME_MAX);
+
+    spi0_dev0 = (struct rt_spi_device *)rt_device_find(name0);
+    spi0_dev1 = (struct rt_spi_device *)rt_device_find(name1);
+
+
+    if (!spi0_dev0 || !spi0_dev1)
+    {
+        rt_kprintf("spi sample run failed! can't find %s device!\n", name0);
+    }
+    else
+    {
+        struct rt_spi_message msg1, msg2;
+
+        msg1.send_buf   = &w25x_read_id;
+        msg1.recv_buf   = RT_NULL;
+        msg1.length     = 1;
+        msg1.cs_take    = 1;
+        msg1.cs_release = 0;
+        msg1.next       = &msg2;
+
+        msg2.send_buf   = RT_NULL;
+        msg2.recv_buf   = id;
+        msg2.length     = 5;
+        msg2.cs_take    = 0;
+        msg2.cs_release = 1;
+        msg2.next       = RT_NULL;
+
+        rt_spi_transfer_message(spi0_dev0, &msg1);
+        rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);
+
+    }
+#endif
+}
+
+#ifdef BSP_USING_SYSTIMER
+#define TIMER   "timer1"
+
+static rt_err_t timer_timeout_cb(rt_device_t dev, rt_size_t size)
+{
+    rt_kprintf("enter hardware timer isr\n");
+    return 0;
+}
+#endif
+rt_err_t test_hwtimer(void)
+{
+#ifdef BSP_USING_SYSTIMER
+    rt_kprintf("Hello Test HW Timer!\n");
+    rt_err_t err;
+    rt_hwtimerval_t val;
+    rt_device_t dev = RT_NULL;
+    rt_tick_t tick;
+    rt_hwtimer_mode_t mode;
+    int t = 5;
+
+    if ((dev = rt_device_find(TIMER)) == RT_NULL)
+    {
+        rt_kprintf("No Device: %s\n", TIMER);
+        return -1;
+    }
+
+    if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
+    {
+        rt_kprintf("Open %s Fail\n", TIMER);
+        return -1;
+    }
+
+    mode = HWTIMER_MODE_PERIOD;
+    err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode);
+
+    tick = rt_tick_get();
+    rt_kprintf("Start Timer> Tick: %d\n", tick);
+
+    val.sec = t;
+    val.usec = 0;
+    rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec);
+    if (rt_device_write(dev, 0, &val, sizeof(val)) != sizeof(val))
+    {
+        rt_kprintf("SetTime Fail\n");
+        goto EXIT;
+    }
+    rt_kprintf("Sleep %d sec\n", t);
+    rt_thread_delay(t*RT_TICK_PER_SECOND);
+
+    err = rt_device_control(dev, HWTIMER_CTRL_STOP, RT_NULL);
+    rt_kprintf("Timer Stoped\n");
+
+    rt_device_read(dev, 0, &val, sizeof(val));
+    rt_kprintf("Read: Sec = %d, Usec = %d\n", val.sec, val.usec);
+
+    rt_device_set_rx_indicate(dev, timer_timeout_cb);
+
+    mode = HWTIMER_MODE_PERIOD;
+    err = rt_device_control(dev, HWTIMER_CTRL_MODE_SET, &mode);
+
+    val.sec = t;
+    val.usec = 0;
+    rt_kprintf("SetTime: Sec %d, Usec %d\n", val.sec, val.usec);
+    if (rt_device_write(dev, 0, &val, sizeof(val)) != sizeof(val))
+    {
+        rt_kprintf("SetTime Fail\n");
+        goto EXIT;
+    }
+
+    rt_thread_delay((t *5 + 1)*RT_TICK_PER_SECOND);
+
+EXIT:
+    err = rt_device_close(dev);
+    rt_kprintf("Close %s\n", TIMER);
+
+    return err;
+#endif
+}
+
+#ifdef RT_USING_WDT
+#define WDT_DEVICE_NAME    "wdg"    /* 鐪嬮棬鐙楄澶囧悕绉� */
+static rt_device_t wdg_dev;         /* 鐪嬮棬鐙楄澶囧彞鏌� */
+static void idle_hook(void)
+{
+    /* 鍦ㄧ┖闂茬嚎绋嬬殑鍥炶皟鍑芥暟閲屽杺鐙� */
+    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
+    //rt_kprintf("feed the dog!\n ");
+}
+
+rt_err_t test_wdt(void)
+{
+    rt_kprintf("Hello Test WDT!\n");
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t timeout = 1;        /* 婧㈠嚭鏃堕棿锛屽崟浣嶏細绉� */
+    char device_name[RT_NAME_MAX];
+    rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);
+    /* 鏍规嵁璁惧鍚嶇О鏌ユ壘鐪嬮棬鐙楄澶囷紝鑾峰彇璁惧鍙ユ焺 */
+    wdg_dev = rt_device_find(device_name);
+    if (!wdg_dev)
+    {
+        rt_kprintf("find %s failed!\n", device_name);
+        return RT_ERROR;
+    }
+    /* 鍒濆鍖栬澶� */
+    ret = rt_device_init(wdg_dev);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("initialize %s failed!\n", device_name);
+        return RT_ERROR;
+    }
+    /* 璁剧疆鐪嬮棬鐙楁孩鍑烘椂闂� */
+    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("set %s timeout failed!\n", device_name);
+        return RT_ERROR;
+    }
+    /* 鍚姩鐪嬮棬鐙� */
+    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("start %s failed!\n", device_name);
+        return -RT_ERROR;
+    }
+    /* 璁剧疆绌洪棽绾跨▼鍥炶皟鍑芥暟 */
+    rt_thread_idle_sethook(idle_hook);
+
+    return ret;
+
+}
+#else
+rt_err_t test_wdt(void)
+{
+    return RT_EOK;
+}
+#endif
+
+int test_rtc(void)
+{
+#ifdef BSP_USING_RTD
+    rt_kprintf("Hello Test RTC!\n");
+    uint8_t i;
+    time_t now;
+
+    rt_err_t ret = RT_EOK;
+
+    rt_kprintf("[RTC Test]RTC Test Start...\n");
+    rt_thread_delay(RT_TICK_PER_SECOND);
+    rt_kprintf("[RTC Test]Set RTC 2017-04-01 12:30:46\n\n");
+    rt_thread_delay(RT_TICK_PER_SECOND);
+
+    ret = set_date(2017, 4, 1);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("[RTC Test]Set RTC Date failed\n");
+        return RT_ERROR;
+    }
+
+    rt_thread_delay(RT_TICK_PER_SECOND);
+
+    ret = set_time(12, 30, 46);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("[RTC Test]Set RTC Time failed\n");
+        return RT_ERROR;
+    }
+
+    rt_thread_delay(RT_TICK_PER_SECOND);
+
+    for (i = 0; i < 10; i++)
+    {
+        rt_kprintf("[RTC Test]Read RTC Date and Time: ");
+        now = time(RT_NULL);
+        rt_kprintf("%s", ctime(&now));
+
+        rt_thread_delay(RT_TICK_PER_SECOND);
+    }
+
+    rt_kprintf("\n");
+#endif
+    return RT_EOK;
+}
+
+void test_device(int argc, char**argv)
+{
+    if (0 == strcmp(argv[1],"smp"))
+    {
+        test_cpusmp();
+        return;
+    }
+    if (0 == strcmp(argv[1],"gpio"))
+    {
+        test_gpio();
+        return;
+    }
+
+    if (0 == strcmp(argv[1],"i2c"))
+    {
+        test_i2c();
+        return;
+    }
+
+    if (0 == strcmp(argv[1],"spi"))
+    {
+        test_spi();
+        return;
+    }
+
+    if (0 == strcmp(argv[1],"hwtimer"))
+    {
+        test_hwtimer();
+        return;
+    }
+
+    if (0 == strcmp(argv[1],"wdt"))
+    {
+        test_wdt();
+        return;
+    }
+
+    if (0 == strcmp(argv[1],"rtc"))
+    {
+        test_rtc();
+        return;
+    }
+    if (0 == strcmp(argv[1],"hdmi"))
+    {
+        test_hdmi();
+        return;
+    }
+    rt_kprintf("param err, please entry test_device <smp|gpio|i2c|spi|hwtimer|wdt|rtc|hdmi>\n");
+}
+MSH_CMD_EXPORT(test_device, sample: test_device <smp|gpio|i2c|spi|hwtimer|wdt|rtc>);

+ 0 - 0
bsp/raspi2/cpu/SConscript → bsp/raspberry-pi/raspi3-32/cpu/SConscript


+ 74 - 0
bsp/raspberry-pi/raspi3-32/cpu/armv7.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-09-15     Bernard      first version
+ */
+
+#ifndef __ARMV7_H__
+#define __ARMV7_H__
+
+/* the exception stack without VFP registers */
+struct rt_hw_exp_stack
+{
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long fp;
+    unsigned long ip;
+    unsigned long sp;
+    unsigned long lr;
+    unsigned long pc;
+    unsigned long cpsr;
+};
+
+struct rt_hw_stack
+{
+    unsigned long cpsr;
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long fp;
+    unsigned long ip;
+    unsigned long lr;
+    unsigned long pc;
+};
+
+#define USERMODE    0x10
+#define FIQMODE     0x11
+#define IRQMODE     0x12
+#define SVCMODE     0x13
+#define MONITORMODE 0x16
+#define ABORTMODE   0x17
+#define HYPMODE     0x1b
+#define UNDEFMODE   0x1b
+#define MODEMASK    0x1f
+#define NOINT       0xc0
+
+#define T_Bit       (1<<5)
+#define F_Bit       (1<<6)
+#define I_Bit       (1<<7)
+#define A_Bit       (1<<8)
+#define E_Bit       (1<<9)
+#define J_Bit       (1<<24)
+
+#endif

+ 183 - 0
bsp/raspberry-pi/raspi3-32/cpu/context_gcc.S

@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-05     Bernard      the first version
+ * 2019-07-28     zdzn         add smp support
+ */
+
+#include "../rtconfig.h"
+.section .text, "ax"
+
+#ifdef RT_USING_SMP
+#define rt_hw_interrupt_disable rt_hw_local_irq_disable
+#define rt_hw_interrupt_enable  rt_hw_local_irq_enable
+#endif
+
+/*
+ * rt_base_t rt_hw_interrupt_disable();
+ */
+.globl rt_hw_interrupt_disable
+rt_hw_interrupt_disable:
+    mrs r0, cpsr
+    cpsid i
+    bx  lr
+
+/*
+ * void rt_hw_interrupt_enable(rt_base_t level);
+ */
+.globl rt_hw_interrupt_enable
+rt_hw_interrupt_enable:
+    msr cpsr, r0
+    bx  lr
+
+/*
+ * void rt_hw_context_switch_to(rt_uint32 to, struct rt_thread *to_thread);
+ * r0 --> to (thread stack)
+ * r1 --> to_thread
+ */
+.globl rt_hw_context_switch_to
+rt_hw_context_switch_to:
+    ldr sp, [r0]            @ get new task stack pointer
+
+#ifdef RT_USING_SMP
+    mov     r0, r1
+    bl      rt_cpus_lock_status_restore
+#endif /*RT_USING_SMP*/
+    b       rt_hw_context_switch_exit
+
+.section .bss.share.isr
+_guest_switch_lvl:
+    .word 0
+
+.globl vmm_virq_update
+
+.section .text.isr, "ax"
+/*
+ * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to, struct rt_thread *to_thread);
+ * r0 --> from (from_thread stack)
+ * r1 --> to (to_thread stack)
+ * r2 --> to_thread
+ */
+.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
+    tst lr, #0x01
+    orrne r4, r4, #0x20     @ it's thumb code
+
+    stmfd sp!, {r4}         @ push cpsr
+
+#ifdef RT_USING_LWP
+    stmfd sp, {r13, r14}^   @ push usr_sp usr_lr
+    sub sp, #8
+#endif
+#ifdef RT_USING_FPU
+    /* fpu context */
+    vmrs r6, fpexc
+    tst  r6, #(1<<30)
+    beq 1f
+    vstmdb sp!, {d0-d15}
+    vstmdb sp!, {d16-d31}
+    vmrs r5, fpscr
+    stmfd sp!, {r5}
+1:
+    stmfd sp!, {r6}
+#endif
+
+    str sp, [r0]            @ store sp in preempted tasks TCB
+    ldr sp, [r1]            @ get new task stack pointer
+
+#ifdef RT_USING_SMP
+    mov     r0, r2
+    bl      rt_cpus_lock_status_restore
+#endif /*RT_USING_SMP*/
+    b       rt_hw_context_switch_exit
+
+/*
+ * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
+ */
+.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
+
+.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:
+#ifdef RT_USING_SMP
+    /* r0 :svc_mod context
+     * r1 :addr of from_thread's sp
+     * r2 :addr of to_thread's sp
+     * r3 :to_thread's tcb
+     */
+
+    str     r0, [r1]
+
+    ldr     sp, [r2]
+    mov     r0, r3
+    bl      rt_cpus_lock_status_restore
+
+    b       rt_hw_context_switch_exit
+
+#else /*RT_USING_SMP*/
+    ldr r2, =rt_thread_switch_interrupt_flag
+    ldr r3, [r2]
+    cmp r3, #1
+    beq _reswitch
+    ldr ip, =rt_interrupt_from_thread   @ set rt_interrupt_from_thread
+    mov r3, #1              @ set rt_thread_switch_interrupt_flag to 1
+    str r0, [ip]
+    str r3, [r2]
+_reswitch:
+    ldr r2, =rt_interrupt_to_thread     @ set rt_interrupt_to_thread
+    str r1, [r2]
+    bx  lr
+#endif /*RT_USING_SMP*/
+
+.global rt_hw_context_switch_exit
+rt_hw_context_switch_exit:
+
+#ifdef RT_USING_SMP
+#ifdef RT_USING_SIGNALS
+    mov     r0, sp
+    cps #Mode_IRQ
+    bl      rt_signal_check
+    cps #Mode_SVC
+    mov     sp, r0
+#endif
+#endif
+#ifdef RT_USING_FPU
+/* fpu context */
+    ldmfd sp!, {r6}
+    vmsr fpexc, r6
+    tst  r6, #(1<<30)
+    beq 1f
+    ldmfd sp!, {r5}
+    vmsr fpscr, r5
+    vldmia sp!, {d16-d31}
+    vldmia sp!, {d0-d15}
+
+#endif
+
+#ifdef RT_USING_LWP
+    ldmfd   sp, {r13, r14}^ /* usr_sp, usr_lr */
+    add     sp, #8
+#endif
+    ldmfd   sp!, {r4}
+    msr     spsr_cxsf, r4        /* original mode */
+    ldmfd   sp!, {r0-r12,lr,pc}^ /* irq return */
+

+ 168 - 0
bsp/raspberry-pi/raspi3-32/cpu/cp15.h

@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-09-15     Bernard      first version
+ */
+#include "raspi.h"
+#ifndef __CP15_H__
+#define __CP15_H__
+
+#ifndef   __STATIC_FORCEINLINE
+#define __STATIC_FORCEINLINE     __attribute__((always_inline)) static inline
+#endif
+
+#define __WFI()    __asm__ volatile ("wfi":::"memory")
+
+#define __WFE()    __asm__ volatile ("wfe":::"memory")
+
+#define __SEV()    __asm__ volatile ("sev")
+
+__STATIC_FORCEINLINE  void __ISB(void)
+{
+    __asm__ volatile ("isb 0xF":::"memory");
+}
+
+
+/**
+  \brief   Data Synchronization Barrier
+  \details Acts as a special kind of Data Memory Barrier.
+           It completes when all explicit memory accesses before this instruction complete.
+ */
+__STATIC_FORCEINLINE  void __DSB(void)
+{
+    __asm__ volatile ("dsb 0xF":::"memory");
+}
+
+/**
+  \brief   Data Memory Barrier
+  \details Ensures the apparent order of the explicit memory operations before
+           and after the instruction, without ensuring their completion.
+ */
+
+__STATIC_FORCEINLINE  void __DMB(void)
+{
+    __asm__ volatile ("dmb 0xF":::"memory");
+}
+
+
+#ifdef RT_USING_SMP
+static inline void send_ipi_msg(int cpu, int ipi_vector)
+{
+    IPI_MAILBOX_SET(cpu) = 1 << ipi_vector;
+}
+
+static inline void setup_bootstrap_addr(int cpu, int addr)
+{
+	CORE_MAILBOX3_SET(cpu) = addr;
+}
+
+static inline void enable_cpu_ipi_intr(int cpu)
+{
+    COREMB_INTCTL(cpu) = IPI_MAILBOX_INT_MASK;
+}
+
+static inline void enable_cpu_timer_intr(int cpu)
+{
+	CORETIMER_INTCTL(cpu) = 0x8;
+}
+
+static inline void enable_cntv(void)
+{
+    rt_uint32_t cntv_ctl;
+    cntv_ctl = 1;
+    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL
+}
+
+static inline void disable_cntv(void)
+{
+    rt_uint32_t cntv_ctl;
+    cntv_ctl = 0;
+    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL
+}
+
+static inline  void mask_cntv(void)
+{
+    rt_uint32_t cntv_ctl;
+    cntv_ctl = 2;
+    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL
+}
+
+static inline void unmask_cntv(void)
+{
+    rt_uint32_t cntv_ctl;
+    cntv_ctl = 1;
+    asm volatile ("mcr p15, 0, %0, c14, c3, 1" :: "r"(cntv_ctl)); // write CNTV_CTL
+}
+
+static inline rt_uint64_t read_cntvct(void)
+{
+    rt_uint32_t val,val1;
+    asm volatile ("mrrc p15, 1, %0, %1, c14" : "=r" (val),"=r" (val1));
+    return (val);
+}
+
+static inline rt_uint64_t read_cntvoff(void)
+{
+
+    rt_uint64_t val;
+    asm volatile ("mrrc p15, 4, %Q0, %R0, c14" : "=r" (val));
+    return (val);
+}
+
+static inline rt_uint32_t read_cntv_tval(void)
+{
+    rt_uint32_t val;
+    asm volatile ("mrc p15, 0, %0, c14, c3, 0" : "=r"(val));
+    return val;
+}
+
+
+static inline  void write_cntv_tval(rt_uint32_t val)
+{
+    asm volatile ("mcr p15, 0, %0, c14, c3, 0" :: "r"(val));
+    return;
+}
+
+static inline rt_uint32_t read_cntfrq(void)
+{
+    rt_uint32_t val;
+    asm volatile ("mrc p15, 0, %0, c14, c0, 0" : "=r"(val));
+    return val;
+}
+
+
+static inline  rt_uint32_t read_cntctrl(void)
+{
+    rt_uint32_t val;
+    asm volatile ("mrc p15, 0, %0, c14, c1, 0" : "=r"(val));
+    return val;
+}
+
+static inline uint32_t write_cntctrl(uint32_t val)
+{
+
+    asm volatile ("mcr p15, 0, %0, c14, c1, 0" : :"r"(val));
+    return val;
+}
+#endif
+
+unsigned long rt_cpu_get_smp_id(void);
+
+void rt_cpu_mmu_disable(void);
+void rt_cpu_mmu_enable(void);
+void rt_cpu_tlb_set(volatile unsigned long*);
+
+void rt_cpu_dcache_clean_flush(void);
+void rt_cpu_icache_flush(void);
+
+void rt_cpu_vector_set_base(unsigned int addr);
+void rt_hw_mmu_init(void);
+void rt_hw_vector_init(void);
+
+void set_timer_counter(unsigned int counter);
+void set_timer_control(unsigned int control);
+#endif

+ 147 - 0
bsp/raspberry-pi/raspi3-32/cpu/cp15_gcc.S

@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-05     Bernard      the first version
+ */
+
+.globl rt_cpu_get_smp_id
+rt_cpu_get_smp_id:
+    mrc     p15, #0, r0, c0, c0, #5
+    bx      lr
+
+.globl rt_cpu_vector_set_base
+rt_cpu_vector_set_base:
+    /* clear SCTRL.V to customize the vector address */
+    mrc     p15, #0, r1, c1, c0, #0
+    bic     r1, #(1 << 13)
+    mcr     p15, #0, r1, c1, c0, #0
+    /* set up the vector address */
+    mcr     p15, #0, r0, c12, c0, #0
+    dsb
+    bx      lr
+
+.globl rt_hw_cpu_dcache_enable
+rt_hw_cpu_dcache_enable:
+    mrc     p15, #0, r0, c1, c0, #0
+    orr     r0,  r0, #0x00000004
+    mcr     p15, #0, r0, c1, c0, #0
+    bx      lr
+
+.globl rt_hw_cpu_icache_enable
+rt_hw_cpu_icache_enable:
+    mrc     p15, #0, r0, c1, c0, #0
+    orr     r0,  r0, #0x00001000
+    mcr     p15, #0, r0, c1, c0, #0
+    bx      lr
+
+_FLD_MAX_WAY:
+   .word  0x3ff
+_FLD_MAX_IDX:
+   .word  0x7ff
+
+.globl set_timer_counter
+set_timer_counter:
+    mcr     p15, #0, r0, c14, c3, #0  @ write virtual timer timerval register
+    bx      lr
+.globl set_timer_control
+set_timer_control:
+    mcr     p15, #0, r0, c14, c3, #1  @ write virtual timer control register
+    bx      lr
+
+.globl rt_cpu_dcache_clean_flush
+rt_cpu_dcache_clean_flush:
+    push    {r4-r11}
+    dmb
+    mrc     p15, #1, r0, c0, c0, #1  @ read clid register
+    ands    r3, r0, #0x7000000       @ get level of coherency
+    mov     r3, r3, lsr #23
+    beq     finished
+    mov     r10, #0
+loop1:
+    add     r2, r10, r10, lsr #1
+    mov     r1, r0, lsr r2
+    and     r1, r1, #7
+    cmp     r1, #2
+    blt     skip
+    mcr     p15, #2, r10, c0, c0, #0
+    isb
+    mrc     p15, #1, r1, c0, c0, #0
+    and     r2, r1, #7
+    add     r2, r2, #4
+    ldr     r4, _FLD_MAX_WAY
+    ands    r4, r4, r1, lsr #3
+    clz     r5, r4
+    ldr     r7, _FLD_MAX_IDX
+    ands    r7, r7, r1, lsr #13
+loop2:
+    mov     r9, r4
+loop3:
+    orr     r11, r10, r9, lsl r5
+    orr     r11, r11, r7, lsl r2
+    mcr     p15, #0, r11, c7, c14, #2
+    subs    r9, r9, #1
+    bge     loop3
+    subs    r7, r7, #1
+    bge     loop2
+skip:
+    add     r10, r10, #2
+    cmp     r3, r10
+    bgt     loop1
+
+finished:
+    dsb
+    isb
+    pop     {r4-r11}
+    bx      lr
+
+.globl rt_cpu_icache_flush
+rt_cpu_icache_flush:
+    mov r0, #0
+    mcr p15, 0, r0, c7, c5, 0       @ I+BTB cache invalidate
+    dsb
+    isb
+    bx      lr
+
+.globl rt_hw_cpu_dcache_disable
+rt_hw_cpu_dcache_disable:
+    push    {r4-r11, lr}
+    bl      rt_cpu_dcache_clean_flush
+    mrc     p15, #0, r0, c1, c0, #0
+    bic     r0,  r0, #0x00000004
+    mcr     p15, #0, r0, c1, c0, #0
+    pop     {r4-r11, lr}
+    bx      lr
+
+.globl rt_hw_cpu_icache_disable
+rt_hw_cpu_icache_disable:
+    mrc     p15, #0, r0, c1, c0, #0
+    bic     r0,  r0, #0x00001000
+    mcr     p15, #0, r0, c1, c0, #0
+    bx      lr
+
+.globl rt_cpu_mmu_disable
+rt_cpu_mmu_disable:
+    mcr     p15, #0, r0, c8, c7, #0    @ invalidate tlb
+    mrc     p15, #0, r0, c1, c0, #0
+    bic     r0, r0, #1
+    mcr     p15, #0, r0, c1, c0, #0    @ clear mmu bit
+    dsb
+    bx      lr
+
+.globl rt_cpu_mmu_enable
+rt_cpu_mmu_enable:
+    mrc     p15, #0, r0, c1, c0, #0
+    orr     r0, r0, #0x001
+    mcr     p15, #0, r0, c1, c0, #0    @ set mmu enable bit
+    dsb
+    bx      lr
+
+.globl rt_cpu_tlb_set
+rt_cpu_tlb_set:
+    mcr     p15, #0, r0, c2, c0, #0
+    dmb
+    bx      lr

+ 91 - 0
bsp/raspberry-pi/raspi3-32/cpu/cpu.c

@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-09-15     Bernard      first version
+ * 2019-07-28     zdzn         add smp support
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <board.h>
+#include "cp15.h"
+
+int rt_hw_cpu_id(void)
+{
+    int cpu_id;
+    __asm__ volatile (
+            "mrc p15, 0, %0, c0, c0, 5"
+            :"=r"(cpu_id)
+            );
+    cpu_id &= 0xf;
+    return cpu_id;
+};
+
+
+#ifdef RT_USING_SMP
+void rt_hw_spin_lock_init(rt_hw_spinlock_t *lock)
+{
+    lock->slock = 0;
+}
+
+void rt_hw_spin_lock(rt_hw_spinlock_t *lock)
+{
+    unsigned long tmp;
+    unsigned long newval;
+    rt_hw_spinlock_t lockval;
+    __asm__ __volatile__(
+            "pld [%0]"
+            ::"r"(&lock->slock)
+            );
+
+    __asm__ __volatile__(
+            "1: ldrex   %0, [%3]\n"
+            "   add %1, %0, %4\n"
+            "   strex   %2, %1, [%3]\n"
+            "   teq %2, #0\n"
+            "   bne 1b"
+            : "=&r" (lockval), "=&r" (newval), "=&r" (tmp)
+            : "r" (&lock->slock), "I" (1 << 16)
+            : "cc");
+
+    while (lockval.tickets.next != lockval.tickets.owner) 
+    {
+        __WFE();
+        lockval.tickets.owner = *(volatile unsigned short *)(&lock->tickets.owner);
+    }
+
+    __DMB();
+}
+
+void rt_hw_spin_unlock(rt_hw_spinlock_t *lock)
+{
+    __DMB();
+    lock->tickets.owner++;
+    __DSB();
+    __SEV();
+}
+#endif /*RT_USING_SMP*/
+
+/**
+ * @addtogroup ARM CPU
+ */
+/*@{*/
+
+/** shutdown CPU */
+void rt_hw_cpu_shutdown()
+{
+    rt_uint32_t level;
+    rt_kprintf("shutdown...\n");
+
+    level = rt_hw_interrupt_disable();
+    while (level)
+    {
+        RT_ASSERT(0);
+    }
+}
+
+/*@}*/

+ 186 - 0
bsp/raspberry-pi/raspi3-32/cpu/interrupt.c

@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018/5/3       Bernard      first version
+ * 2019-07-28     zdzn         add smp support
+ * 2019-08-09     zhangjun     fixup the problem of smp startup and scheduling issues, 
+ *                             write addr to mailbox3 to startup smp, and we use mailbox0 for ipi
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "cp15.h"
+#include <board.h>
+
+#define MAX_HANDLERS                72
+
+#ifdef RT_USING_SMP
+#define rt_interrupt_nest rt_cpu_self()->irq_nest
+#else
+extern volatile rt_uint8_t rt_interrupt_nest;
+#endif
+
+const unsigned int VECTOR_BASE = 0x00;
+extern void rt_cpu_vector_set_base(unsigned int addr);
+extern int system_vectors;
+
+void rt_hw_vector_init(void)
+{
+    rt_cpu_vector_set_base((unsigned int)&system_vectors);
+}
+
+/* exception and interrupt handler table */
+struct rt_irq_desc isr_table[MAX_HANDLERS];
+
+rt_uint32_t rt_interrupt_from_thread;
+rt_uint32_t rt_interrupt_to_thread;
+rt_uint32_t rt_thread_switch_interrupt_flag;
+
+extern int system_vectors;
+
+static void default_isr_handler(int vector, void *param)
+{
+#ifdef RT_USING_SMP
+    rt_kprintf("cpu %d unhandled irq: %d\n", rt_hw_cpu_id(),vector);
+#else
+    rt_kprintf("unhandled irq: %d\n",vector);
+#endif
+}
+
+/**
+ * This function will initialize hardware interrupt
+ */
+void rt_hw_interrupt_init(void)
+{
+    rt_uint32_t index;
+
+    /* mask all of interrupts */
+    IRQ_DISABLE_BASIC = 0x000000ff;
+    IRQ_DISABLE1      = 0xffffffff;
+    IRQ_DISABLE2      = 0xffffffff;
+    for (index = 0; index < MAX_HANDLERS; index ++)
+    {
+        isr_table[index].handler = default_isr_handler;
+        isr_table[index].param = NULL;
+#ifdef RT_USING_INTERRUPT_INFO
+        rt_strncpy(isr_table[index].name, "unknown", RT_NAME_MAX);
+        isr_table[index].counter = 0;
+#endif
+    }
+
+    /* 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 vector)
+{
+
+    if (vector < 32)
+    {
+        IRQ_DISABLE1 = (1 << vector);
+    }
+    else if (vector < 64)
+    {
+        vector = vector % 32;
+        IRQ_DISABLE2 = (1 << vector);
+    }
+    else
+    {
+        vector = vector - 64;
+        IRQ_DISABLE_BASIC = (1 << vector);
+    }
+}
+
+/**
+ * This function will un-mask a interrupt.
+ * @param vector the interrupt number
+ */
+void rt_hw_interrupt_umask(int vector)
+{
+    if (vector < 32)
+    {
+        IRQ_ENABLE1 = (1 << vector);
+    }
+    else if (vector < 64)
+    {
+        vector = vector % 32;
+        IRQ_ENABLE2 = (1 << vector);
+    }
+    else
+    {
+        vector = vector - 64;
+        IRQ_ENABLE_BASIC = (1 << vector);
+    }
+}
+
+/**
+ * This function will install a interrupt service routine to a interrupt.
+ * @param vector the interrupt number
+ * @param new_handler the interrupt service routine to be installed
+ * @param old_handler the old interrupt service routine
+ */
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name)
+{
+    rt_isr_handler_t old_handler = RT_NULL;
+
+    if (vector < MAX_HANDLERS)
+    {
+        old_handler = isr_table[vector].handler;
+
+        if (handler != RT_NULL)
+        {
+#ifdef RT_USING_INTERRUPT_INFO
+            rt_strncpy(isr_table[vector].name, name, RT_NAME_MAX);
+#endif /* RT_USING_INTERRUPT_INFO */
+            isr_table[vector].handler = handler;
+            isr_table[vector].param = param;
+        }
+    }
+
+    return old_handler;
+}
+
+#ifdef RT_USING_SMP
+void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask)
+{
+    __DSB();
+    if (cpu_mask & 0x1)
+    {
+        send_ipi_msg(0, ipi_vector);
+    }
+    if (cpu_mask & 0x2)
+    {
+    	send_ipi_msg(1, ipi_vector);
+    }
+    if (cpu_mask & 0x4)
+    {
+    	send_ipi_msg(2, ipi_vector);
+    }
+    if (cpu_mask & 0x8)
+    {
+    	send_ipi_msg(3, ipi_vector);
+    }
+    __DSB();
+}
+#endif
+
+#ifdef RT_USING_SMP
+void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler)
+{
+    /* note: ipi_vector maybe different with irq_vector */
+    rt_hw_interrupt_install(ipi_vector, ipi_isr_handler, 0, "IPI_HANDLER");
+}
+#endif

+ 18 - 0
bsp/raspberry-pi/raspi3-32/cpu/interrupt.h

@@ -0,0 +1,18 @@
+
+#ifndef __INTERRUPT_H__
+#define __INTERRUPT_H__
+
+#include <rthw.h>
+#include <board.h>
+
+#define INT_IRQ     0x00
+#define INT_FIQ     0x01
+
+void rt_hw_interrupt_init(void);
+void rt_hw_interrupt_mask(int vector);
+void rt_hw_interrupt_umask(int vector);
+
+rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
+        void *param, const char *name);
+
+#endif

+ 188 - 0
bsp/raspberry-pi/raspi3-32/cpu/mmu.c

@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-01-10     bernard      porting to AM1808
+ * 2019-07-28     zdzn         add smp support
+ */
+
+#include "mmu.h"
+
+/* dump 2nd level page table */
+void rt_hw_cpu_dump_page_table_2nd(rt_uint32_t *ptb)
+{
+    int i;
+    int fcnt = 0;
+
+    for (i = 0; i < 256; i++)
+    {
+        rt_uint32_t pte2 = ptb[i];
+        if ((pte2 & 0x3) == 0)
+        {
+            if (fcnt == 0)
+                rt_kprintf("    ");
+            rt_kprintf("%04x: ", i);
+            fcnt++;
+            if (fcnt == 16)
+            {
+                rt_kprintf("fault\n");
+                fcnt = 0;
+            }
+            continue;
+        }
+        if (fcnt != 0)
+        {
+            rt_kprintf("fault\n");
+            fcnt = 0;
+        }
+
+        rt_kprintf("    %04x: %x: ", i, pte2);
+        if ((pte2 & 0x3) == 0x1)
+        {
+            rt_kprintf("L,ap:%x,xn:%d,texcb:%02x\n",
+                       ((pte2 >> 7) | (pte2 >> 4))& 0xf,
+                       (pte2 >> 15) & 0x1,
+                       ((pte2 >> 10) | (pte2 >> 2)) & 0x1f);
+        }
+        else
+        {
+            rt_kprintf("S,ap:%x,xn:%d,texcb:%02x\n",
+                       ((pte2 >> 7) | (pte2 >> 4))& 0xf, pte2 & 0x1,
+                       ((pte2 >> 4) | (pte2 >> 2)) & 0x1f);
+        }
+    }
+}
+
+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);
+        }
+    }
+}
+
+/* level1 page table, each entry for 1MB memory. */
+volatile static unsigned long MMUTable[4*1024] __attribute__((aligned(16*1024)));
+void rt_hw_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 *)MMUTable + (vaddrStart >> 20);
+    nSec = (vaddrEnd >> 20) - (vaddrStart >> 20);
+    for (i = 0; i <= nSec; i++)
+    {
+        *pTT = attr | (((paddrStart >> 20) + i) << 20);
+        pTT++;
+    }
+}
+
+unsigned long rt_hw_set_domain_register(unsigned long domain_val)
+{
+    unsigned long old_domain;
+
+    asm volatile ("mrc p15, 0, %0, c3, c0\n" : "=r" (old_domain));
+    asm volatile ("mcr p15, 0, %0, c3, c0\n" : :"r" (domain_val) : "memory");
+
+    return old_domain;
+}
+
+void rt_hw_init_mmu_table()
+{
+    /* set page table */
+    /* 4G 1:1 memory */
+    rt_hw_mmu_setmtt(0x00000000, 0x3effffff, 0x00000000, NORMAL_MEM);
+    /* IO memory region */
+    rt_hw_mmu_setmtt(0x3f000000, 0x40010000, 0x3f000000, DEVICE_MEM);
+}
+
+void rt_hw_change_mmu_table(rt_uint32_t vaddrStart,
+                      rt_uint32_t size,
+                      rt_uint32_t paddrStart, rt_uint32_t attr)
+{
+    rt_hw_mmu_setmtt(vaddrStart, vaddrStart+size-1, paddrStart, attr);
+#ifndef RT_USING_SMP
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
+#endif
+}
+
+
+void rt_hw_mmu_init(void)
+{
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
+    rt_hw_cpu_dcache_disable();
+    rt_hw_cpu_icache_disable();
+    rt_cpu_mmu_disable();
+
+    /*rt_hw_cpu_dump_page_table(MMUTable);*/
+    rt_hw_set_domain_register(0x55555555);
+
+    rt_cpu_tlb_set(MMUTable);
+
+    rt_cpu_mmu_enable();
+
+    rt_hw_cpu_icache_enable();
+    rt_hw_cpu_dcache_enable();
+}
+

+ 51 - 0
bsp/raspberry-pi/raspi3-32/cpu/mmu.h

@@ -0,0 +1,51 @@
+#ifndef MMU_H__
+#define MMU_H__
+#include <rtthread.h>
+#include <rthw.h>
+#include <board.h>
+#include "cp15.h"
+
+#define DESC_SEC       (0x2)
+#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 XN             (1 << 4)  // eXecute Never
+#define SHARED         (1 << 16) /* shareable */
+#define SHAREDEVICE    (1 << 2)  /* shared device */
+#define STRONGORDER    (0 << 2)  /* strong ordered */
+#define MEMWBWA        ((1 << 12) | (3 << 2))     /* write back, write allocate */
+
+#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)
+
+/* Read/Write, cache, write back */
+#define RW_CB          (AP_RW | DOMAIN0 | CB | DESC_SEC)
+/* Read/Write, cache, write through */
+#define RW_CNB         (AP_RW | DOMAIN0 | CNB | DESC_SEC)
+/* Read/Write without cache and write buffer */
+#define RW_NCNB        (AP_RW | DOMAIN0 | NCNB | DESC_SEC)
+/* Read/Write without cache and write buffer, no execute */
+#define RW_NCNBXN      (AP_RW | DOMAIN0 | NCNB | DESC_SEC | XN)
+/* Read/Write without cache and write buffer */
+#define RW_FAULT       (AP_RW | DOMAIN1 | NCNB | DESC_SEC)
+
+/* device mapping type */
+#define DEVICE_MEM     (SHARED | SHAREDEVICE | RW_NCNBXN)
+/* normal memory mapping type */
+#define NORMAL_MEM     (SHARED | AP_RW | DOMAIN0 | MEMWBWA | DESC_SEC)
+#define STRONG_ORDER_MEM (SHARED | AP_RO | XN | DESC_SEC)
+#define BUS_ADDRESS(phys)	(((phys) & ~0xC0000000)  |  0xC0000000)
+
+void rt_hw_change_mmu_table(rt_uint32_t vaddrStart,
+                      rt_uint32_t size,
+                      rt_uint32_t paddrStart, rt_uint32_t attr);
+#endif

+ 72 - 0
bsp/raspberry-pi/raspi3-32/cpu/stack.c

@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-09-23     Bernard      the first version
+ * 2011-10-05     Bernard      add thumb mode
+ */
+#include <rtthread.h>
+#include <board.h>
+#include <armv7.h>
+
+/**
+ * @addtogroup AM33xx
+ */
+/*@{*/
+
+/**
+ * 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 */
+
+    /* cpsr */
+    if ((rt_uint32_t)tentry & 0x01)
+        *(--stk) = SVCMODE | 0x20;          /* thumb mode */
+    else
+        *(--stk) = SVCMODE;                 /* arm mode   */
+
+#ifdef RT_USING_LWP
+    *(--stk) = 0;       /* user lr */
+    *(--stk) = 0;       /* user sp*/
+#endif
+#ifdef RT_USING_FPU
+    *(--stk) = 0;       /* not use fpu*/
+#endif
+
+    /* return task's current stack address */
+    return (rt_uint8_t *)stk;
+}
+
+/*@}*/

+ 459 - 0
bsp/raspberry-pi/raspi3-32/cpu/start_gcc.S

@@ -0,0 +1,459 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-05     Bernard      the first version
+ * 2019-07-28     zdzn         add smp support
+ */
+
+#include "../rtconfig.h"
+.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
+
+#ifdef RT_USING_FPU
+.equ UND_Stack_Size,     0x00000400
+#else
+.equ UND_Stack_Size,     0x00000000
+#endif
+.equ SVC_Stack_Size,     0x00000400
+.equ ABT_Stack_Size,     0x00000000
+.equ RT_FIQ_STACK_PGSZ,  0x00000000
+.equ RT_IRQ_STACK_PGSZ,  0x00000800
+.equ USR_Stack_Size,     0x00000400
+
+#define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
+                 RT_FIQ_STACK_PGSZ + RT_IRQ_STACK_PGSZ)
+
+.section .data.share.isr
+/* stack */
+
+#ifdef RT_USING_SMP
+.globl stack_start0
+.globl stack_top0
+.globl stack_start1
+.globl stack_top1
+.globl stack_start2
+.globl stack_top2
+.globl stack_start3
+.globl stack_top3
+stack_start0:
+.rept ISR_Stack_Size
+.byte 0
+.endr
+stack_top0:
+
+stack_start1:
+.rept ISR_Stack_Size
+.byte 0
+.endr
+stack_top1:
+
+stack_start2:
+.rept ISR_Stack_Size
+.byte 0
+.endr
+stack_top2:
+
+stack_start3:
+.rept ISR_Stack_Size
+.byte 0
+.endr
+stack_top3:
+
+.globl boot_indicate
+boot_indicate:
+.rept 16
+.byte 0
+.endr
+
+#else
+.globl stack_start
+.globl stack_top
+stack_start:
+.rept ISR_Stack_Size
+.byte 0
+.endr
+stack_top:
+#endif
+
+
+.text
+/* reset entry */
+.globl _reset
+_reset:
+
+    /* Disable IRQ & FIQ */
+    cpsid if
+
+    /* Check for HYP mode */
+    mrs r0, cpsr_all
+    and r0, r0, #0x1F
+    mov r8, #0x1A
+    cmp r0, r8
+    beq overHyped
+    b continue
+
+overHyped: /* Get out of HYP mode */
+    ldr r1, =continue
+    msr ELR_hyp, r1
+    mrs r1, cpsr_all
+    and r1, r1, #0x1f    ;@ CPSR_MODE_MASK
+    orr r1, r1, #0x13    ;@ CPSR_MODE_SUPERVISOR
+    msr SPSR_hyp, r1
+    eret
+
+continue:
+
+    /* disable mmu */
+    bl      rt_cpu_mmu_disable
+    /* set the cpu to SVC32 mode and disable interrupt */
+    mrs     r0, cpsr
+    bic     r0, r0, #0x1f
+    orr     r0, r0, #0x13
+    msr     cpsr_c, r0
+#ifdef RT_USING_SMP
+    mrc     p15, 0, r0, c0, c0, 5
+    ubfx    r0, r0, #0, #2
+    cmp     r0, #0
+    beq     1f
+    /* write boot indicate */
+    ldr     r5, = boot_indicate
+    str     r0, [r5, r0, lsl #2]
+    bl secondary_cpu_start
+    b .
+1:
+#endif
+    /* setup stack */
+#ifdef RT_USING_SMP
+    ldr     r0, =stack_top0
+#else
+    ldr     r0, =stack_top
+#endif
+    bl      stack_setup
+      
+    /* 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                  */
+    bl rt_hw_init_mmu_table
+    bl init_mbox_mmu_map
+    bl rt_hw_mmu_init
+
+    /* start RT-Thread Kernel */
+    ldr     pc, _rtthread_startup
+_rtthread_startup:
+    .word rtthread_startup
+
+stack_setup:
+
+    @  Set the startup stack for svc
+    mov     sp, 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, #RT_FIQ_STACK_PGSZ
+
+    @  Enter IRQ Mode and set its Stack Pointer
+    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
+    mov     sp, r0
+    sub     r0, r0, #RT_IRQ_STACK_PGSZ
+
+    /* come back to SVC mode */
+    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
+    bx      lr
+
+.text
+
+/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq          */
+.section .text.isr, "ax"
+    .align  5
+.globl vector_fiq
+vector_fiq:
+    stmfd   sp!,{r0-r7,lr}
+    bl      rt_hw_trap_fiq
+    ldmfd   sp!,{r0-r7,lr}
+    subs    pc, lr, #4
+
+.globl      rt_interrupt_enter
+.globl      rt_interrupt_leave
+.globl      rt_thread_switch_interrupt_flag
+.globl      rt_interrupt_from_thread
+.globl      rt_interrupt_to_thread
+
+.globl      rt_current_thread
+.globl      vmm_thread
+.globl      vmm_virq_check
+
+    .align  5
+.globl vector_irq
+vector_irq:
+#ifdef RT_USING_SMP
+    clrex
+      
+    stmfd   sp!, {r0, r1}
+    cps     #Mode_SVC
+    mov     r0, sp          /* svc_sp */
+    mov     r1, lr          /* svc_lr */
+
+    cps     #Mode_IRQ
+    sub     lr, lr, #4
+    stmfd   r0!, {r1, lr}       /* svc_lr, svc_pc */
+    stmfd   r0!, {r2 - r12}
+    ldmfd   sp!, {r1, r2}     /* original r0, r1 */
+    stmfd   r0!, {r1 - r2}
+    mrs     r1,  spsr         /* original mode */
+    stmfd   r0!, {r1}
+
+#ifdef RT_USING_LWP
+    stmfd   r0, {r13, r14}^ /* usr_sp, usr_lr */
+    sub   r0, #8
+#endif
+#ifdef RT_USING_FPU
+    /* fpu context */
+    vmrs r6, fpexc
+    tst  r6, #(1<<30)
+    beq 1f
+    vstmdb r0!, {d0-d15}
+    vstmdb r0!, {d16-d31}
+    vmrs r5, fpscr
+    stmfd r0!, {r5}
+1:
+    stmfd r0!, {r6}
+#endif
+    mov     r8, r0
+
+    bl      rt_interrupt_enter
+    bl      rt_hw_trap_irq
+    bl      rt_interrupt_leave
+    
+    cps     #Mode_SVC
+    mov     sp, r8
+    mov     r0, r8
+    
+    bl      rt_scheduler_do_irq_switch
+
+    b       rt_hw_context_switch_exit
+
+#else
+    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
+    @ rt_hw_context_switch_interrupt_do and don't return
+    ldr     r0, =rt_thread_switch_interrupt_flag
+    ldr     r1, [r0]
+    cmp     r1, #1
+    beq     rt_hw_context_switch_interrupt_do
+
+    ldmfd   sp!, {r0-r12,lr}
+    subs    pc,  lr, #4
+
+rt_hw_context_switch_interrupt_do:
+    mov     r1,  #0         @ clear flag
+    str     r1,  [r0]
+
+    mov     r1, sp          @ r1 point to {r0-r3} in stack
+    add     sp, sp, #4*4
+    ldmfd   sp!, {r4-r12,lr}@ reload saved registers
+    mrs     r0,  spsr       @ get cpsr of interrupt thread
+    sub     r2,  lr, #4     @ save old task's pc to r2
+
+    @ Switch to SVC mode with no interrupt. If the usr mode guest is
+    @ interrupted, this will just switch to the stack of kernel space.
+    @ save the registers in kernel space won't trigger data abort.
+    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
+
+    stmfd   sp!, {r2}       @ push old task's pc
+    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
+    ldmfd   r1,  {r1-r4}    @ restore r0-r3 of the interrupt thread
+    stmfd   sp!, {r1-r4}    @ push old task's r0-r3
+    stmfd   sp!, {r0}       @ push old task's cpsr
+
+#ifdef RT_USING_LWP
+    stmfd sp, {r13, r14}^  @push usr_sp, usr_lr
+    sub sp, #8
+#endif
+#ifdef RT_USING_FPU
+    /* fpu context */
+    vmrs r6, fpexc
+    tst  r6, #(1<<30)
+    beq 1f
+    vstmdb sp!, {d0-d15}
+    vstmdb sp!, {d16-d31}
+    vmrs r5, fpscr
+    stmfd sp!, {r5}
+1:
+    stmfd sp!, {r6}
+#endif
+
+    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
+
+#ifdef RT_USING_FPU
+/* fpu context */
+    ldmfd sp!, {r6}
+    vmsr fpexc, r6
+    tst  r6, #(1<<30)
+    beq 1f
+    ldmfd sp!, {r5}
+    vmsr fpscr, r5
+    vldmia sp!, {d16-d31}
+    vldmia sp!, {d0-d15}
+1:
+#endif
+
+#ifdef RT_USING_LWP
+    ldmfd sp, {r13, r14}^  @pop usr_sp, usr_lr
+    add sp, #8
+#endif
+
+    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
+    msr     spsr_cxsf, r4
+
+    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
+
+#endif
+
+.macro push_svc_reg
+    sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
+    stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
+    mov     r0, sp
+    mrs     r6, spsr                @/* Save CPSR                       */
+    str     lr, [r0, #15*4]         @/* Push PC                         */
+    str     r6, [r0, #16*4]         @/* Push CPSR                       */
+    cps     #Mode_SVC
+    str     sp, [r0, #13*4]         @/* Save calling SP                 */
+    str     lr, [r0, #14*4]         @/* Save calling PC                 */
+.endm
+
+    .align  5
+    .globl  vector_swi
+vector_swi:
+    push_svc_reg
+    bl      rt_hw_trap_swi
+    b       .
+
+    .align  5
+    .globl  vector_undef
+vector_undef:
+    push_svc_reg
+    cps #Mode_UND
+    bl      rt_hw_trap_undef
+#ifdef RT_USING_FPU
+    ldr     lr, [sp, #15*4]
+    ldmia   sp, {r0 - r12}
+    add     sp, sp, #17 * 4
+    movs    pc, lr
+#endif
+    b       .
+
+    .align  5
+    .globl  vector_pabt
+vector_pabt:
+    push_svc_reg
+    bl      rt_hw_trap_pabt
+    b       .
+
+    .align  5
+    .globl  vector_dabt
+vector_dabt:
+    push_svc_reg
+    bl      rt_hw_trap_dabt
+    b       .
+
+    .align  5
+    .globl  vector_resv
+vector_resv:
+    push_svc_reg
+    bl      rt_hw_trap_resv
+    b       .
+
+#ifdef RT_USING_SMP
+
+.global secondary_cpu_start
+secondary_cpu_start:
+    /* set vector base */
+    mrc p15, 0, r0, c1, c0, 0        
+    bic r0, #(1<<13)
+    mcr p15, 0, r0, c1, c0, 0
+    
+    /* setup stack */
+    mrc p15, 0, r0, c0, c0, 5
+    ubfx    r0, r0, #0, #2
+    ldr r1, =stack_top0
+    ldr r2, =ISR_Stack_Size
+    mul r3, r2, r0
+    add r0, r1, r3
+    bl  stack_setup
+    /* initialize the mmu table and enable mmu */
+    bl  rt_hw_mmu_init
+    b   secondary_cpu_c_start
+
+#endif
+
+;@ void arm_smp_enable(void);
+.globl arm_smp_enable
+arm_smp_enable:
+    mrc p15, 0, r0, c1, c0, 1   ;@ set SMP bit in ACTLR
+    orr r0, r0, #0x40
+    mcr p15, 0, r0, c1, c0, 1
+    bx lr
+/*
+    mrrc p15, 1, r0, r1, c15
+    orr r0, r0, #0x40
+    mcrr p15, 1, r0, r1, c15
+    dsb
+    isb
+    bx lr
+*/
+.text
+;@ void arm_smp_disable(void);
+.globl arm_smp_disable
+
+arm_smp_disable:
+    mrc p15, 0, r0, c1, c0, 1   ;@ clear SMP bit in ACTLR
+    bic r0, r0, #0x40
+    mcr p15, 0, r0, c1, c0, 1
+    bx lr
+/*
+    mrrc p15, 1, r0, r1, c15
+    bic r0, r0, #0x40
+    mcrr p15, 1, r0, r1, c15
+    bx lr
+*/
+

+ 219 - 0
bsp/raspberry-pi/raspi3-32/cpu/trap.c

@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-20     Bernard      first version
+ * 2019-07-28     zdzn         add smp support
+ * 2019-08-09     zhangjun     fixup the problem of smp startup and scheduling issues, 
+ *                             write addr to mailbox3 to startup smp, and we use mailbox0 for ipi
+ */
+
+#include <rthw.h>
+#include <board.h>
+#include <rtthread.h>
+
+#include "armv7.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
+ */
+void rt_hw_show_register(struct rt_hw_exp_stack *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);
+}
+
+
+/**
+ * When 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_undef(struct rt_hw_exp_stack *regs)
+{
+    rt_kprintf("undefined instruction:\n");
+    rt_hw_show_register(regs);
+#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_exp_stack *regs)
+{
+    rt_kprintf("software interrupt:\n");
+    rt_hw_show_register(regs);
+#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 an instruction prefetch.
+ *
+ * @param regs system registers
+ *
+ * @note never invoke this function in application
+ */
+void rt_hw_trap_pabt(struct rt_hw_exp_stack *regs)
+{
+    rt_kprintf("prefetch abort:\n");
+    rt_hw_show_register(regs);
+#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_exp_stack *regs)
+{
+    rt_kprintf("data abort:");
+    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_exp_stack *regs)
+{
+    rt_kprintf("reserved trap:\n");
+    rt_hw_show_register(regs);
+#ifdef RT_USING_FINSH
+    list_thread();
+#endif
+    rt_hw_cpu_shutdown();
+}
+
+void rt_hw_trap_irq(void)
+{
+    void *param;
+    uint32_t irq;
+    rt_isr_handler_t isr_func;
+    extern struct rt_irq_desc isr_table[];
+    uint32_t value = 0;
+    value = IRQ_PEND_BASIC & 0x3ff;
+#ifdef RT_USING_SMP
+    uint32_t mailbox_data;
+    uint32_t cpu_id = rt_hw_cpu_id();
+    uint32_t int_source = CORE_IRQSOURCE(cpu_id);
+    mailbox_data = IPI_MAILBOX_CLEAR(cpu_id);
+    if (int_source & 0x0f)
+    {
+        if (int_source & 0x08)
+        {
+            isr_func = isr_table[IRQ_ARM_TIMER].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+            isr_table[IRQ_ARM_TIMER].counter++;
+#endif
+            if (isr_func)
+            {
+                param = isr_table[IRQ_ARM_TIMER].param;
+                isr_func(IRQ_ARM_TIMER, param);
+            }
+        }
+    }
+    if (int_source & 0xf0)
+    {
+        /*it's a ipi interrupt*/
+        if (mailbox_data & 0x1)
+        {
+            /* clear mailbox */
+            IPI_MAILBOX_CLEAR(cpu_id) = mailbox_data;    
+            isr_func = isr_table[IRQ_ARM_MAILBOX].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+            isr_table[IRQ_ARM_MAILBOX].counter++;
+#endif
+            if (isr_func)
+            {
+                param = isr_table[IRQ_ARM_MAILBOX].param;
+                isr_func(IRQ_ARM_MAILBOX, param);
+            }
+        }
+        else 
+            CORE_MAILBOX3_CLEAR(cpu_id) = mailbox_data;
+    }
+#endif
+    /* local interrupt*/
+    if (value)
+    {
+        if (value & (1 << 8))
+        {
+            value = IRQ_PEND1;
+            irq = __rt_ffs(value) - 1;
+        }
+        else if (value & (1 << 9))
+        {
+            value = IRQ_PEND2;
+            irq = __rt_ffs(value) + 31;
+        }
+        else
+        {
+            value &= 0x0f;
+            irq = __rt_ffs(value) + 63;
+        }
+
+        /* get interrupt service routine */
+        isr_func = isr_table[irq].handler;
+#ifdef RT_USING_INTERRUPT_INFO
+        isr_table[irq].counter++;
+#endif
+        if (isr_func)
+        {
+            /* Interrupt for myself. */
+            param = isr_table[irq].param;
+            /* turn to interrupt service routine */
+            isr_func(irq, param);
+        }
+    }
+}
+
+void rt_hw_trap_fiq(void)
+{
+
+}

+ 51 - 0
bsp/raspberry-pi/raspi3-32/cpu/vector_gcc.S

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2013-07-05     Bernard      the first version
+ */
+
+.section .vectors, "ax"
+.code 32
+
+.globl system_vectors
+system_vectors:
+    ldr pc, _vector_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
+
+.globl _reset
+.globl vector_undef
+.globl vector_swi
+.globl vector_pabt
+.globl vector_dabt
+.globl vector_resv
+.globl vector_irq
+.globl vector_fiq
+
+_vector_reset:
+    .word _reset
+_vector_undef:
+    .word vector_undef
+_vector_swi:
+    .word vector_swi
+_vector_pabt:
+    .word vector_pabt
+_vector_dabt:
+    .word vector_dabt
+_vector_resv:
+    .word vector_resv
+_vector_irq:
+    .word vector_irq
+_vector_fiq:
+    .word vector_fiq
+
+.balignl    16,0xdeadbeef

+ 103 - 0
bsp/raspberry-pi/raspi3-32/driver/Kconfig

@@ -0,0 +1,103 @@
+menu "Hardware Drivers Config"
+    menu "BCM Peripheral Drivers"
+        menuconfig BSP_USING_UART
+            bool "Using UART"
+            select RT_USING_SERIAL
+            default y
+
+            if BSP_USING_UART
+                config RT_USING_UART0
+                bool "Enabel UART 0"
+                default y
+
+                config RT_USING_UART1
+                    bool "Enabel UART 1"
+                    default n
+            endif
+         
+        config BSP_USING_PIN
+            bool "Using PIN"
+            select RT_USING_PIN
+            default y
+
+        menuconfig BSP_USING_SYSTIMER
+            bool "Enable SYSTIMER"
+            select RT_USING_HWTIMER
+            default n
+
+        if  BSP_USING_SYSTIMER
+            config RT_USING_SYSTIMER1
+                bool "Enable sys timer1"
+                default n
+            config RT_USING_SYSTIMER3
+                bool "Enable sys timer3"
+                default n
+        endif
+
+        menuconfig BSP_USING_I2C
+            bool "Enable I2C"
+            select RT_USING_I2C
+            default n
+
+        if BSP_USING_I2C
+            config BSP_USING_I2C0
+                bool "Enable I2C0"
+                default n
+            config BSP_USING_I2C1
+                bool "Enable I2C1"
+                default n
+        endif
+
+        menuconfig BSP_USING_SPI
+            bool "Enable SPI"
+            select RT_USING_SPI
+            default n
+        
+        if BSP_USING_SPI   
+            config BSP_USING_SPI0_BUS
+                bool "Enable SPI0 BUS"
+                default n
+            config BSP_USING_SPI0_DEVICE0
+                bool "Enable SPI0 DEVICE0"
+                select BSP_USING_SPI0_BUS
+                default n
+            config BSP_USING_SPI0_DEVICE1
+                bool "Enable SPI0 DEVICE1"
+                select BSP_USING_SPI0_BUS
+                default n
+        endif
+
+        config BSP_USING_WDT
+            bool "Enable WDT"
+            select RT_USING_WDT
+            default n
+
+        menuconfig BSP_USING_RTC
+            bool "Enable RTC"
+            select RT_USING_RTC
+            default n
+
+        if BSP_USING_RTC
+            config BSP_USING_ALARM
+                bool "Enable Alarm"
+                select RT_USING_ALARM
+                default n
+        endif
+        
+        menuconfig BSP_USING_SDIO
+            bool "Enable SDIO"
+            select RT_USING_SDIO
+            default n
+
+        if BSP_USING_SDIO
+            config BSP_USING_SDIO0
+                bool "Enable SDIO0"
+                select RT_USING_SDIO
+                default n
+        endif
+        menuconfig BSP_USING_HDMI
+            bool "Enable HDMI"
+            select BSP_USING_SPI
+            default n
+    endmenu
+endmenu

+ 31 - 0
bsp/raspberry-pi/raspi3-32/driver/SConscript

@@ -0,0 +1,31 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Split('''
+board.c
+drv_uart.c
+mbox.c
+''')
+CPPPATH = [cwd]
+
+if GetDepend('BSP_USING_SYSTIMER'):
+    src += ['drv_timer.c']
+if GetDepend('BSP_USING_PIN'):
+    src += ['drv_gpio.c']
+if GetDepend('BSP_USING_I2C'):
+    src += ['drv_i2c.c']
+if GetDepend('BSP_USING_WDT'):
+    src += ['drv_wdt.c']
+if GetDepend('BSP_USING_SPI'):
+    src += ['drv_spi.c']
+if GetDepend('BSP_USING_SDIO'):
+    src += ['drv_sdio.c']
+if GetDepend('BSP_USING_RTC'):
+    src += ['drv_rtc.c']
+if GetDepend('BSP_USING_HDMI'):
+    src += ['drv_fb.c']
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 182 - 0
bsp/raspberry-pi/raspi3-32/driver/board.c

@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "drv_uart.h"
+#include "drv_timer.h"
+
+#include "cp15.h"
+
+#ifdef RT_USING_SMP
+unsigned int cntfrq;
+#endif
+
+void rt_hw_timer_isr(int vector, void *parameter)
+{
+    rt_tick_increase();
+#ifndef RT_USING_SMP
+    ARM_TIMER_IRQCLR = 0;
+#else
+    mask_cntv();
+    __DSB();
+    write_cntv_tval(cntfrq);
+    __DSB();
+    unmask_cntv();
+    __DSB();
+#endif
+}
+
+int rt_hw_timer_init()
+{
+#ifndef RT_USING_SMP
+    /* timer_clock = apb_clock/(pre_divider + 1) */
+    ARM_TIMER_PREDIV = (250 - 1);
+
+    ARM_TIMER_RELOAD = 0;
+    ARM_TIMER_LOAD   = 0;
+    ARM_TIMER_IRQCLR = 0;
+    ARM_TIMER_CTRL   = 0;
+
+    ARM_TIMER_RELOAD = 10000;
+    ARM_TIMER_LOAD   = 10000;
+
+    /* 23-bit counter, enable interrupt, enable timer */
+    ARM_TIMER_CTRL   = (1 << 1) | (1 << 5) | (1 << 7);
+#else
+    __DSB();
+    cntfrq = 35000;
+    write_cntv_tval(cntfrq);
+    enable_cntv();
+    __DSB();
+    enable_cpu_timer_intr(rt_hw_cpu_id());
+#endif
+
+    rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick");
+    rt_hw_interrupt_umask(IRQ_ARM_TIMER);
+    return 0;
+}
+#ifdef RT_USING_SMP
+extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
+
+void ipi_handler()
+{
+    rt_scheduler_ipi_handler(0,RT_NULL);
+}
+#endif
+void vector_copy(void)
+{
+    rt_memcpy((void*)0x0, (void*)0x8000, 64);
+}
+
+void idle_wfi(void)
+{
+    asm volatile ("wfi");
+}
+
+void rt_hw_board_init(void)
+{
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init();
+    vector_copy();
+    rt_hw_vector_init();
+    /* initialize uart */
+    rt_hw_uart_init();
+    /* initialize timer for os tick */
+    rt_hw_timer_init();
+    rt_thread_idle_sethook(idle_wfi);
+#ifdef RT_USING_CONSOLE
+    /* set console device */
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif /* RT_USING_CONSOLE */
+#ifdef RT_USING_HEAP
+    /* initialize memory system */
+    rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+    rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+#endif
+
+#ifdef RT_USING_SMP
+    /* install IPI handle */
+    rt_hw_ipi_handler_install(IRQ_ARM_MAILBOX, ipi_handler);
+    rt_hw_interrupt_umask(IRQ_ARM_MAILBOX);
+    enable_cpu_ipi_intr(0);
+#endif
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+
+}
+
+
+void _reset(void);
+void secondary_cpu_start(void);
+
+#ifdef RT_USING_SMP
+void rt_hw_secondary_cpu_up(void)
+{
+    int i;
+    int retry,val;
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
+    /*TODO maybe, there is some bug */
+    for (i = RT_CPUS_NR - 1; i>0; i-- )
+    {
+        rt_kprintf("boot cpu:%d\n", i);
+        setup_bootstrap_addr(i, (int)_reset);
+        __SEV();
+        __DSB();
+        __ISB();
+        retry = 10;
+        rt_thread_delay(RT_TICK_PER_SECOND/1000);
+        do
+        {
+            val = CORE_MAILBOX3_CLEAR(i);
+            if (val == 0)
+            {
+                rt_kprintf("start OK: CPU %d \n",i);
+                break;
+            }
+            rt_thread_delay(RT_TICK_PER_SECOND);
+
+            retry --;
+            if (retry <= 0)
+            {
+                rt_kprintf("can't start for CPU %d \n",i);
+                break;
+            }
+        } while (1);
+    }
+    __DSB();
+    __SEV();
+}
+
+void secondary_cpu_c_start(void)
+{
+    uint32_t id;
+    id = rt_hw_cpu_id();
+    rt_kprintf("cpu = 0x%08x\n",id);
+    rt_hw_timer_init();
+    rt_kprintf("cpu %d startup.\n",id);
+    rt_hw_vector_init();
+    enable_cpu_ipi_intr(id);
+    rt_hw_spin_lock(&_cpus_lock);
+    rt_system_scheduler_start();
+}
+
+void rt_hw_secondary_cpu_idle_exec(void)
+{
+    __WFE();
+}
+
+#endif
+
+

+ 29 - 0
bsp/raspberry-pi/raspi3-32/driver/board.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#ifndef BOARD_H__
+#define BOARD_H__
+
+#include <stdint.h>
+
+#include <rthw.h>
+#include  "raspi.h"
+
+#define __REG32 HWREG32
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define RT_HW_HEAP_BEGIN    (void*)&__bss_end
+#define RT_HW_HEAP_END      (void*)(RT_HW_HEAP_BEGIN + 4 * 1024 * 1024)
+
+void rt_hw_board_init(void);
+
+#endif
+

+ 508 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_fb.c

@@ -0,0 +1,508 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "mbox.h"
+#include "drv_fb.h"
+#include "mmu.h"
+
+#define CHAR_W          8
+#define CHAR_H          12
+
+#define COLOR_DELTA     0.05
+static struct rt_hdmi_fb_device _hdmi;
+
+// https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c
+unsigned char FONT[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'!'*/
+0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'"'*/
+0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00, 0x00, 0x00, /*'#'*/
+0x00, 0x00, 0x08, 0x3c, 0x0a, 0x1c, 0x28, 0x1e, 0x08, 0x00, 0x00, 0x00, /*'$'*/
+0x00, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 0x00, 0x00, /*'%'*/
+0x00, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x2a, 0x12, 0x2c, 0x00, 0x00, 0x00, /*'&'*/
+0x00, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'''*/
+0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, /*'('*/
+0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, /*')'*/
+0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, /*'*'*/
+0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*'+'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*','*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'-'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*'.'*/
+0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /*'/'*/
+0x00, 0x1c, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'0'*/
+0x00, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'1'*/
+0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'2'*/
+0x00, 0x1c, 0x22, 0x20, 0x18, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'3'*/
+0x00, 0x10, 0x18, 0x18, 0x14, 0x14, 0x3e, 0x10, 0x38, 0x00, 0x00, 0x00, /*'4'*/
+0x00, 0x3e, 0x02, 0x02, 0x1e, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'5'*/
+0x00, 0x18, 0x04, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'6'*/
+0x00, 0x3e, 0x22, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, /*'7'*/
+0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'8'*/
+0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, /*'9'*/
+0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*':'*/
+0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*';'*/
+0x00, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, /*'<'*/
+0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, /*'='*/
+0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, /*'>'*/
+0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'?'*/
+0x00, 0x00, 0x1c, 0x22, 0x3a, 0x3a, 0x1a, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'@'*/
+0x00, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, /*'A'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'B'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'C'*/
+0x00, 0x00, 0x0e, 0x12, 0x22, 0x22, 0x22, 0x12, 0x0e, 0x00, 0x00, 0x00, /*'D'*/
+0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'E'*/
+0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'F'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'G'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'H'*/
+0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, /*'I'*/
+0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'J'*/
+0x00, 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'K'*/
+0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'L'*/
+0x00, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'M'*/
+0x00, 0x00, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x00, 0x00, 0x00, /*'N'*/
+0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'O'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'P'*/
+0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x30, 0x00, 0x00, /*'Q'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'R'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'S'*/
+0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'T'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'U'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'V'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00, 0x00, /*'W'*/
+0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, /*'X'*/
+0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'Y'*/
+0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'Z'*/
+0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, /*'['*/
+0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, /*'\'*/
+0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, /*']'*/
+0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'^'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, /*'_'*/
+0x00, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'`'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'a'*/
+0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'b'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, /*'c'*/
+0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'d'*/
+0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'e'*/
+0x00, 0x38, 0x04, 0x04, 0x1e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, /*'f'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'g'*/
+0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'h'*/
+0x00, 0x08, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'i'*/
+0x00, 0x10, 0x10, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, /*'j'*/
+0x00, 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x00, 0x00, 0x00, /*'k'*/
+0x00, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'l'*/
+0x00, 0x00, 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x22, 0x00, 0x00, 0x00, /*'m'*/
+0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'n'*/
+0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'o'*/
+0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, /*'p'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, /*'q'*/
+0x00, 0x00, 0x00, 0x00, 0x1a, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'r'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x1c, 0x20, 0x1e, 0x00, 0x00, 0x00, /*'s'*/
+0x00, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, /*'t'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'u'*/
+0x00, 0x00, 0x00, 0x00, 0x36, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'v'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00, /*'w'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, /*'x'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'y'*/
+0x00, 0x00, 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, 0x00, 0x00, /*'z'*/
+0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, /*'{'*/
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /*'|'*/
+0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, /*'}'*/
+0x00, 0x04, 0x2a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'~'*/
+0x00, 0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x00, 0x00, 0x00, /*DEL*/
+};
+
+void newline(fb_t* fb)
+{
+    uint8_t* to;
+    uint8_t* from;
+    int i;
+    fb->y++;
+    fb->x = 0;
+
+    if (fb->y == (fb->height / CHAR_H))
+    {
+
+        to = (uint8_t*) fb->addr;
+        from = to + (CHAR_H * fb->pitch);
+
+        for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++)
+        {
+            *to++ = *from++;
+        }
+
+        uint32_t *addr = (uint32_t*) (fb->addr) + (fb->height - CHAR_H) * fb->width;
+
+        for (i = 0; i < (CHAR_H * fb->width); i++)
+        {
+            *addr++ = fb->back;
+        }
+
+        fb->y--;
+    }
+}
+
+void clear_line(fb_t *fb, const int line)
+{
+    int i;
+    uint32_t* addr;
+    if (line > fb->height / CHAR_H)
+    {
+        fb->y = 0;
+    }
+    else
+    {
+        fb->y = line;
+    }
+
+    fb->x = 0;
+
+    addr = (uint32_t*) (fb->addr + (line * CHAR_H * fb->depth * fb->width));
+    for (i = 0; i < (CHAR_H * fb->width); i++)
+    {
+        *addr++ = fb->back;
+    }
+
+}
+
+void clear(fb_t *fb, const uint32_t color)
+{
+
+    uint32_t *addr = (uint32_t*) fb->addr;
+    uint32_t i;
+    for (i = 0; i < (fb->height * fb->width); i++)
+    {
+        *addr++ = color;
+    }
+    fb->x = 0;
+    fb->y = 0;
+
+}
+
+void fb_draw_char(fb_t *fb, char s)
+{
+    unsigned char* addr = (unsigned char*) fb->addr;
+    unsigned char *glyph = (unsigned char*) FONT + (s) * 12;
+    // calculate the offset on screen
+    int offs = (fb->y * CHAR_H * fb->pitch) + (fb->x * (CHAR_W + 1) * 4);
+    // variables
+    int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8;
+    // display a character
+    for (j = 0; j < CHAR_H; j++)
+    {
+        // display one row
+        line = offs;
+        mask = 1;
+        for (i = 0; i < CHAR_W; i++)
+        {
+            // if bit set, we use white color, otherwise black
+            *((unsigned int*) (addr + line)) = ((int) *glyph) & mask ? fb->fore : fb->back;
+            mask <<= 1;
+            line += 4;
+        }
+        // adjust to next line
+        glyph += bytesperline;
+        offs += fb->pitch;
+    }
+}
+
+void fb_print(fb_t *fb, char *s)
+{
+
+    // draw next character if it's not zero
+    while (*s)
+    {
+        // handle carrige return
+        if (*s == '\r')
+        {
+            fb->x = 0;
+        }
+        else if (*s == '\n')
+        {
+            newline(fb);
+        }
+        else if (*s == '\t')
+        {
+            fb->x = ((fb->x + 4) >> 2) << 2;
+        }
+        else if (*s == '\b')
+        {
+            if (fb->x)
+            {
+                fb->x--;
+                fb_draw_char(fb, ' ');
+            }
+        }
+        else
+        {
+            fb_draw_char(fb, *s);
+            fb->x++;
+        }
+        // next character
+        if (fb->x == fb->width / CHAR_W)
+        {
+            newline(fb);
+        }
+        s++;
+    }
+}
+
+rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+rt_err_t hdmi_fb_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
+{
+    return 0;
+}
+
+rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    fb_print(&_hdmi.fb, (char *) buffer);
+#ifdef BSP_USING_HDMI_DISPLAY
+    rt_device_t uart = rt_device_find("uart1");
+    int old_flag = uart->open_flag;
+    uart->open_flag |= RT_DEVICE_FLAG_STREAM;
+    rt_device_write(uart, 0, buffer, size);
+    uart->open_flag = old_flag;
+#endif
+    return size;
+}
+
+rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
+{
+    return RT_EOK;
+}
+
+const static struct rt_device_ops hdmi_fb_ops = 
+{
+    RT_NULL,
+    hdmi_fb_open,
+    hdmi_fb_close,
+    hdmi_fb_read,
+    hdmi_fb_write,
+    hdmi_fb_control
+};
+
+static struct rt_device_graphic_info _hdmi_info;
+
+static void hdmi_draw_rect(const char* pixel, int x1, int y1, int x2, int y2)
+{
+    int i, j;
+    int line;
+    for (j = y1; j <= y2; j++)
+    {
+        line = (j * _hdmi.fb.pitch) + (x1 * 4);
+        for (i = x1; i <= x2; i++)
+        {
+            // if bit set, we use white color, otherwise black
+            *((unsigned int*) (_hdmi_info.framebuffer + line)) = *(unsigned int*) pixel;
+            line += 4;
+        }
+    }
+
+}
+
+static void hdmi_set_pixel(const char* pixel, int x, int y)
+{
+    *(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) = *(uint32_t *) pixel;
+}
+
+static void hdmi_get_pixel(char* pixel, int x, int y)
+{
+    uint32_t ret = 0;
+    ret = (*(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) & 0x00FFFFFF);
+    *pixel = ret;
+}
+
+static void hdmi_draw_hline(const char* pixel, int x1, int x2, int y)
+{
+    hdmi_draw_rect(pixel, x1, y, x2, y);
+}
+
+static void hdmi_draw_vline(const char* pixel, int x, int y1, int y2)
+{
+    hdmi_draw_rect(pixel, x, y1, x, y2);
+}
+
+static void hdmi_blit_line(const char* pixels, int x, int y, rt_size_t size)
+{
+    int i = 0;
+    uint32_t *pixel_base = (uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4));
+    uint32_t *colors = (uint32_t *) pixels;
+    for (i = 0; i < size; i++)
+    {
+        pixel_base[i] = colors[i];
+    }
+}
+
+static struct rt_device_graphic_ops hdmi_ops = 
+{
+    hdmi_set_pixel,
+    hdmi_get_pixel,
+    hdmi_draw_hline,
+    hdmi_draw_vline,
+    hdmi_blit_line
+};
+
+rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
+{
+    struct rt_device *device;
+    RT_ASSERT(hdmi_fb != RT_NULL);
+
+    device = &hdmi_fb->parent;
+    device->user_data = &hdmi_ops;
+
+    /* set device type */
+    device->type = RT_Device_Class_Graphic;
+    /* initialize device interface */
+#ifdef RT_USING_DEVICE_OPS
+    device->ops = &hdmi_fb_ops;
+#else
+    device->init = RT_NULL;
+    device->open = hdmi_fb_open;
+    device->close = hdmi_fb_close;
+    device->read = hdmi_fb_read;
+    device->write = hdmi_fb_write;
+    device->control = hdmi_fb_control;
+#endif
+
+    /* register to device manager */
+    rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
+
+    return RT_EOK;
+}
+
+/**
+ * Show a picture
+ */
+void print_fb_info()
+{
+    rt_kprintf("FrameBuffer Info: \n \t width %x\t height %x\t depth %x\t addr %x\t size %x\t \n", fb_info.width,
+            fb_info.height, fb_info.depth, fb_info.addr, fb_info.size);
+    rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]);
+}
+
+void hdmi_fb_init()
+{
+    unsigned int *mbox = (unsigned int*) MBOX_ADDR;
+    mbox[0] = 35 * 4;
+    mbox[1] = MBOX_REQUEST;
+
+    mbox[2] = 0x48003;  //set phy wh
+    mbox[3] = 8;
+    mbox[4] = 8;
+    mbox[5] = 640;         //FrameBufferInfo.width
+    mbox[6] = 480;          //FrameBufferInfo.height
+
+    mbox[7] = 0x48004;  //set virt wh
+    mbox[8] = 8;
+    mbox[9] = 8;
+    mbox[10] = 640;        //FrameBufferInfo.virtual_width
+    mbox[11] = 480;         //FrameBufferInfo.virtual_height
+
+    mbox[12] = 0x48009; //set virt offset
+    mbox[13] = 8;
+    mbox[14] = 8;
+    mbox[15] = 0;           //FrameBufferInfo.x_offset
+    mbox[16] = 0;           //FrameBufferInfo.y.offset
+
+    mbox[17] = 0x48005; //set depth
+    mbox[18] = 4;
+    mbox[19] = 4;
+    mbox[20] = 32;          //FrameBufferInfo.depth
+
+    mbox[21] = 0x48006; //set pixel order
+    mbox[22] = 4;
+    mbox[23] = 4;
+    mbox[24] = 1;           //RGB, not BGR preferably
+
+    mbox[25] = 0x40001; //get framebuffer, gets alignment on request
+    mbox[26] = 8;
+    mbox[27] = 8;
+    mbox[28] = 4096;        //FrameBufferInfo.pointer
+    mbox[29] = 0;           //FrameBufferInfo.size
+
+    mbox[30] = 0x40008; //get pitch
+    mbox[31] = 4;
+    mbox[32] = 4;
+    mbox[33] = 0;           //FrameBufferInfo.pitch
+
+    mbox[34] = MBOX_TAG_LAST;
+    if (mbox_call(MBOX_CH_PROP, MMU_DISABLE) && mbox[20] == 32 && mbox[28] != 0)
+    {
+        mbox[28] &= 0x3FFFFFFF;
+        _hdmi.fb.width = mbox[5];
+        _hdmi.fb.height = mbox[6];
+        _hdmi.fb.pitch = mbox[33];
+        //_hdmi.fb.addr = (void*)((unsigned long)mbox[28]);
+        _hdmi.fb.addr = (rt_uint32_t) mbox[28];
+        _hdmi.fb.size = mbox[29];
+        _hdmi.fb.depth = 32;
+        _hdmi.fb.x = 0;
+        _hdmi.fb.y = 0;
+        _hdmi.fb.fore = CONSOLE_WHITE;
+        _hdmi.fb.back = CONSOLE_BLACK;
+        rt_hdmi_fb_device_init(&_hdmi, "hdmi");
+        rt_hw_change_mmu_table(_hdmi.fb.addr, _hdmi.fb.size, _hdmi.fb.addr, DEVICE_MEM);
+        fb_info.width = _hdmi.fb.width;
+        fb_info.height = _hdmi.fb.height;
+        fb_info.addr = _hdmi.fb.addr;
+        fb_info.size = _hdmi.fb.size;
+        fb_info.pitch = _hdmi.fb.pitch;
+        fb_info.depth = _hdmi.fb.depth;
+        _hdmi_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
+        _hdmi_info.bits_per_pixel = _hdmi.fb.depth;
+        _hdmi_info.width = _hdmi.fb.width;
+        _hdmi_info.height = _hdmi.fb.height;
+        _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr;
+    }
+}
+
+INIT_DEVICE_EXPORT(hdmi_fb_init);

+ 60 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_fb.h

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+#ifndef __DRV_FB_H__
+#define __DRV_FB_H__
+
+#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
+
+#define COLOR_BLACK RGB(0, 0, 0)
+
+#define COLOR_GREEN RGB(0, 255, 0)  
+ 
+#define COLOR_CYAN RGB(0, 255, 255) 
+
+#define COLOR_RED RGB(255, 0, 0)  
+
+#define COLOR_YELLOW RGB(255, 255, 0) 
+
+#define COLOR_WHITE RGB(255, 255, 255)   
+
+#define CONSOLE_WHITE COLOR_WHITE
+#define CONSOLE_BLACK COLOR_BLACK
+#define CONSOLE_GREEN COLOR_GREEN
+#define CONSOLE_CYAN COLOR_CYAN
+#define CONSOLE_RED COLOR_RED
+#define CONSOLE_YELLOW COLOR_YELLOW
+
+typedef struct
+{
+    rt_uint32_t width;
+    rt_uint32_t height;
+    rt_uint32_t vwidth;
+    rt_uint32_t vheight;
+    rt_uint32_t pitch;
+    rt_uint32_t depth;
+    rt_uint32_t fore;
+    rt_uint32_t back;
+    rt_uint32_t x;
+    rt_uint32_t y;
+    rt_uint32_t addr;
+    rt_uint32_t size;
+} fb_t;
+
+struct rt_hdmi_fb_device
+{
+    struct rt_device parent;
+    fb_t fb;
+};
+
+fb_t fb_info;
+void print_fb_info();
+void hdmi_fb_init();
+
+#endif/* __DRV_FB_H__ */

+ 318 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_gpio.c

@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_gpio.h"
+
+#ifdef BSP_USING_PIN
+/*
+ * gpio_int[0] for BANK0 (pins 0-27)
+ * gpio_int[1] for BANK1 (pins 28-45)
+ * gpio_int[2] for BANK2 (pins 46-53)
+ */
+static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM];
+
+void gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud)
+{
+    rt_uint8_t num = pin / 32;
+    rt_uint8_t shift = pin % 32;
+    BCM283X_GPIO_GPPUD = pud;
+    DELAY_MICROS(10);
+    BCM283X_GPIO_GPPUDCLK(num) = 1 << shift;
+    DELAY_MICROS(10);
+    BCM283X_GPIO_GPPUD = BCM283X_GPIO_PUD_OFF;
+    BCM283X_GPIO_GPPUDCLK(num) = 0 << shift;
+}
+
+static void gpio_ack_irq(int irq, bcm_gpio_pin pin)
+{
+    rt_uint32_t data;
+    data = IRQ_PEND2;
+    data &= (0x0 << (irq - 32));
+    IRQ_PEND2 = data;
+
+    data = IRQ_DISABLE2;
+    data |= (0x1 << (irq - 32));
+    IRQ_DISABLE2 = data;
+}
+
+void gpio_irq_disable(rt_uint8_t index, bcm_gpio_pin pin)
+{
+    int irq = 0;
+    rt_uint32_t  reg_value;
+    rt_uint8_t irq_type;
+    irq = IRQ_GPIO0 + index;
+
+    gpio_ack_irq(irq, pin);
+
+    irq_type = _g_gpio_irq_tbl[index].irq_type[pin];
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t mask = 1 << shift;
+
+    switch (irq_type)
+    {
+    case PIN_IRQ_MODE_RISING:
+        reg_value = BCM283X_GPIO_GPREN(pin /32);
+        BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        break;
+    case PIN_IRQ_MODE_FALLING:
+        reg_value = BCM283X_GPIO_GPFEN(pin /32);
+        BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        break;
+    case PIN_IRQ_MODE_RISING_FALLING:
+        reg_value = BCM283X_GPIO_GPAREN(pin /32);
+        BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        reg_value = BCM283X_GPIO_GPAFEN(pin /32);
+        BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        break;
+    case PIN_IRQ_MODE_HIGH_LEVEL:
+        reg_value = BCM283X_GPIO_GPHEN(pin /32);
+        BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        break;
+    case PIN_IRQ_MODE_LOW_LEVEL:
+        reg_value = BCM283X_GPIO_GPLEN(pin /32);
+        BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
+        break;
+    }
+}
+
+void gpio_irq_enable(rt_uint8_t index, bcm_gpio_pin pin)
+{
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    offset = pin;
+    if (index == 0)
+        offset = IRQ_GPIO0 - 32;
+    else if (index == 1)
+        offset = IRQ_GPIO1 - 32;
+    else
+        offset = IRQ_GPIO2 - 32;
+
+    data = IRQ_ENABLE2;
+    data |= 0x1 << offset;
+    IRQ_ENABLE2 = data;
+
+}
+
+static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+    RT_ASSERT(!(mode & 0x8));
+
+    switch (mode)
+    {
+    case PIN_MODE_OUTPUT:
+        GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP);
+        break;
+    case PIN_MODE_INPUT:
+        GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case PIN_MODE_INPUT_PULLUP:
+        gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
+        GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case PIN_MODE_INPUT_PULLDOWN:
+        gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN);
+        GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case PIN_MODE_OUTPUT_OD:
+        gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF);
+        GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP);
+        break;
+    }
+}
+
+static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+    RT_ASSERT(!(value & 0xE));
+
+    if (value)
+        BCM283X_GPIO_GPSET(pin / 32) |= (1 << (pin %32));
+    else
+        BCM283X_GPIO_GPCLR(pin / 32) |= (0 << (pin %32));
+
+}
+
+static int raspi_pin_read(struct rt_device *device, rt_base_t pin)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+    return (BCM2835_GPIO_GPLEV(pin / 32) & (1 << (pin % 32)))? PIN_HIGH : PIN_LOW;
+}
+
+static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+
+    rt_uint8_t index;
+    rt_uint32_t  reg_value;
+    if (pin <= 27)
+        index = 0;
+    else if (pin <= 45)
+        index = 1;
+    else
+        index = 2;
+    _g_gpio_irq_tbl[index].irq_cb[pin]    = hdr;
+    _g_gpio_irq_tbl[index].irq_arg[pin]   = args;
+    _g_gpio_irq_tbl[index].irq_type[pin]  = mode;
+
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t mask = 1 << shift;
+
+    switch (mode)
+    {
+    case PIN_IRQ_MODE_RISING:
+        reg_value = BCM283X_GPIO_GPREN(pin /32);
+        BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        break;
+    case PIN_IRQ_MODE_FALLING:
+        reg_value = BCM283X_GPIO_GPFEN(pin /32);
+        BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        break;
+    case PIN_IRQ_MODE_RISING_FALLING:
+        reg_value = BCM283X_GPIO_GPAREN(pin /32);
+        BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        reg_value = BCM283X_GPIO_GPAFEN(pin /32);
+        BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        break;
+    case PIN_IRQ_MODE_HIGH_LEVEL:
+        reg_value = BCM283X_GPIO_GPHEN(pin /32);
+        BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        break;
+    case PIN_IRQ_MODE_LOW_LEVEL:
+        reg_value = BCM283X_GPIO_GPLEN(pin /32);
+        BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
+        break;
+    }
+    return RT_EOK;
+}
+
+static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+
+    rt_uint8_t index;
+    if (pin <= 27)
+        index = 0;
+    else if (pin <= 45)
+        index = 1;
+    else
+        index = 2;
+
+    gpio_irq_disable(index, pin);
+
+    _g_gpio_irq_tbl[index].irq_cb[pin]    = RT_NULL;
+    _g_gpio_irq_tbl[index].irq_arg[pin]   = RT_NULL;
+    _g_gpio_irq_tbl[index].irq_type[pin]  = RT_NULL;
+
+    return RT_EOK;
+}
+
+rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
+{
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
+
+    rt_uint8_t index;
+    if (pin <= 27)
+        index = 0;
+    else if (pin <= 45)
+        index = 1;
+    else
+        index = 2;
+
+    if (enabled)
+        gpio_irq_enable(index, pin);
+    else
+        gpio_irq_disable(index, pin);
+
+    return RT_EOK;
+}
+
+static void gpio_irq_handler(int irq, void *param)
+{
+    struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
+    rt_uint32_t pin;
+    rt_uint32_t value;
+    rt_uint32_t tmpvalue;
+
+    if (irq == IRQ_GPIO0)
+    {
+        /* 0~27 */
+
+        value = BCM283X_GPIO_GPEDS(0);
+        value &= 0x0fffffff;
+        pin = 0;
+        BCM283X_GPIO_GPEDS(0) = 0;
+    }
+    else if (irq == IRQ_GPIO1)
+    {
+        /* 28-45 */
+        tmpvalue = BCM283X_GPIO_GPEDS(0);
+        tmpvalue &= (~0x0fffffff);
+
+        value = BCM283X_GPIO_GPEDS(1);
+        value &= 0x3fff;
+        value = (value<<4) | tmpvalue;
+        pin = 28;
+        BCM283X_GPIO_GPEDS(0) = 0;
+        BCM283X_GPIO_GPEDS(1) = 0;
+    }
+    else if (irq == IRQ_GPIO2)
+    {
+        /* 46-53 */
+        value = BCM283X_GPIO_GPEDS(1);
+        value &= (~0x3fff);
+        value &= 0xff600000;
+        pin = 46;
+        BCM283X_GPIO_GPEDS(1) = 0;
+    }
+
+    while (value)
+    {
+        if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
+        {
+            irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
+            gpio_ack_irq(irq,pin);
+        }
+        pin++;
+        value = value >> 1;
+    }
+}
+
+static const struct rt_pin_ops ops =
+{
+    raspi_pin_mode,
+    raspi_pin_write,
+    raspi_pin_read,
+    raspi_pin_attach_irq,
+    raspi_pin_detach_irq,
+    raspi_pin_irq_enable,
+};
+#endif
+
+int rt_hw_gpio_init(void)
+{
+#ifdef BSP_USING_PIN
+    rt_device_pin_register("gpio", &ops, RT_NULL);
+
+    /* install ISR */
+    rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO0);
+
+    rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO1);
+
+    rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO2);
+#endif
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_gpio_init);

+ 42 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_gpio.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "interrupt.h"
+#include "board.h"
+
+#define GPIO_IRQ_NUM 3
+
+#define IRQ_GPIO0               49
+#define IRQ_GPIO1               50
+#define IRQ_GPIO2               51
+#define IRQ_GPIO3               52
+
+struct gpio_irq_def
+{
+    void  *irq_arg[32];
+    void (*irq_cb[32])(void *param);
+    rt_uint8_t irq_type[32];
+};
+
+enum gpio_irq_clock
+{
+    GPIO_IRQ_LOSC_32KHZ = 0,
+    GPIO_IRQ_HOSC_24MHZ
+};
+
+int rt_hw_gpio_init(void);
+
+#endif /* __DRV_GPIO_H__ */

+ 238 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_i2c.c

@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_i2c.h"
+
+//Maybe redefined
+typedef unsigned long                   rt_ubase_t;
+typedef rt_ubase_t                      rt_size_t;
+
+rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag)
+{
+    rt_uint32_t status;
+    rt_uint32_t remaining = len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    BCM283X_BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
+    /* Clear Status */
+    BCM283X_BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
+    /* Set Data Length */
+    BCM283X_BSC_DLEN(base) = len;
+    if (flag)
+    {
+        /* Start read */
+        BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ;
+        /* wait for transfer to complete */
+        while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
+        {
+            /* we must empty the FIFO as it is populated and not use any delay */
+            while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
+            {
+                /* Read from FIFO, no barrier */
+                buf[i] = BCM283X_BSC_FIFO(base);
+                i++;
+                remaining--;
+            }
+        }
+        /* transfer has finished - grab any remaining stuff in FIFO */
+        while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD))
+        {
+            /* Read from FIFO, no barrier */
+            buf[i] = BCM283X_BSC_FIFO(base);
+            i++;
+            remaining--;
+        }
+    }
+    else
+    {
+        /* pre populate FIFO with max buffer */
+        while (remaining && (i < BSC_FIFO_SIZE))
+        {
+            BCM283X_BSC_FIFO(base) = buf[i];
+            i++;
+            remaining--;
+        }
+
+        /* Enable device and start transfer */
+        BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST;
+
+        /* Transfer is over when BCM2835_BSC_S_DONE */
+        while (!(BCM283X_BSC_S(base) & BSC_S_DONE))
+        {
+            while (remaining && (BCM283X_BSC_S(base) & BSC_S_TXD))
+            {
+                /* Write to FIFO */
+                BCM283X_BSC_FIFO(base) = buf[i];
+                i++;
+                remaining--;
+            }
+        }
+    }
+
+    status = BCM283X_BSC_S(base);
+    if (status & BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+    else if (status & BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+    BCM283X_BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE);
+
+    return reason;
+}
+
+struct raspi_i2c_hw_config
+{
+    rt_uint8_t bsc_num;
+    rt_uint8_t sdl_pin;
+    rt_uint8_t scl_pin;
+    rt_uint8_t sdl_mode;
+    rt_uint8_t scl_mode;
+};
+
+#if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1))
+
+static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num);
+static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num);
+static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                      rt_uint32_t,
+                                      rt_uint32_t);
+
+static rt_uint32_t i2c_byte_wait_us = 0;
+static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num)
+{
+    rt_size_t i;
+    rt_uint8_t reason;
+    RT_ASSERT(bus != RT_NULL);
+
+    volatile rt_uint32_t base = (volatile rt_uint32_t)(bus->parent.user_data);
+
+    if (bus->addr == 0)
+        base = BCM283X_BSC0_BASE;
+    else
+        base = BCM283X_BSC1_BASE;
+
+    BCM283X_BSC_A(base) = msgs->addr;
+
+    for (i = 0; i < num; i++)
+    {
+        if (msgs[i].flags & RT_I2C_RD)
+            reason = i2c_read_or_write(base, msgs->buf, msgs->len, 1);
+        else
+            reason = i2c_read_or_write(base, msgs->buf, msgs->len, 0);
+    }
+    return (reason == 0)? i : 0;
+}
+
+static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num)
+{
+    return 0;
+}
+static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                      rt_uint32_t cmd,
+                                      rt_uint32_t arg)
+{
+    return RT_EOK;
+}
+
+static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
+{
+    .master_xfer = raspi_i2c_mst_xfer,
+    .slave_xfer = raspi_i2c_slv_xfer,
+    .i2c_bus_control = raspi_i2c_bus_control,
+};
+
+
+static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg)
+{
+    RT_ASSERT(cfg != RT_NULL);
+
+    volatile rt_uint32_t base = cfg->scl_mode ? BCM283X_BSC1_BASE : BCM283X_BSC0_BASE;
+
+    GPIO_FSEL(cfg->sdl_pin, cfg->sdl_mode); /* SDA */
+    GPIO_FSEL(cfg->scl_pin, cfg->scl_mode); /* SCL */
+
+    /* use 0xFFFE mask to limit a max value and round down any odd number */
+    rt_uint32_t divider = (BCM283X_CORE_CLK_HZ / 10000) & 0xFFFE;
+    BCM283X_BSC_DIV(base) = (rt_uint16_t) divider;
+    i2c_byte_wait_us = (divider * 1000000 * 9 / BCM283X_CORE_CLK_HZ);
+
+    return RT_EOK;
+}
+#endif
+
+#if defined (BSP_USING_I2C0)
+#define I2C0_BUS_NAME    "i2c0"
+static struct raspi_i2c_hw_config hw_device0 =
+{
+    .bsc_num = 0,
+    .sdl_pin = RPI_GPIO_P1_27,
+    .scl_pin = RPI_GPIO_P1_28,
+    .sdl_mode = BCM283X_GPIO_FSEL_ALT0,
+    .scl_mode = BCM283X_GPIO_FSEL_ALT0,
+};
+
+struct rt_i2c_bus_device device0 =
+{
+    .ops = &raspi_i2c_ops,
+    .addr = 0,
+};
+
+#endif
+
+#if defined (BSP_USING_I2C1)
+#define I2C1_BUS_NAME    "i2c1"
+static struct raspi_i2c_hw_config hw_device1 =
+{
+    .bsc_num = 1,
+    .sdl_pin = RPI_GPIO_P1_03,
+    .scl_pin = RPI_GPIO_P1_05,
+    .sdl_mode = BCM283X_GPIO_FSEL_ALT0,
+    .scl_mode = BCM283X_GPIO_FSEL_ALT0,
+};
+struct rt_i2c_bus_device device1 =
+{
+    .ops = &raspi_i2c_ops,
+    .addr = 1,
+};
+
+#endif
+
+int rt_hw_i2c_init(void)
+{
+#if defined(BSP_USING_I2C0)
+    raspi_i2c_configure(&hw_device0);
+    rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME);
+#endif
+
+#if defined(BSP_USING_I2C1)
+    raspi_i2c_configure(&hw_device1);
+    rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME);
+#endif
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_i2c_init);

+ 43 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_i2c.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_I2C_H__
+#define __DRV_I2C_H__
+
+#include <rtdevice.h>
+#include <rtthread.h>
+
+#include "board.h"
+
+struct raspi_master_config_t
+{
+    rt_uint8_t sdl_pin;
+    rt_uint8_t scl_pin;
+    rt_uint8_t sdl_pin_mode;
+    rt_uint8_t scl_pin_mode;
+    rt_uint8_t slave_address;
+    rt_uint32_t bsc_base;
+    rt_uint16_t clk_div;
+};
+
+struct raspi_i2c_bus
+{
+    struct rt_i2c_bus_device device;
+    struct rt_i2c_msg *msg;
+    rt_uint32_t msg_cnt;
+    volatile rt_uint32_t msg_ptr;
+    volatile rt_uint32_t dptr;
+    char *device_name;
+    struct raspi_master_config_t *cfg;
+};
+
+int rt_hw_i2c_init(void);
+
+#endif

+ 301 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_rtc.c

@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_rtc.h"
+
+#ifdef BSP_USING_RTC
+
+#define RTC_I2C_BUS_NAME      "i2c0"
+#define RTC_ADDR            0x68
+
+static struct rt_device rtc_device;
+static struct rt_i2c_bus_device *i2c_bus = RT_NULL;
+
+rt_uint8_t buf[]=
+{
+    0x00, 0x00, 0x43, 0x15, 0x05, 0x01, 0x03, 0x19
+};
+
+
+rt_uint8_t i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len)
+{
+    rt_uint32_t remaining = cmds_len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1);
+
+    /* Clear Status */
+    BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
+
+    /* Set Data Length */
+    BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = cmds_len;
+
+    /* pre populate FIFO with max buffer */
+    while (remaining && (i < BSC_FIFO_SIZE))
+    {
+        BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = cmds[i];
+        i++;
+        remaining--;
+    }
+
+    /* Enable device and start transfer */
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) |= BSC_C_I2CEN | BSC_C_ST;
+
+    /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */
+    while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TA))
+    {
+        /* Linux may cause us to miss entire transfer stage */
+        if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE)
+            break;
+    }
+
+    remaining = buf_len;
+    i = 0;
+
+    /* Send a repeated start with read bit set in address */
+    BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = buf_len;
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST  | BSC_C_READ;
+
+    /* Wait for write to complete and first byte back. */
+  //  DELAYMICROS(i2c_byte_wait_us * (cmds_len + 1));
+
+    /* wait for transfer to complete */
+    while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE))
+    {
+        /* we must empty the FIFO as it is populated and not use any delay */
+        while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD))
+        {
+        /* Read from FIFO, no barrier */
+        buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE);
+        i++;
+        remaining--;
+        }
+    }
+
+    /* transfer has finished - grab any remaining stuff in FIFO */
+    while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_RXD))
+    {
+        /* Read from FIFO */
+        buf[i] = BCM283X_BSC_FIFO(BCM283X_BSC0_BASE);
+        i++;
+        remaining--;
+    }
+
+    /* Received a NACK */
+    if (BCM283X_BSC_S(BCM283X_BSC0_BASE)  & BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+
+    /* Received Clock Stretch Timeout */
+    else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+
+    /* Not all data is sent */
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) = (BSC_S_DONE &BSC_S_DONE);
+
+    return reason;
+}
+
+rt_uint8_t i2c_write(rt_uint8_t* buf, rt_uint32_t len)
+{
+    rt_uint32_t remaining = len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    BCM283X_BSC_C(BCM283X_BSC0_BASE)  |= BSC_C_CLEAR_1 & BSC_C_CLEAR_1;
+    /* Clear Status */
+    BCM283X_BSC_S(BCM283X_BSC0_BASE) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE;
+    /* Set Data Length */
+    BCM283X_BSC_DLEN(BCM283X_BSC0_BASE) = len;
+    /* pre populate FIFO with max buffer */
+    while (remaining && (i < BSC_FIFO_SIZE))
+    {
+        BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i];
+        i++;
+        remaining--;
+    }
+
+    /* Enable device and start transfer */
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_C_I2CEN | BSC_C_ST;
+
+    /* Transfer is over when BCM2835_BSC_S_DONE */
+    while (!(BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_DONE))
+    {
+        while (remaining && (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_TXD))
+        {
+        /* Write to FIFO */
+        BCM283X_BSC_FIFO(BCM283X_BSC0_BASE) = buf[i];
+        i++;
+        remaining--;
+        }
+    }
+
+    /* Received a NACK */
+    if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+
+    /* Received Clock Stretch Timeout */
+    else if (BCM283X_BSC_S(BCM283X_BSC0_BASE) & BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+
+    /* Not all data is sent */
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+
+    BCM283X_BSC_C(BCM283X_BSC0_BASE) = BSC_S_DONE & BSC_S_DONE;
+    return reason;
+}
+
+
+static time_t raspi_get_timestamp(void)
+{
+    struct tm tm_new = {0};
+    buf[0] = 0;
+
+    i2c_write_read_rs((char*)buf, 1, (char*)buf, 7);
+
+    tm_new.tm_year = ((buf[6] / 16) + 0x30) * 10 + (buf[6] % 16) + 0x30;
+    tm_new.tm_mon  = ((buf[5] & 0x1F) / 16 + 0x30) + (buf[5] & 0x1F) % 16+ 0x30;
+    tm_new.tm_mday = ((buf[4] & 0x3F) / 16 + 0x30) + (buf[4] & 0x3F) % 16+ 0x30;
+    tm_new.tm_hour = ((buf[2] & 0x3F) / 16 + 0x30) + (buf[2] & 0x3F) % 16+ 0x30;
+    tm_new.tm_min  = ((buf[1] & 0x7F) / 16 + 0x30) + (buf[1] & 0x7F) % 16+ 0x30;
+    tm_new.tm_sec  = ((buf[0] & 0x7F) / 16 + 0x30) + (buf[0] & 0x7F) % 16+ 0x30;
+
+    return mktime(&tm_new);
+}
+
+static int raspi_set_timestamp(time_t timestamp)
+{
+    struct tm *tblock;
+    tblock = localtime(&timestamp);
+    buf[0] = 0;
+    buf[1] = tblock->tm_sec;
+    buf[2] = tblock->tm_min;
+    buf[3] = tblock->tm_hour;
+    buf[4] = tblock->tm_wday;
+    buf[5] = tblock->tm_mday;
+    buf[6] = tblock->tm_mon;
+    buf[7] = tblock->tm_year;
+
+    i2c_write(buf, 8);
+
+    return RT_EOK;
+}
+
+static rt_err_t raspi_rtc_init(rt_device_t dev)
+{
+    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(RTC_I2C_BUS_NAME);
+    raspi_set_timestamp(0);
+    return RT_EOK;
+}
+
+static rt_err_t raspi_rtc_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */
+    GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */
+    return RT_EOK;
+}
+
+static rt_err_t raspi_rtc_close(rt_device_t dev)
+{
+    GPIO_FSEL(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */
+    GPIO_FSEL(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */
+    return RT_EOK;
+}
+
+static rt_err_t raspi_rtc_control(rt_device_t dev, int cmd, void *args)
+{
+
+    RT_ASSERT(dev != RT_NULL);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_RTC_GET_TIME:
+        *(rt_uint32_t *)args = raspi_get_timestamp();
+        break;
+    case RT_DEVICE_CTRL_RTC_SET_TIME:
+        raspi_set_timestamp(*(time_t *)args);
+        break;
+    default:
+        return RT_EINVAL;
+    }
+    return RT_EOK;
+}
+
+static rt_size_t raspi_rtc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_GET_TIME, buffer);
+    return size;
+}
+
+static rt_size_t raspi_rtc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    raspi_rtc_control(dev, RT_DEVICE_CTRL_RTC_SET_TIME, (void *)buffer);
+    return size;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops raspi_rtc_ops =
+{
+    .init = raspi_rtc_init,
+    .open = raspi_rtc_open,
+    .close = raspi_rtc_close,
+    .read = raspi_rtc_read,
+    .write = raspi_rtc_write,
+    .control = raspi_rtc_control
+};
+#endif
+
+int rt_hw_rtc_init(void)
+{
+    rt_err_t ret = RT_EOK;
+
+    rtc_device.type        = RT_Device_Class_RTC;
+    rtc_device.rx_indicate = RT_NULL;
+    rtc_device.tx_complete = RT_NULL;
+
+#ifdef RT_USING_DEVICE_OPS
+    rtc_device.ops        = &raspi_rtc_ops;
+#else
+    rtc_device.init    = raspi_rtc_init;
+    rtc_device.open    = raspi_rtc_open;
+    rtc_device.close   = raspi_rtc_close;
+    rtc_device.read    = raspi_rtc_read;
+    rtc_device.write   = raspi_rtc_write;
+    rtc_device.control = raspi_rtc_control;
+#endif
+
+    rtc_device.user_data   = RT_NULL;
+
+    /* register a rtc device */
+    ret = rt_device_register(&rtc_device, "rtc", RT_DEVICE_FLAG_RDWR);
+
+    return ret;
+}
+INIT_DEVICE_EXPORT(rt_hw_rtc_init);
+#endif /* BSP_USING_RTC */
+

+ 21 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_rtc.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_RTC_H__
+#define __DRV_RTC_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+
+int rt_hw_rtc_init(void);
+
+#endif

+ 580 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_sdio.c

@@ -0,0 +1,580 @@
+/*
+ * File      : drv_sdio.c
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_sdio.h"
+
+static rt_uint32_t sdCommandTable[] = {
+    SD_CMD_INDEX(0),
+    SD_CMD_RESERVED(1),
+    SD_CMD_INDEX(2) | SD_RESP_R2,
+    SD_CMD_INDEX(3) | SD_RESP_R1,
+    SD_CMD_INDEX(4),
+    SD_CMD_RESERVED(5), //SD_CMD_INDEX(5) | SD_RESP_R4,
+    SD_CMD_INDEX(6) | SD_RESP_R1,
+    SD_CMD_INDEX(7) | SD_RESP_R1b,
+    SD_CMD_INDEX(8) | SD_RESP_R1,
+    SD_CMD_INDEX(9) | SD_RESP_R2,
+    SD_CMD_INDEX(10) | SD_RESP_R2,
+    SD_CMD_INDEX(11) | SD_RESP_R1,
+    SD_CMD_INDEX(12) | SD_RESP_R1b | SD_CMD_TYPE_ABORT,
+    SD_CMD_INDEX(13) | SD_RESP_R1,
+    SD_CMD_RESERVED(14),
+    SD_CMD_INDEX(15),
+    SD_CMD_INDEX(16) | SD_RESP_R1,
+    SD_CMD_INDEX(17) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_INDEX(18) | SD_RESP_R1 | SD_DATA_READ | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
+    SD_CMD_INDEX(19) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_INDEX(20) | SD_RESP_R1b,
+    SD_CMD_RESERVED(21),
+    SD_CMD_RESERVED(22),
+    SD_CMD_INDEX(23) | SD_RESP_R1,
+    SD_CMD_INDEX(24) | SD_RESP_R1 | SD_DATA_WRITE,
+    SD_CMD_INDEX(25) | SD_RESP_R1 | SD_DATA_WRITE | SD_CMD_MULTI_BLOCK | SD_CMD_BLKCNT_EN,
+    SD_CMD_INDEX(26) | SD_RESP_R1 | SD_DATA_WRITE, //add
+    SD_CMD_INDEX(27) | SD_RESP_R1 | SD_DATA_WRITE,
+    SD_CMD_INDEX(28) | SD_RESP_R1b,
+    SD_CMD_INDEX(29) | SD_RESP_R1b,
+    SD_CMD_INDEX(30) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_RESERVED(31),
+    SD_CMD_INDEX(32) | SD_RESP_R1,
+    SD_CMD_INDEX(33) | SD_RESP_R1,
+    SD_CMD_RESERVED(34),
+    SD_CMD_INDEX(35) | SD_RESP_R1, //add
+    SD_CMD_INDEX(36) | SD_RESP_R1, //add
+    SD_CMD_RESERVED(37),
+    SD_CMD_INDEX(38) | SD_RESP_R1b,
+    SD_CMD_INDEX(39) | SD_RESP_R4, //add
+    SD_CMD_INDEX(40) | SD_RESP_R5, //add
+    SD_CMD_INDEX(41) | SD_RESP_R3, //add, mov from harbote
+    SD_CMD_RESERVED(42) | SD_RESP_R1,
+    SD_CMD_RESERVED(43),
+    SD_CMD_RESERVED(44),
+    SD_CMD_RESERVED(45),
+    SD_CMD_RESERVED(46),
+    SD_CMD_RESERVED(47),
+    SD_CMD_RESERVED(48),
+    SD_CMD_RESERVED(49),
+    SD_CMD_RESERVED(50),
+    SD_CMD_INDEX(51) | SD_RESP_R1 | SD_DATA_READ,
+    SD_CMD_RESERVED(52),
+    SD_CMD_RESERVED(53),
+    SD_CMD_RESERVED(54),
+    SD_CMD_INDEX(55) | SD_RESP_R3,
+    SD_CMD_INDEX(56) | SD_RESP_R1 | SD_CMD_ISDATA,
+    SD_CMD_RESERVED(57),
+    SD_CMD_RESERVED(58),
+    SD_CMD_RESERVED(59),
+    SD_CMD_RESERVED(60),
+    SD_CMD_RESERVED(61),
+    SD_CMD_RESERVED(62),
+    SD_CMD_RESERVED(63)
+};
+
+static inline rt_uint32_t read32(rt_uint32_t addr)
+{
+    return (*((volatile rt_uint32_t *)(addr)));
+}
+
+static inline void write32(rt_uint32_t addr, rt_uint32_t value)
+{
+    *((volatile rt_uint32_t *)(addr)) = value;
+}
+
+rt_err_t sd_int(struct sdhci_pdata_t * pdat, unsigned int mask)
+{
+    unsigned int r;
+    unsigned int m = mask | INT_ERROR_MASK;
+    int cnt = 1000000;
+    while (!(read32(pdat->virt + EMMC_INTERRUPT) & (m | INT_ERROR_MASK)) && cnt--)
+        DELAY_MICROS(1);
+    r = read32(pdat->virt + EMMC_INTERRUPT);
+    if (cnt <= 0 || (r & INT_CMD_TIMEOUT) || (r & INT_DATA_TIMEOUT))
+    {
+        write32(pdat->virt + EMMC_INTERRUPT, r);
+        rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n",mask, r, read32(pdat->virt + EMMC_STATUS));
+        return -RT_ETIMEOUT;
+    }
+    else if (r & INT_ERROR_MASK)
+    {
+        write32(pdat->virt + EMMC_INTERRUPT, r);
+        rt_kprintf("send cmd/data error %x -> %x\n",r, read32(pdat->virt + EMMC_INTERRUPT));
+        return -RT_ERROR;
+    }
+    write32(pdat->virt + EMMC_INTERRUPT, mask);
+    return RT_EOK;
+}
+
+rt_err_t sd_status(struct sdhci_pdata_t * pdat, unsigned int mask)
+{
+    int cnt = 500000;
+    while ((read32(pdat->virt + EMMC_STATUS) & mask) && !(read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK) && cnt--)
+        DELAY_MICROS(1);
+    if (cnt <= 0)
+    {
+        return -RT_ETIMEOUT;
+    }
+    else if (read32(pdat->virt + EMMC_INTERRUPT) & INT_ERROR_MASK)
+        return  -RT_ERROR;
+    return RT_EOK;
+}
+
+static rt_err_t raspi_transfer_command(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd)
+{
+
+    rt_uint32_t cmdidx;
+    rt_err_t ret = RT_EOK;
+    ret = sd_status(pdat, SR_CMD_INHIBIT);
+    if (ret)
+    {
+        rt_kprintf("ERROR: EMMC busy %d\n", ret);
+        return ret;
+    }
+
+    cmdidx = sdCommandTable[cmd->cmdidx];
+    if (cmdidx == 0xFFFFFFFF)
+        return -RT_EINVAL;
+    if (cmd->datarw == DATA_READ)
+        cmdidx |= SD_DATA_READ;
+    if (cmd->datarw == DATA_WRITE)
+        cmdidx |= SD_DATA_WRITE;
+    mmcsd_dbg("transfer cmd %x(%d) %x %x\n", cmdidx, cmd->cmdidx, cmd->cmdarg, read32(pdat->virt + EMMC_INTERRUPT));
+    write32(pdat->virt + EMMC_INTERRUPT,read32(pdat->virt + EMMC_INTERRUPT));
+    write32(pdat->virt + EMMC_ARG1, cmd->cmdarg);
+    write32(pdat->virt + EMMC_CMDTM, cmdidx);
+    if (cmd->cmdidx == SD_APP_OP_COND)
+        DELAY_MICROS(1000);
+    else if ((cmd->cmdidx == SD_SEND_IF_COND) || (cmd->cmdidx == APP_CMD))
+        DELAY_MICROS(100);
+    ret = sd_int(pdat, INT_CMD_DONE);
+    if (ret)
+    {
+        return ret;
+    }
+    if (cmd->resptype & RESP_MASK)
+    {
+
+        if (cmd->resptype & RESP_R2)
+        {
+            rt_uint32_t resp[4];
+            resp[0] = read32(pdat->virt + EMMC_RESP0);
+            resp[1] = read32(pdat->virt + EMMC_RESP1);
+            resp[2] = read32(pdat->virt + EMMC_RESP2);
+            resp[3] = read32(pdat->virt + EMMC_RESP3);
+            if (cmd->resptype == RESP_R2)
+            {
+                cmd->response[0] = resp[3]<<8 |((resp[2]>>24)&0xff);
+                cmd->response[1] = resp[2]<<8 |((resp[1]>>24)&0xff);
+                cmd->response[2] = resp[1]<<8 |((resp[0]>>24)&0xff);
+                cmd->response[3] = resp[0]<<8 ;
+            }
+            else
+            {
+                cmd->response[0] = resp[0];
+                cmd->response[1] = resp[1];
+                cmd->response[2] = resp[2];
+                cmd->response[3] = resp[3];
+            }
+        }
+        else
+            cmd->response[0] = read32(pdat->virt + EMMC_RESP0);
+    }
+    mmcsd_dbg("response: %x: %x %x %x %x (%x, %x)\n", cmd->resptype, cmd->response[0], cmd->response[1], cmd->response[2], cmd->response[3], read32(pdat->virt + EMMC_STATUS),read32(pdat->virt + EMMC_INTERRUPT));
+    return ret;
+}
+
+static rt_err_t read_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    int c = 0;
+    rt_err_t ret;
+    int d;
+    while (c < blkcount)
+    {
+        if ((ret = sd_int(pdat, INT_READ_RDY)))
+        {
+            rt_kprintf("timeout happens when reading block %d\n",c);
+            return ret;
+        }
+        for (d=0; d < blksize / 4; d++)
+            if (read32(pdat->virt + EMMC_STATUS) & SR_READ_AVAILABLE)
+                buf[d] = read32(pdat->virt + EMMC_DATA);
+        c++;
+        buf += blksize / 4;
+    }
+    return RT_EOK;
+}
+
+static rt_err_t write_bytes(struct sdhci_pdata_t * pdat, rt_uint32_t * buf, rt_uint32_t blkcount, rt_uint32_t blksize)
+{
+    int c = 0;
+    rt_err_t ret;
+    int d;
+    while (c < blkcount)
+    {
+        if ((ret = sd_int(pdat, INT_WRITE_RDY)))
+        {
+            return ret;
+        }
+        for (d=0; d < blksize / 4; d++)
+            write32(pdat->virt + EMMC_DATA, buf[d]);
+        c++;
+        buf += blksize / 4;
+    }
+    if ((ret = sd_int(pdat, INT_DATA_DONE)))
+    {
+        return ret;
+    }
+    return RT_EOK;
+}
+
+static rt_err_t raspi_transfer_data(struct sdhci_pdata_t * pdat, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+{
+    rt_uint32_t dlen = (rt_uint32_t)(dat->blkcnt * dat->blksz);
+    rt_err_t ret = sd_status(pdat, SR_DAT_INHIBIT);
+    if (ret)
+    {
+        rt_kprintf("ERROR: EMMC busy\n");
+        return ret;
+    }
+    if (dat->blkcnt > 1)
+    {
+        struct sdhci_cmd_t newcmd;
+        newcmd.cmdidx = SET_BLOCK_COUNT;
+        newcmd.cmdarg = dat->blkcnt;
+        newcmd.resptype = RESP_R1;
+        ret = raspi_transfer_command(pdat, &newcmd);
+        if (ret) return ret;
+    }
+    write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
+
+    if (dat->flag & DATA_DIR_READ)
+    {
+        cmd->datarw = DATA_READ;
+        ret = raspi_transfer_command(pdat, cmd);
+        if (ret) return ret;
+        mmcsd_dbg("read_block %d, %d\n", dat->blkcnt, dat->blksz );
+        ret = read_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+    else if (dat->flag & DATA_DIR_WRITE)
+    {
+        cmd->datarw = DATA_WRITE;
+        ret = raspi_transfer_command(pdat, cmd);
+        if (ret) return ret;
+        mmcsd_dbg("write_block %d, %d", dat->blkcnt, dat->blksz );
+        ret = write_bytes(pdat, (rt_uint32_t *)dat->buf, dat->blkcnt, dat->blksz);
+    }
+    return ret;
+}
+
+static rt_err_t sdhci_transfer(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat)
+{
+    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
+
+    if (!dat)
+        return raspi_transfer_command(pdat, cmd);
+
+    return raspi_transfer_data(pdat, cmd, dat);
+}
+
+static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
+{
+    struct sdhci_t *sdhci = (struct sdhci_t *)host->private_data;
+    struct sdhci_cmd_t cmd;
+    struct sdhci_cmd_t stop;
+    struct sdhci_data_t dat;
+
+    rt_memset(&cmd, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&stop, 0, sizeof(struct sdhci_cmd_t));
+    rt_memset(&dat, 0, sizeof(struct sdhci_data_t));
+
+    cmd.cmdidx = req->cmd->cmd_code;
+    cmd.cmdarg = req->cmd->arg;
+    cmd.resptype =resp_type(req->cmd);
+    if (req->data)
+    {
+        dat.buf = (rt_uint8_t *)req->data->buf;
+        dat.flag = req->data->flags;
+        dat.blksz = req->data->blksize;
+        dat.blkcnt = req->data->blks;
+
+        req->cmd->err = sdhci_transfer(sdhci, &cmd, &dat);
+    }
+    else
+    {
+        req->cmd->err = sdhci_transfer(sdhci, &cmd, RT_NULL);
+    }
+
+    req->cmd->resp[3] = cmd.response[3];
+    req->cmd->resp[2] = cmd.response[2];
+    req->cmd->resp[1] = cmd.response[1];
+    req->cmd->resp[0] = cmd.response[0];
+
+    if (req->stop)
+    {
+        stop.cmdidx = req->stop->cmd_code;
+        stop.cmdarg = req->stop->arg;
+        cmd.resptype =resp_type(req->stop);
+        req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
+    }
+
+    mmcsd_req_complete(host);
+}
+
+rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
+{
+    return 0;
+}
+
+void mmc_enable_irq(struct rt_mmcsd_host *host, rt_int32_t en)
+{
+
+}
+
+static rt_err_t sdhci_detect(struct sdhci_t * sdhci)
+{
+    return RT_EOK;
+}
+
+static rt_err_t sdhci_setwidth(struct sdhci_t * sdhci, rt_uint32_t width)
+{
+    rt_uint32_t temp = 0;
+    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
+    if (width == MMCSD_BUS_WIDTH_4)
+    {
+        temp = read32((pdat->virt + EMMC_CONTROL0));
+        temp |= C0_HCTL_HS_EN;
+        temp |= C0_HCTL_DWITDH;   // always use 4 data lines:
+        write32((pdat->virt + EMMC_CONTROL0), temp);
+    }
+    return RT_EOK;
+}
+
+static rt_uint32_t sdhci_getdivider(rt_uint32_t sdHostVer, rt_uint32_t freq)
+{
+    rt_uint32_t divisor;
+    rt_uint32_t closest = 41666666 / freq;
+    rt_uint32_t shiftcount = __rt_fls(closest - 1);
+
+
+    if (shiftcount > 0) shiftcount--;
+    if (shiftcount > 7) shiftcount = 7;
+    if (sdHostVer > HOST_SPEC_V2)
+        divisor = closest;
+    else
+        divisor = (1 << shiftcount);
+
+    if (divisor <= 2)
+    {
+        divisor = 2;
+        shiftcount = 0;
+    }
+
+    rt_uint32_t hi = 0;
+    if (sdHostVer > HOST_SPEC_V2)
+        hi = (divisor & 0x300) >> 2;
+    rt_uint32_t lo = (divisor & 0x0ff);
+    rt_uint32_t cdiv = (lo << 8) + hi;
+    return cdiv;
+}
+
+static rt_err_t sdhci_setclock(struct sdhci_t * sdhci, rt_uint32_t clock)
+{
+    rt_uint32_t temp = 0;
+    rt_uint32_t sdHostVer = 0;
+    int count = 100000;
+    struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)(sdhci->priv);
+
+    while ((read32(pdat->virt + EMMC_STATUS) & (SR_CMD_INHIBIT | SR_DAT_INHIBIT)) && (--count))
+        DELAY_MICROS(1);
+    if (count <= 0)
+    {
+        rt_kprintf("EMMC: Set clock: timeout waiting for inhibit flags. Status %08x.\n",read32(pdat->virt + EMMC_STATUS));
+        return RT_ERROR;
+    }
+
+    // Switch clock off.
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp &= ~C1_CLK_EN;
+    write32((pdat->virt + EMMC_CONTROL1),temp);
+    DELAY_MICROS(10);
+    // Request the new clock setting and enable the clock
+    temp = read32(pdat->virt + EMMC_SLOTISR_VER);
+    sdHostVer = (temp & HOST_SPEC_NUM) >> HOST_SPEC_NUM_SHIFT;
+    int cdiv = sdhci_getdivider(sdHostVer, clock);
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp = (temp & 0xffff003f) | cdiv;
+    write32((pdat->virt + EMMC_CONTROL1),temp);
+    DELAY_MICROS(10);
+
+    // Enable the clock.
+    temp = read32(pdat->virt + EMMC_CONTROL1);
+    temp |= C1_CLK_EN;
+    write32((pdat->virt + EMMC_CONTROL1),temp);
+    DELAY_MICROS(10);
+    // Wait for clock to be stable.
+    count = 10000;
+    while (!(read32(pdat->virt + EMMC_CONTROL1) & C1_CLK_STABLE) && count--)
+        DELAY_MICROS(10);
+    if (count <= 0)
+    {
+        rt_kprintf("EMMC: ERROR: failed to get stable clock %d.\n", clock);
+        return RT_ERROR;
+    }
+    mmcsd_dbg("set stable clock %d.\n", clock);
+    return RT_EOK;
+}
+
+static void mmc_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg)
+{
+    struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
+    sdhci_setclock(sdhci, io_cfg->clock);
+    sdhci_setwidth(sdhci, io_cfg->bus_width);
+}
+
+static const struct rt_mmcsd_host_ops ops =
+{
+    mmc_request_send,
+    mmc_set_iocfg,
+    RT_NULL,
+    RT_NULL,
+};
+
+static void sdmmc_gpio_init()
+{
+//    int pin;
+//    bcm283x_gpio_fsel(47,BCM283X_GPIO_FSEL_INPT);
+//    bcm283x_gpio_set_pud(47, BCM283X_GPIO_PUD_UP);
+//    bcm283x_peri_set_bits(BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN1, 1<<15, 1<<15);
+//    for (pin = 53; pin >= 48; pin--)
+//    {
+//        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_ALT3);
+//        bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
+//    }
+}
+
+static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat){
+    rt_uint32_t temp;
+    int cnt;
+    write32((pdat->virt + EMMC_CONTROL0),0);
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp |= C1_SRST_HC;
+    write32((pdat->virt + EMMC_CONTROL1),temp);
+    cnt = 10000;
+    do
+    {
+        DELAY_MICROS(10);
+    }
+    while ((read32((pdat->virt + EMMC_CONTROL1)) & C1_SRST_HC) && cnt--);
+
+    if (cnt <= 0)
+    {
+        rt_kprintf("ERROR: failed to reset EMMC\n");
+        return RT_ERROR;
+    }
+    temp = read32((pdat->virt + EMMC_CONTROL1));
+    temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
+    write32((pdat->virt + EMMC_CONTROL1),temp);
+    DELAY_MICROS(10);
+    return RT_EOK;
+}
+
+#ifdef RT_MMCSD_DBG
+void dump_registers(struct sdhci_pdata_t * pdat){
+    rt_kprintf("EMMC registers:");
+    int i = EMMC_ARG2;
+    for (; i <= EMMC_CONTROL2; i += 4)
+        rt_kprintf("\t%x:%x\n", i, read32(pdat->virt + i));
+    rt_kprintf("\t%x:%x\n", 0x50, read32(pdat->virt + 0x50));
+    rt_kprintf("\t%x:%x\n", 0x70, read32(pdat->virt + 0x70));
+    rt_kprintf("\t%x:%x\n", 0x74, read32(pdat->virt + 0x74));
+    rt_kprintf("\t%x:%x\n", 0x80, read32(pdat->virt + 0x80));
+    rt_kprintf("\t%x:%x\n", 0x84, read32(pdat->virt + 0x84));
+    rt_kprintf("\t%x:%x\n", 0x88, read32(pdat->virt + 0x88));
+    rt_kprintf("\t%x:%x\n", 0x8c, read32(pdat->virt + 0x8c));
+    rt_kprintf("\t%x:%x\n", 0x90, read32(pdat->virt + 0x90));
+    rt_kprintf("\t%x:%x\n", 0xf0, read32(pdat->virt + 0xf0));
+    rt_kprintf("\t%x:%x\n", 0xfc, read32(pdat->virt + 0xfc));
+}
+#endif
+
+int raspi_sdmmc_init(void)
+{
+    rt_uint32_t virt;
+    struct rt_mmcsd_host * host = RT_NULL;
+    struct sdhci_pdata_t * pdat = RT_NULL;
+    struct sdhci_t * sdhci = RT_NULL;
+
+#ifdef BSP_USING_SDIO0
+    host = mmcsd_alloc_host();
+    if (!host)
+    {
+        rt_kprintf("alloc host failed");
+        goto err;
+    }
+
+    sdhci = rt_malloc(sizeof(struct sdhci_t));
+    if (!sdhci)
+    {
+        rt_kprintf("alloc sdhci failed");
+        goto err;
+    }
+    rt_memset(sdhci, 0, sizeof(struct sdhci_t));
+
+    sdmmc_gpio_init();
+
+    virt = MMC0_BASE_ADDR;
+
+    pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
+    RT_ASSERT(pdat != RT_NULL);
+
+    pdat->virt = (rt_uint32_t)virt;
+    reset_emmc(pdat);
+
+    sdhci->name = "sd0";
+    sdhci->voltages = VDD_33_34;
+    sdhci->width = MMCSD_BUSWIDTH_4;
+    sdhci->clock = 200 * 1000 * 1000;
+    sdhci->removeable = RT_TRUE;
+
+    sdhci->detect = sdhci_detect;
+    sdhci->setwidth = sdhci_setwidth;
+    sdhci->setclock = sdhci_setclock;
+    sdhci->transfer = sdhci_transfer;
+    sdhci->priv = pdat;
+
+    host->ops = &ops;
+    host->freq_min = 400000;
+    host->freq_max = 50000000;
+    host->valid_ocr = VDD_32_33 | VDD_33_34;
+    host->flags = MMCSD_MUTBLKWRITE | MMCSD_SUP_HIGHSPEED | MMCSD_SUP_SDIO_IRQ | MMCSD_BUSWIDTH_4;
+    host->max_seg_size = 2048;
+    host->max_dma_segs = 10;
+    host->max_blk_size = 512;
+    host->max_blk_count = 4096;
+
+    host->private_data = sdhci;
+
+    write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
+    write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
+#ifdef RT_MMCSD_DBG
+    dump_registers(pdat);
+#endif
+    mmcsd_change(host);
+#endif
+    return RT_EOK;
+
+err:
+    if (host)  rt_free(host);
+    if (sdhci) rt_free(sdhci);
+
+    return -RT_EIO;
+}
+
+INIT_DEVICE_EXPORT(raspi_sdmmc_init);

+ 253 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_sdio.h

@@ -0,0 +1,253 @@
+/*
+ * File      : drv_sdio.h
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_SDIO_H__
+#define __DRV_SDIO_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <drivers/mmcsd_core.h>
+
+#include "board.h"
+
+#define MMC0_BASE_ADDR     0x3F300000
+
+/* Struct for Intrrrupt Information */
+#define SDXC_CmdDone       BIT(0)
+#define SDXC_DataDone      BIT(1)
+#define SDXC_BlockGap      BIT(2)
+#define SDXC_WriteRdy      BIT(4)
+#define SDXC_ReadRdy       BIT(5)
+#define SDXC_Card          BIT(8)
+#define SDXC_Retune        BIT(12)
+#define SDXC_BootAck       BIT(13)
+#define SDXC_EndBoot       BIT(14)
+#define SDXC_Err              BIT(15)
+#define SDXC_CTOErr        BIT(16)
+#define SDXC_CCRCErr       BIT(17)
+#define SDXC_CENDErr       BIT(18)
+#define SDXC_CBADErr       BIT(19)
+#define SDXC_DTOErr        BIT(20)
+#define SDXC_DCRCErr       BIT(21)
+#define SDXC_DENDErr       BIT(22)
+#define SDXC_ACMDErr       BIT(24)
+
+#define SDXC_BLKCNT_EN          BIT(1)
+#define SDXC_AUTO_CMD12_EN      BIT(2)
+#define SDXC_AUTO_CMD23_EN      BIT(3)
+#define SDXC_DAT_DIR              BIT(4)   //from card to host
+#define SDXC_MULTI_BLOCK        BIT(5)
+#define SDXC_CMD_RSPNS_136         BIT(16)
+#define SDXC_CMD_RSPNS_48         BIT(17)
+#define SDXC_CMD_RSPNS_48busy   BIT(16)|BIT(17)
+#define SDXC_CHECK_CRC_CMD      BIT(19)
+#define SDXC_CMD_IXCHK_EN       BIT(20)
+#define SDXC_CMD_ISDATA         BIT(21)
+#define SDXC_CMD_SUSPEND        BIT(22)
+#define SDXC_CMD_RESUME         BIT(23)
+#define SDXC_CMD_ABORT          BIT(23)|BIT(22)
+
+#define SDXC_CMD_INHIBIT    BIT(0)
+#define SDXC_DAT_INHIBIT    BIT(1)
+#define SDXC_DAT_ACTIVE     BIT(2)
+#define SDXC_WRITE_TRANSFER     BIT(8)
+#define SDXC_READ_TRANSFER     BIT(9)
+
+struct sdhci_cmd_t
+{
+    rt_uint32_t cmdidx;
+    rt_uint32_t cmdarg;
+    rt_uint32_t resptype;
+    rt_uint32_t datarw;
+#define DATA_READ 1
+#define DATA_WRITE 2
+    rt_uint32_t response[4];
+};
+
+struct sdhci_data_t
+{
+    rt_uint8_t * buf;
+    rt_uint32_t flag;
+    rt_uint32_t blksz;
+    rt_uint32_t blkcnt;
+};
+
+struct sdhci_t
+{
+    char * name;
+    rt_uint32_t voltages;
+    rt_uint32_t width;
+    rt_uint32_t clock;
+    rt_err_t removeable;
+    void * sdcard;
+
+    rt_err_t (*detect)(struct sdhci_t * sdhci);
+    rt_err_t (*setwidth)(struct sdhci_t * sdhci, rt_uint32_t width);
+    rt_err_t (*setclock)(struct sdhci_t * sdhci, rt_uint32_t clock);
+    rt_err_t (*transfer)(struct sdhci_t * sdhci, struct sdhci_cmd_t * cmd, struct sdhci_data_t * dat);
+    void * priv;
+};
+
+struct sdhci_pdata_t
+{
+    rt_uint32_t virt;
+};
+
+// EMMC command flags
+#define CMD_TYPE_NORMAL  0x00000000
+#define CMD_TYPE_SUSPEND 0x00400000
+#define CMD_TYPE_RESUME  0x00800000
+#define CMD_TYPE_ABORT   0x00c00000
+#define CMD_IS_DATA      0x00200000
+#define CMD_IXCHK_EN     0x00100000
+#define CMD_CRCCHK_EN    0x00080000
+#define CMD_RSPNS_NO     0x00000000
+#define CMD_RSPNS_136    0x00010000
+#define CMD_RSPNS_48     0x00020000
+#define CMD_RSPNS_48B    0x00030000
+#define TM_MULTI_BLOCK   0x00000020
+#define TM_DAT_DIR_HC    0x00000000
+#define TM_DAT_DIR_CH    0x00000010
+#define TM_AUTO_CMD23    0x00000008
+#define TM_AUTO_CMD12    0x00000004
+#define TM_BLKCNT_EN     0x00000002
+#define TM_MULTI_DATA    (CMD_IS_DATA|TM_MULTI_BLOCK|TM_BLKCNT_EN)
+
+#define RCA_NO     1
+#define RCA_YES    2
+
+// INTERRUPT register settings
+#define INT_AUTO_ERROR   0x01000000
+#define INT_DATA_END_ERR 0x00400000
+#define INT_DATA_CRC_ERR 0x00200000
+#define INT_DATA_TIMEOUT 0x00100000
+#define INT_INDEX_ERROR  0x00080000
+#define INT_END_ERROR    0x00040000
+#define INT_CRC_ERROR    0x00020000
+#define INT_CMD_TIMEOUT  0x00010000
+#define INT_ERR          0x00008000
+#define INT_ENDBOOT      0x00004000
+#define INT_BOOTACK      0x00002000
+#define INT_RETUNE       0x00001000
+#define INT_CARD         0x00000100
+#define INT_READ_RDY     0x00000020
+#define INT_WRITE_RDY    0x00000010
+#define INT_BLOCK_GAP    0x00000004
+#define INT_DATA_DONE    0x00000002
+#define INT_CMD_DONE     0x00000001
+#define INT_ERROR_MASK   (INT_CRC_ERROR|INT_END_ERROR|INT_INDEX_ERROR| \
+                          INT_DATA_TIMEOUT|INT_DATA_CRC_ERR|INT_DATA_END_ERR| \
+                          INT_ERR|INT_AUTO_ERROR)
+#define INT_ALL_MASK     (INT_CMD_DONE|INT_DATA_DONE|INT_READ_RDY|INT_WRITE_RDY|INT_ERROR_MASK)
+
+#define EMMC_ARG2         (0x00)
+#define EMMC_BLKSIZECNT   (0x04)
+#define EMMC_ARG1         (0x08)
+#define EMMC_CMDTM        (0x0c)
+#define EMMC_RESP0        (0x10)
+#define EMMC_RESP1        (0x14)
+#define EMMC_RESP2        (0x18)
+#define EMMC_RESP3        (0x1c)
+#define EMMC_DATA         (0x20)
+#define EMMC_STATUS       (0x24)
+#define EMMC_CONTROL0     (0x28)
+#define EMMC_CONTROL1     (0x2c)
+#define EMMC_INTERRUPT    (0x30)
+#define EMMC_IRPT_MASK    (0x34)
+#define EMMC_IRPT_EN      (0x38)
+#define EMMC_CONTROL2     (0x3c)
+#define EMMC_BOOT_TIMEOUT (0x70)
+#define EMMC_EXRDFIFO_EN  (0x84)
+#define EMMC_SPI_INT_SPT  (0xf0)
+#define EMMC_SLOTISR_VER  (0xfc)
+
+// CONTROL register settings
+#define C0_SPI_MODE_EN   0x00100000
+#define C0_HCTL_HS_EN    0x00000004
+#define C0_HCTL_DWITDH   0x00000002
+
+#define C1_SRST_DATA     0x04000000
+#define C1_SRST_CMD      0x02000000
+#define C1_SRST_HC       0x01000000
+#define C1_TOUNIT_DIS    0x000f0000
+#define C1_TOUNIT_MAX    0x000e0000
+#define C1_CLK_GENSEL    0x00000020
+#define C1_CLK_EN        0x00000004
+#define C1_CLK_STABLE    0x00000002
+#define C1_CLK_INTLEN    0x00000001
+
+#define FREQ_SETUP           400000  // 400 Khz
+#define FREQ_NORMAL        25000000  // 25 Mhz
+
+// SLOTISR_VER values
+#define HOST_SPEC_NUM              0x00ff0000
+#define HOST_SPEC_NUM_SHIFT        16
+#define HOST_SPEC_V3               2
+#define HOST_SPEC_V2               1
+#define HOST_SPEC_V1               0
+
+// STATUS register settings
+#define SR_DAT_LEVEL1        0x1e000000
+#define SR_CMD_LEVEL         0x01000000
+#define SR_DAT_LEVEL0        0x00f00000
+#define SR_DAT3              0x00800000
+#define SR_DAT2              0x00400000
+#define SR_DAT1              0x00200000
+#define SR_DAT0              0x00100000
+#define SR_WRITE_PROT        0x00080000  // From SDHC spec v2, BCM says reserved
+#define SR_READ_AVAILABLE    0x00000800  // ???? undocumented
+#define SR_WRITE_AVAILABLE   0x00000400  // ???? undocumented
+#define SR_READ_TRANSFER     0x00000200
+#define SR_WRITE_TRANSFER    0x00000100
+#define SR_DAT_ACTIVE        0x00000004
+#define SR_DAT_INHIBIT       0x00000002
+#define SR_CMD_INHIBIT       0x00000001
+
+#define CONFIG_MMC_USE_DMA
+#define DMA_ALIGN       (32U)
+
+#define SD_CMD_INDEX(a)        ((a) << 24)
+#define SD_CMD_RESERVED(a)  0xffffffff
+#define SD_CMD_INDEX(a)        ((a) << 24)
+#define SD_CMD_TYPE_NORMAL    0x0
+#define SD_CMD_TYPE_SUSPEND    (1 << 22)
+#define SD_CMD_TYPE_RESUME    (2 << 22)
+#define SD_CMD_TYPE_ABORT    (3 << 22)
+#define SD_CMD_TYPE_MASK    (3 << 22)
+#define SD_CMD_ISDATA        (1 << 21)
+#define SD_CMD_IXCHK_EN        (1 << 20)
+#define SD_CMD_CRCCHK_EN    (1 << 19)
+#define SD_CMD_RSPNS_TYPE_NONE    0            // For no response
+#define SD_CMD_RSPNS_TYPE_136    (1 << 16)        // For response R2 (with CRC), R3,4 (no CRC)
+#define SD_CMD_RSPNS_TYPE_48    (2 << 16)        // For responses R1, R5, R6, R7 (with CRC)
+#define SD_CMD_RSPNS_TYPE_48B    (3 << 16)        // For responses R1b, R5b (with CRC)
+#define SD_CMD_RSPNS_TYPE_MASK  (3 << 16)
+#define SD_CMD_MULTI_BLOCK    (1 << 5)
+#define SD_CMD_DAT_DIR_HC    0
+#define SD_CMD_DAT_DIR_CH    (1 << 4)
+#define SD_CMD_AUTO_CMD_EN_NONE    0
+#define SD_CMD_AUTO_CMD_EN_CMD12    (1 << 2)
+#define SD_CMD_AUTO_CMD_EN_CMD23    (2 << 2)
+#define SD_CMD_BLKCNT_EN        (1 << 1)
+#define SD_CMD_DMA          1
+#define SD_RESP_NONE        SD_CMD_RSPNS_TYPE_NONE
+#define SD_RESP_R1          (SD_CMD_RSPNS_TYPE_48)           // | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R1b         (SD_CMD_RSPNS_TYPE_48B)         // | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R2          (SD_CMD_RSPNS_TYPE_136)           //| SD_CMD_CRCCHK_EN)
+#define SD_RESP_R3          SD_CMD_RSPNS_TYPE_48
+#define SD_RESP_R4          SD_CMD_RSPNS_TYPE_136
+#define SD_RESP_R5          (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R5b         (SD_CMD_RSPNS_TYPE_48B | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R6          (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_RESP_R7          (SD_CMD_RSPNS_TYPE_48 | SD_CMD_CRCCHK_EN)
+#define SD_DATA_READ        (SD_CMD_ISDATA | SD_CMD_DAT_DIR_CH)
+#define SD_DATA_WRITE       (SD_CMD_ISDATA | SD_CMD_DAT_DIR_HC)
+#endif

+ 287 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_spi.c

@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+#include "drv_spi.h"
+
+#ifdef RT_USING_SPI
+
+#define RPI_CORE_CLK_HZ        250000000
+#define BSP_SPI_MAX_HZ (30* 1000 *1000)
+#define SPITIMEOUT 0x0FFF
+
+void spi_gpio_write(rt_uint8_t pin, rt_uint8_t val)
+{
+    if (val)
+        BCM283X_GPIO_GPSET(pin / 32) = 1 << (pin % 32);
+    else
+        BCM283X_GPIO_GPCLR(pin / 32) = 0 << (pin % 32);
+}
+
+struct raspi_spi_hw_config
+{
+    rt_uint8_t spi_num;
+    raspi_gpio_pin sclk_pin;
+    raspi_pin_select sclk_mode;
+    raspi_gpio_pin mosi_pin;
+    raspi_pin_select mosi_mode;
+    raspi_gpio_pin miso_pin;
+    raspi_pin_select miso_mode;
+#if defined (BSP_USING_SPI0_DEVICE0) || defined (BSP_USING_SPI1_DEVICE0)
+    raspi_gpio_pin ce0_pin;
+    raspi_pin_select ce0_mode;
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1) || defined (BSP_USING_SPI1_DEVICE1)
+    raspi_gpio_pin ce1_pin;
+    raspi_pin_select ce1_mode;
+#endif
+
+#if defined (BSP_USING_SPI1_DEVICE2)
+    raspi_gpio_pin ce2_pin;
+    raspi_pin_select ce2_mode;
+#endif
+};
+
+struct raspi_spi_device
+{
+    char *device_name;
+    struct rt_spi_bus *spi_bus;
+    struct rt_spi_device *spi_device;
+    raspi_gpio_pin cs_pin;
+};
+
+static rt_err_t raspi_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
+{
+    RT_ASSERT(cfg != RT_NULL);
+    RT_ASSERT(device != RT_NULL);
+    rt_uint16_t divider;
+
+    // spi clear fifo
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CLEAR;
+
+    if (cfg->mode & RT_SPI_CPOL)
+        BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPOL;
+
+    if (cfg->mode & RT_SPI_CPHA)
+        BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CPHA;
+
+    if (cfg->mode & RT_SPI_CS_HIGH)
+        BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CSPOL;
+
+    //set clk
+    if (cfg->max_hz > BSP_SPI_MAX_HZ)
+        cfg->max_hz = BSP_SPI_MAX_HZ;
+
+    divider = (rt_uint16_t) ((rt_uint32_t) RPI_CORE_CLK_HZ / cfg->max_hz);
+    divider &= 0xFFFE;
+
+    BCM283X_SPI0_CLK(BCM283X_SPI0_BASE) = divider;
+
+    return RT_EOK;
+}
+
+rt_uint8_t correct_order(rt_uint8_t b, rt_uint8_t flag)
+{
+    if (flag)
+        return raspi_byte_reverse_table[b];
+    else
+        return b;
+}
+
+static rt_err_t spi_transfernb(rt_uint8_t* tbuf, rt_uint8_t* rbuf, rt_uint32_t len, rt_uint8_t flag)
+{
+    rt_uint32_t TXCnt=0;
+    rt_uint32_t RXCnt=0;
+
+    /* Clear TX and RX fifos */
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_CLEAR & BCM283X_SPI0_CS_CLEAR);
+
+    /* Set TA = 1 */
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (BCM283X_SPI0_CS_TA & BCM283X_SPI0_CS_TA);
+
+
+    /* Use the FIFO's to reduce the interbyte times */
+    while ((TXCnt < len) || (RXCnt < len))
+    {
+        /* TX fifo not full, so add some more bytes */
+        while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_TXD)) && (TXCnt < len))
+        {
+            BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE) = correct_order(tbuf[TXCnt],flag);
+            TXCnt++;
+        }
+        /* Rx fifo not empty, so get the next received bytes */
+        while (((BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_RXD)) && (RXCnt < len))
+        {
+            rbuf[RXCnt] = correct_order(BCM283X_SPI0_FIFO(BCM283X_SPI0_BASE),flag);
+            RXCnt++;
+        }
+    }
+    /* Wait for DONE to be set */
+    while (!(BCM283X_SPI0_CS(BCM283X_SPI0_BASE) & BCM283X_SPI0_CS_DONE));
+
+    /* Set TA = 0, and also set the barrier */
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= (0 & BCM283X_SPI0_CS_TA);
+    return RT_EOK;
+}
+
+static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
+{
+
+    RT_ASSERT(device != RT_NULL);
+    RT_ASSERT(device->bus != RT_NULL);
+    RT_ASSERT(device->parent.user_data != RT_NULL);
+    RT_ASSERT(message->send_buf != RT_NULL || message->recv_buf != RT_NULL);
+
+    rt_err_t res;
+    rt_uint8_t flag;
+    struct rt_spi_configuration config = device->config;
+    raspi_gpio_pin cs_pin = (raspi_gpio_pin)device->parent.user_data;
+
+    if (config.mode & RT_SPI_MSB)
+        flag = 0;
+    else
+        flag = 1;
+
+    if (message->cs_take)
+        (config.mode & RT_SPI_CS_HIGH)?
+                spi_gpio_write(cs_pin, 1):
+                spi_gpio_write(cs_pin, 0);
+
+    /* deal data */
+    res = spi_transfernb((rt_uint8_t *)message->send_buf, (rt_uint8_t *)message->recv_buf,
+            (rt_int32_t)message->length, flag);
+
+    if (message->cs_release)
+        (config.mode & RT_SPI_CS_HIGH)?
+                spi_gpio_write(cs_pin, 0):
+                spi_gpio_write(cs_pin, 1);
+
+    if (res != RT_EOK)
+           return RT_ERROR;
+
+    return message->length;
+}
+
+rt_err_t raspi_spi_bus_attach_device(const char *bus_name, struct raspi_spi_device *device)
+{
+    rt_err_t ret;
+    RT_ASSERT(device != RT_NULL);
+    ret = rt_spi_bus_attach_device(device->spi_device, device->device_name, bus_name, (void *)(device->cs_pin));
+    return ret;
+}
+
+rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg)
+{
+    GPIO_FSEL(hwcfg->sclk_pin, hwcfg->sclk_mode);
+    GPIO_FSEL(hwcfg->miso_pin, hwcfg->miso_mode);
+    GPIO_FSEL(hwcfg->mosi_pin, hwcfg->mosi_mode);
+
+#if defined (BSP_USING_SPI0_DEVICE0)
+    GPIO_FSEL(hwcfg->ce0_pin, hwcfg->ce0_mode);
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1)
+    GPIO_FSEL(hwcfg->ce1_pin, hwcfg->ce1_mode);
+#endif
+
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = 0;
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) = BCM283X_SPI0_CS_CLEAR;
+
+    //enable chip select
+#if defined (BSP_USING_SPI0_DEVICE0)
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0;
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1)
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= 0x2;
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1)
+    BCM283X_SPI0_CS(BCM283X_SPI0_BASE) |= BCM283X_SPI0_CS_CS;
+#endif
+    return RT_EOK;
+}
+
+static struct rt_spi_ops raspi_spi_ops =
+{
+    .configure = raspi_spi_configure,
+    .xfer = raspi_spi_xfer
+};
+
+#if defined (BSP_USING_SPI0_BUS)
+#define SPI0_BUS_NAME  "spi0"
+#define SPI0_DEVICE0_NAME  "spi0.0"
+#define SPI0_DEVICE1_NAME  "spi0.1"
+
+struct rt_spi_bus spi0_bus;
+
+#if defined (BSP_USING_SPI0_DEVICE0)
+struct rt_spi_device spi0_device0;
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1)
+static struct rt_spi_device spi0_device1;
+#endif
+
+struct raspi_spi_hw_config raspi_spi0_hw =
+{
+    .spi_num = 0,
+    .sclk_pin = RPI_GPIO_P1_23,
+    .sclk_mode = BCM283X_GPIO_FSEL_ALT0,
+    .mosi_pin = RPI_GPIO_P1_19,
+    .mosi_mode = BCM283X_GPIO_FSEL_ALT0,
+    .miso_pin = RPI_GPIO_P1_21,
+    .miso_mode = BCM283X_GPIO_FSEL_ALT0,
+
+#if defined (BSP_USING_SPI0_DEVICE0)
+    .ce0_pin = RPI_GPIO_P1_24,
+    .ce0_mode = BCM283X_GPIO_FSEL_ALT0,
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1)
+    .ce1_pin = RPI_GPIO_P1_26,
+    .ce1_mode = BCM283X_GPIO_FSEL_ALT0,
+#endif
+};
+#endif
+
+int rt_hw_spi_init(void)
+{
+
+#if defined (BSP_USING_SPI0_BUS)
+    raspi_spi_hw_init(&raspi_spi0_hw);
+    rt_spi_bus_register(&spi0_bus, SPI0_BUS_NAME, &raspi_spi_ops);
+
+#if defined (BSP_USING_SPI0_DEVICE0)
+    struct raspi_spi_device raspi_spi0_device0 =
+    {
+        .device_name = SPI0_DEVICE0_NAME,
+        .spi_bus = &spi0_bus,
+        .spi_device = &spi0_device0,
+        .cs_pin = raspi_spi0_hw.ce0_pin,
+    };
+    raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device0);
+#endif
+
+#if defined (BSP_USING_SPI0_DEVICE1)
+    struct raspi_spi_device raspi_spi0_device1 =
+    {
+        .device_name = SPI0_DEVICE1_NAME,
+        .spi_bus = &spi0_bus,
+        .spi_device = &spi0_device1,
+        .cs_pin = raspi_spi0_hw.ce1_pin,
+    };
+    raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device1);
+#endif
+#endif
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_spi_init);
+
+#endif

+ 102 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_spi.h

@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_SPI_H__
+#define __DRV_SPI_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+//#include <drivers/spi.h>
+#include "board.h"
+
+#define SPI0_BASE_ADDR     (PER_BASE + BCM283X_SPI0_BASE)
+
+static rt_uint8_t raspi_byte_reverse_table[] =
+{
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+#define    SPI_CORE_CLK    250000000U
+#define    SPI_CS        0x00
+#define    SPI_CS_LEN_LONG        (1 << 25)
+#define    SPI_CS_DMA_LEN        (1 << 24)
+#define    SPI_CS_CSPOL2        (1 << 23)
+#define    SPI_CS_CSPOL1        (1 << 22)
+#define    SPI_CS_CSPOL0        (1 << 21)
+#define    SPI_CS_RXF        (1 << 20)
+#define    SPI_CS_RXR        (1 << 19)
+#define    SPI_CS_TXD        (1 << 18)
+#define    SPI_CS_RXD        (1 << 17)
+#define    SPI_CS_DONE        (1 << 16)
+#define    SPI_CS_LEN        (1 << 13)
+#define    SPI_CS_REN        (1 << 12)
+#define    SPI_CS_ADCS        (1 << 11)
+#define    SPI_CS_INTR        (1 << 10)
+#define    SPI_CS_INTD        (1 << 9)
+#define    SPI_CS_DMAEN        (1 << 8)
+#define    SPI_CS_TA        (1 << 7)
+#define    SPI_CS_CSPOL        (1 << 6)
+#define    SPI_CS_CLEAR_RXFIFO    (1 << 5)
+#define    SPI_CS_CLEAR_TXFIFO    (1 << 4)
+#define    SPI_CS_CPOL        (1 << 3)
+#define    SPI_CS_CPHA        (1 << 2)
+#define    SPI_CS_MASK        0x3
+#define    SPI_FIFO    0x04
+#define    SPI_CLK        0x08
+#define    SPI_CLK_MASK        0xffff
+#define    SPI_DLEN    0x0c
+#define    SPI_DLEN_MASK        0xffff
+#define    SPI_LTOH    0x10
+#define    SPI_LTOH_MASK        0xf
+#define    SPI_DC        0x14
+#define    SPI_DC_RPANIC_SHIFT    24
+#define    SPI_DC_RPANIC_MASK    (0xff << SPI_DC_RPANIC_SHIFT)
+#define    SPI_DC_RDREQ_SHIFT    16
+#define    SPI_DC_RDREQ_MASK    (0xff << SPI_DC_RDREQ_SHIFT)
+#define    SPI_DC_TPANIC_SHIFT    8
+#define    SPI_DC_TPANIC_MASK    (0xff << SPI_DC_TPANIC_SHIFT)
+#define    SPI_DC_TDREQ_SHIFT    0
+#define    SPI_DC_TDREQ_MASK    0xff
+
+int rt_hw_spi_init(void);
+
+#endif

+ 154 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_timer.c

@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_timer.h"
+
+#ifdef BSP_USING_SYSTIMER
+
+static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state)
+{
+    if (state == 0)
+        hwtimer->ops->stop(hwtimer);
+}
+
+static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
+{
+    rt_err_t result = RT_EOK;
+    rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
+    int timer_id = timer->timer_id;
+
+    if (mode == HWTIMER_MODE_PERIOD)
+        timer->cnt = cnt;
+    else
+        timer->cnt = 0; 
+
+    __sync_synchronize();
+    if (timer_id == 1)
+    {
+        rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
+        STIMER_C1 = STIMER_CLO + cnt;
+    } 
+    else if (timer_id == 3)
+    {
+        rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
+        STIMER_C3 = STIMER_CLO + cnt;
+    }
+    else    
+        result = -RT_ERROR;
+
+    __sync_synchronize();
+         
+    return result;
+}
+
+static void raspi_systimer_stop(rt_hwtimer_t *hwtimer)
+{
+    rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
+    int timer_id = timer->timer_id;
+    if (timer_id == 1)
+        rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1);
+    else if (timer_id == 3)
+        rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3);
+ 
+}
+
+static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
+{
+    /* The frequency value is an immutable value. */
+    if (cmd == HWTIMER_CTRL_FREQ_SET)
+    {
+        return RT_EOK;
+    }
+    else
+    {
+        return -RT_ENOSYS;
+    }
+}
+
+
+void rt_device_systimer_isr(int vector, void *param)
+{
+    
+    rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param;
+    rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
+    RT_ASSERT(timer != RT_NULL);
+
+    int timer_id = timer->timer_id;
+
+    __sync_synchronize();
+    if (timer_id == 1)
+    {
+        STIMER_CS = 0x2;
+        STIMER_C1 = STIMER_CLO + timer->cnt;               
+    }   
+    else if (timer_id == 3)
+    {
+        STIMER_CS = 0x8;
+        STIMER_C3 = STIMER_CLO + timer->cnt;                 
+    }
+    __sync_synchronize();
+
+    rt_device_hwtimer_isr(hwtimer);
+}
+    
+static struct rt_hwtimer_device _hwtimer1;
+static struct rt_hwtimer_device _hwtimer3;
+
+static rt_systimer_t _systimer1;
+static rt_systimer_t _systimer3;
+
+const static struct rt_hwtimer_ops systimer_ops =
+{
+    raspi_systimer_init,
+    raspi_systimer_start,
+    raspi_systimer_stop,
+    RT_NULL,
+    raspi_systimer_ctrl
+};
+
+static const struct rt_hwtimer_info _info =
+{
+    1000000,            /* the maxinum count frequency can be set */
+    1000000,            /* the maxinum count frequency can be set */
+    0xFFFFFFFF,         /* the maximum counter value */
+    HWTIMER_CNTMODE_UP  /* count mode (inc/dec) */
+};
+
+#endif
+
+int rt_hw_systimer_init(void)
+{
+
+#ifdef BSP_USING_SYSTIMER
+
+#ifdef RT_USING_SYSTIMER1
+    _systimer1.timer_id =1;
+    _hwtimer1.ops = &systimer_ops;
+    _hwtimer1.info = &_info;
+    rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1);
+    rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1");
+    rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
+#endif
+
+#ifdef RT_USING_SYSTIMER3
+    _systimer3.timer_id =3;
+    _hwtimer3.ops = &systimer_ops;
+    _hwtimer3.info = &_info;
+    rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3);
+    rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3");
+    rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
+#endif
+
+#endif
+
+    return 0;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_systimer_init);

+ 27 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_timer.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+#ifndef __DRV_TIMER_H__
+#define __DRV_TIMER_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+
+typedef struct rt_systimer_device
+{
+    int  timer_id;
+    rt_uint32_t cnt;
+} rt_systimer_t;
+
+int rt_hw_systimer_init(void);
+
+
+#endif

+ 183 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_uart.c

@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2018/5/5       Bernard      The first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+#include "drv_uart.h"
+
+#include <rtdevice.h>
+
+#define AUX_BASE            (0x3F000000 + 0x215000)
+
+struct hw_uart_device
+{
+    rt_uint32_t hw_base;
+    rt_uint32_t irqno;
+};
+
+static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    if (uart->hw_base == AUX_BASE)
+    {
+        rt_uint32_t value;
+
+        /* GPIO function set */
+        value = BCM283X_GPIO_GPFSEL(1);
+        value &= ~(7 << 12); /* GPIO14 */
+        value |= 2 << 12 ; /* ALT5 */
+        value &= ~(7 << 15); /* GPIO15 */
+        value |= 2 << 15 ; /* ALT5 */
+        BCM283X_GPIO_GPFSEL(1) = value;
+
+        BCM283X_GPIO_GPPUD = 0;
+        BCM283X_GPIO_GPPUDCLK(0) = (1 << 14) | (1 << 15);
+        BCM283X_GPIO_GPPUDCLK(0) = 0;
+
+        AUX_ENABLES(uart->hw_base)      = 1;    /* Enable UART1 */
+        AUX_MU_IER_REG(uart->hw_base)   = 0;    /* Disable interrupt */
+        AUX_MU_CNTL_REG(uart->hw_base)  = 0;    /* Disable Transmitter and Receiver */
+        AUX_MU_LCR_REG(uart->hw_base)   = 3;    /* Works in 8-bit mode */
+        AUX_MU_MCR_REG(uart->hw_base)   = 0;    /* Disable RTS */
+        AUX_MU_IIR_REG(uart->hw_base)   = 0xC6; /* Enable FIFO, Clear FIFO */
+        AUX_MU_BAUD_REG(uart->hw_base)  = 270;  /* 115200 = system clock 250MHz / (8 * (baud + 1)), baud = 270 */
+        AUX_MU_CNTL_REG(uart->hw_base)  = 3;    /* Enable Transmitter and Receiver */
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* disable rx irq */
+        AUX_MU_IER_REG(uart->hw_base) = 0x0;
+        rt_hw_interrupt_mask(uart->irqno);
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        AUX_MU_IER_REG(uart->hw_base) = 0x1;
+        rt_hw_interrupt_umask(uart->irqno);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static int uart_putc(struct rt_serial_device *serial, char c)
+{
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20));
+    AUX_MU_IO_REG(uart->hw_base) = c;
+
+    return 1;
+}
+
+static int uart_getc(struct rt_serial_device *serial)
+{
+    int ch = -1;
+    struct hw_uart_device *uart;
+
+    RT_ASSERT(serial != RT_NULL);
+    uart = (struct hw_uart_device *)serial->parent.user_data;
+
+    if ((AUX_MU_LSR_REG(uart->hw_base) & 0x01))
+    {
+        ch = AUX_MU_IO_REG(uart->hw_base) & 0xff;
+    }
+
+    return ch;
+}
+
+static const struct rt_uart_ops _uart_ops =
+{
+    uart_configure,
+    uart_control,
+    uart_putc,
+    uart_getc,
+};
+
+static void rt_hw_uart_isr(int irqno, void *param)
+{
+    struct rt_serial_device *serial = (struct rt_serial_device*)param; 
+    rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+}
+
+#ifdef RT_USING_UART0
+/* UART device driver structure */
+static struct hw_uart_device _uart0_device =
+{
+    RPI_UART0_BASE,
+    IRQ_PBA8_UART0,
+};
+static struct rt_serial_device _serial0;
+#endif
+
+#ifdef RT_USING_UART1
+/* UART1 device driver structure */
+static struct hw_uart_device _uart1_device =
+{
+    AUX_BASE,
+    IRQ_AUX,
+};
+static struct rt_serial_device _serial1;
+#endif
+
+int rt_hw_uart_init(void)
+{
+    struct hw_uart_device *uart;
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+#ifdef RT_USING_UART0
+    uart = &_uart0_device;
+
+    _serial0.ops    = &_uart_ops;
+    _serial0.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&_serial0, "uart0",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
+                          uart);
+    rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial0, "uart0");
+#endif
+
+#ifdef RT_USING_UART1
+    uart = &_uart1_device;
+    _serial1.ops = &_uart_ops;
+    _serial1.config = config;
+
+    /* register UART1 device */
+    rt_hw_serial_register(&_serial1, "uart1",
+                          RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
+    /* enable Rx and Tx of UART */
+    rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial1, "uart1");
+#endif
+
+    return 0;
+}

+ 41 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_uart.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#ifndef DRV_UART_H__
+#define DRV_UART_H__
+
+/*
+ *  Auxiliary
+ */
+#define AUX_IRQ(BASE)             HWREG32(BASE + 0x00)   /* Auxiliary Interrupt status 3 */
+#define AUX_ENABLES(BASE)         HWREG32(BASE + 0x04)   /* Auxiliary enables 3bit */
+#define AUX_MU_IO_REG(BASE)       HWREG32(BASE + 0x40)   /* Mini Uart I/O Data 8bit */
+#define AUX_MU_IER_REG(BASE)      HWREG32(BASE + 0x44)   /* Mini Uart Interrupt Enable 8bit */
+#define AUX_MU_IIR_REG(BASE)      HWREG32(BASE + 0x48)   /* Mini Uart Interrupt Identify 8bit */
+#define AUX_MU_LCR_REG(BASE)      HWREG32(BASE + 0x4C)   /* Mini Uart Line Control 8bit */
+#define AUX_MU_MCR_REG(BASE)      HWREG32(BASE + 0x50)   /* Mini Uart Modem Control 8bit */
+#define AUX_MU_LSR_REG(BASE)      HWREG32(BASE + 0x54)   /* Mini Uart Line Status 8bit */
+#define AUX_MU_MSR_REG(BASE)      HWREG32(BASE + 0x58)   /* Mini Uart Modem Status 8bit */
+#define AUX_MU_SCRATCH(BASE)      HWREG32(BASE + 0x5C)   /* Mini Uart Scratch 8bit */
+#define AUX_MU_CNTL_REG(BASE)     HWREG32(BASE + 0x60)   /* Mini Uart Extra Control 8bit */
+#define AUX_MU_STAT_REG(BASE)     HWREG32(BASE + 0x64)   /* Mini Uart Extra Status 32bit */
+#define AUX_MU_BAUD_REG(BASE)     HWREG32(BASE + 0x68)   /* Mini Uart Baudrate 16bit */
+#define AUX_SPI0_CNTL0_REG(BASE)  HWREG32(BASE + 0x80)   /* SPI 1 Control register 0 32bit */
+#define AUX_SPI0_CNTL1_REG(BASE)  HWREG32(BASE + 0x84)   /* SPI 1 Control register 1 8bit */
+#define AUX_SPI0_STAT_REG(BASE)   HWREG32(BASE + 0x88)   /* SPI 1 Status 32bit */
+#define AUX_SPI0_IO_REG(BASE)     HWREG32(BASE + 0x90)   /* SPI 1 Data 32bit */
+#define AUX_SPI0_PEEK_REG(BASE)   HWREG32(BASE + 0x94)   /* SPI 1 Peek 16bit */
+#define AUX_SPI1_CNTL0_REG(BASE)  HWREG32(BASE + 0xC0)   /* SPI 2 Control register 0 32bit */
+#define AUX_SPI1_CNTL1_REG(BASE)  HWREG32(BASE + 0xC4)   /* SPI 2 Control register 1 8bit */
+
+int rt_hw_uart_init(void);
+
+#endif /* DRV_UART_H__ */
+

+ 117 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_wdt.c

@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+#include "drv_wdt.h"
+
+#ifdef BSP_USING_WDT
+
+#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
+#define WDOG_TICKS_TO_SECS(x) ((x) >> 16)
+
+static struct raspi_wdt_driver bcm_wdt;
+
+void raspi_watchdog_init(rt_uint32_t time_init)
+{
+    bcm_wdt.timeout = time_init;
+}
+
+void raspi_watchdog_start()
+{
+    volatile rt_uint32_t cur;
+    PM_WDOG = PM_PASSWORD | (SECS_TO_WDOG_TICKS(bcm_wdt.timeout) & PM_WDOG_TIME_SET);
+    cur = PM_RSTC;
+    PM_RSTC = PM_PASSWORD | (cur & PM_RSTC_WRCFG_CLR) | PM_RSTC_WRCFG_FULL_RESET;
+}
+
+void raspi_watchdog_stop()
+{
+    PM_RSTC = PM_PASSWORD | PM_RSTC_RESET;
+}
+
+void raspi_watchdog_clr()
+{
+    bcm_wdt.timeout = 0;
+}
+
+void raspi_watchdog_set_timeout(rt_uint32_t timeout_us)
+{
+    bcm_wdt.timeout = timeout_us;
+}
+
+rt_uint64_t raspi_watchdog_get_timeout()
+{
+    return bcm_wdt.timeout;
+}
+
+rt_uint64_t raspi_watchdog_get_timeleft()
+{
+    rt_uint32_t ret = PM_WDOG;
+    return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
+}
+
+static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt)
+{
+    /*init for 10S*/
+    raspi_watchdog_init(1000000);
+    raspi_watchdog_start();
+    raspi_watchdog_stop();
+    return RT_EOK;
+}
+
+static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg)
+{
+    rt_uint64_t  timeout_us = 0;
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+        timeout_us = *((rt_uint32_t *)arg) * 1000000;
+        if (timeout_us >= 0xFFFFFFFF)
+            timeout_us = 0xFFFFFFFF;
+        raspi_watchdog_set_timeout((rt_uint32_t)timeout_us);
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+        timeout_us = raspi_watchdog_get_timeout();
+        *((rt_uint32_t *)arg) = timeout_us / 1000000;
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
+        timeout_us = raspi_watchdog_get_timeleft();
+        *((rt_uint32_t *)arg) = timeout_us / 1000000;
+        break;
+    case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+        raspi_watchdog_clr();
+        break;
+    case RT_DEVICE_CTRL_WDT_START:
+        raspi_watchdog_start();
+        break;
+    case RT_DEVICE_CTRL_WDT_STOP:
+        raspi_watchdog_stop();
+        break;
+    default:
+        return RT_EIO;
+    }
+    return RT_EOK;
+}
+
+static const struct rt_watchdog_ops raspi_wdg_pos =
+{
+    raspi_wdg_init,
+    raspi_wdg_control,
+};
+
+static rt_watchdog_t raspi_wdg;
+
+int rt_hw_wdt_init(void)
+{
+    raspi_wdg.ops = &raspi_wdg_pos;
+    rt_hw_watchdog_register(&raspi_wdg, "wdg", 0, RT_NULL);
+    return RT_EOK;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_wdt_init);
+#endif /*BSP_USING_WDT */

+ 26 - 0
bsp/raspberry-pi/raspi3-32/driver/drv_wdt.h

@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_WDT_H__
+#define __DRV_WDT_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "board.h"
+
+struct raspi_wdt_driver
+{
+    rt_uint32_t timeout;
+};
+
+int rt_hw_wdt_init(void);
+
+#endif

+ 54 - 0
bsp/raspberry-pi/raspi3-32/driver/mbox.c

@@ -0,0 +1,54 @@
+/*
+ * File      : mbox.c
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+
+/* mailbox message buffer */
+#include "mbox.h"
+#include "mmu.h"
+
+volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR;
+/**
+ * Make a mailbox call. Returns 0 on failure, non-zero on success
+ */
+void init_mbox_mmu_map()
+{
+    rt_hw_change_mmu_table(MBOX_ADDR, 96, MBOX_ADDR, STRONG_ORDER_MEM);
+}
+
+int mbox_call(unsigned char ch, int mmu_enable)
+{
+    unsigned int r = (((MBOX_ADDR)&~0xF) | (ch&0xF));
+    if (mmu_enable)
+        r = BUS_ADDRESS(r);
+    /* wait until we can write to the mailbox */
+    do
+    {
+        asm volatile("nop");
+    } while (*MBOX_STATUS & MBOX_FULL);
+    /* write the address of our message to the mailbox with channel identifier */
+    *MBOX_WRITE = r;
+    /* now wait for the response */
+    while (1)
+    {
+        /* is there a response? */
+        do
+        {
+            asm volatile("nop");
+        } 
+        while (*MBOX_STATUS & MBOX_EMPTY);
+        /* is it a response to our message? */
+        if (r == *MBOX_READ)
+        {
+            /* is it a valid successful response? */
+            return mbox[1] == MBOX_RESPONSE;
+        }
+    }
+    return 0;
+}

+ 63 - 0
bsp/raspberry-pi/raspi3-32/driver/mbox.h

@@ -0,0 +1,63 @@
+/*
+ * File      : mbox.h
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+
+#ifndef __MBOX_H__
+#define __MBOX_H__
+
+/* a properly aligned buffer */
+extern volatile unsigned int* mbox;
+
+#define MBOX_REQUEST    0
+
+/* channels */
+#define MBOX_CH_POWER   0
+#define MBOX_CH_FB      1
+#define MBOX_CH_VUART   2
+#define MBOX_CH_VCHIQ   3
+#define MBOX_CH_LEDS    4
+#define MBOX_CH_BTNS    5
+#define MBOX_CH_TOUCH   6
+#define MBOX_CH_COUNT   7
+#define MBOX_CH_PROP    8
+
+/* tags */
+#define MBOX_TAG_SETPOWER       0x28001
+#define MBOX_TAG_SETCLKRATE     0x38002
+#define MBOX_GET_MAC_ADDRESS    0x10003
+#define MBOX_GET_CLOCK_RATE        0x30002
+#define MBOX_SET_CLOCK_RATE        0x38002
+#define MBOX_TAG_LAST           0
+
+#define MMIO_BASE       0x3F000000
+#define VIDEOCORE_MBOX  (MMIO_BASE+0x0000B880)
+#define MBOX_READ       ((volatile unsigned int*)(VIDEOCORE_MBOX+0x0))
+#define MBOX_POLL       ((volatile unsigned int*)(VIDEOCORE_MBOX+0x10))
+#define MBOX_SENDER     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x14))
+#define MBOX_STATUS     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x18))
+#define MBOX_CONFIG     ((volatile unsigned int*)(VIDEOCORE_MBOX+0x1C))
+#define MBOX_WRITE      ((volatile unsigned int*)(VIDEOCORE_MBOX+0x20))
+#define MBOX_RESPONSE   0x80000000
+#define MBOX_FULL       0x80000000
+#define MBOX_EMPTY      0x40000000
+
+#define DEVICE_ID_SD_CARD    0
+#define DEVICE_ID_USB_HCD    3
+#define POWER_STATE_OFF        (0 << 0)
+#define POWER_STATE_ON        (1 << 0)
+#define POWER_STATE_WAIT    (1 << 1)
+#define POWER_STATE_NO_DEVICE    (1 << 1)    // in response
+#define MMU_ENABLE 1
+#define MMU_DISABLE 0
+
+#define MBOX_ADDR 0xc00000
+
+int mbox_call(unsigned char ch, int mmu_enable);
+#endif

+ 432 - 0
bsp/raspberry-pi/raspi3-32/driver/raspi.h

@@ -0,0 +1,432 @@
+/*
+ * File      : rsapi.h
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date    Author  Notes
+ * 2019-07-29     zdzn    first version
+ */
+
+#ifndef __RASPI_H__
+#define __RASPI_H__
+
+/* define for bcm283x*/
+typedef enum
+{
+    BCM_GPIO_PIN_0 = 0,
+    BCM_GPIO_PIN_1,
+    BCM_GPIO_PIN_2,
+    BCM_GPIO_PIN_3,
+    BCM_GPIO_PIN_4,
+    BCM_GPIO_PIN_5,
+    BCM_GPIO_PIN_6,
+    BCM_GPIO_PIN_7,
+    BCM_GPIO_PIN_8,
+    BCM_GPIO_PIN_9,
+    BCM_GPIO_PIN_10,
+    BCM_GPIO_PIN_11,
+    BCM_GPIO_PIN_12,
+    BCM_GPIO_PIN_13,
+    BCM_GPIO_PIN_14,
+    BCM_GPIO_PIN_15,
+    BCM_GPIO_PIN_16,
+    BCM_GPIO_PIN_17,
+    BCM_GPIO_PIN_18,
+    BCM_GPIO_PIN_19,
+    BCM_GPIO_PIN_20,
+    BCM_GPIO_PIN_21,
+    BCM_GPIO_PIN_22,
+    BCM_GPIO_PIN_23,
+    BCM_GPIO_PIN_24,
+    BCM_GPIO_PIN_25,
+    BCM_GPIO_PIN_26,
+    BCM_GPIO_PIN_27,
+    BCM_GPIO_PIN_28,
+    BCM_GPIO_PIN_29,
+    BCM_GPIO_PIN_30,
+    BCM_GPIO_PIN_31,
+    BCM_GPIO_PIN_32,
+    BCM_GPIO_PIN_33,
+    BCM_GPIO_PIN_34,
+    BCM_GPIO_PIN_35,
+    BCM_GPIO_PIN_36,
+    BCM_GPIO_PIN_37,
+    BCM_GPIO_PIN_38,
+    BCM_GPIO_PIN_39,
+    BCM_GPIO_PIN_40,
+    BCM_GPIO_PIN_41,
+    BCM_GPIO_PIN_42,
+    BCM_GPIO_PIN_43,
+    BCM_GPIO_PIN_44,
+    BCM_GPIO_PIN_45,
+    BCM_GPIO_PIN_46,
+    BCM_GPIO_PIN_47,
+    BCM_GPIO_PIN_48,
+    BCM_GPIO_PIN_49,
+    BCM_GPIO_PIN_50,
+    BCM_GPIO_PIN_51,
+    BCM_GPIO_PIN_52,
+    BCM_GPIO_PIN_53,
+    BCM_GPIO_PIN_NULL,
+} bcm_gpio_pin;
+
+typedef enum
+{
+    BCM283X_GPIO_FSEL_INPT = 0x00,   /*!< Input 0b000 */
+    BCM283X_GPIO_FSEL_OUTP = 0x01,   /*!< Output 0b001 */
+    BCM283X_GPIO_FSEL_ALT0 = 0x04,   /*!< Alternate function 0 0b100 */
+    BCM283X_GPIO_FSEL_ALT1 = 0x05,   /*!< Alternate function 1 0b101 */
+    BCM283X_GPIO_FSEL_ALT2 = 0x06,   /*!< Alternate function 2 0b110, */
+    BCM283X_GPIO_FSEL_ALT3 = 0x07,   /*!< Alternate function 3 0b111 */
+    BCM283X_GPIO_FSEL_ALT4 = 0x03,   /*!< Alternate function 4 0b011 */
+    BCM283X_GPIO_FSEL_ALT5 = 0x02,   /*!< Alternate function 5 0b010 */
+    BCM283X_GPIO_FSEL_MASK = 0x07    /*!< Function select bits mask 0b111 */
+} gpio_function_select;
+
+typedef enum
+{
+    BCM283X_GPIO_PUD_OFF    = 0x00,   /*!< Off ? disable pull-up/down 0b00 */
+    BCM283X_GPIO_PUD_DOWN   = 0x01,   /*!< Enable Pull Down control 0b01 */
+    BCM283X_GPIO_PUD_UP     = 0x02    /*!< Enable Pull Up control 0b10  */
+} gpio_pud_mode;
+
+#define BCM283X_CORE_CLK_HZ 250000000    /* 50 MHz */
+
+/* Base Address */
+#define PER_BASE     (0x3F000000)
+#define PER_BASE_40000000    (0x40000000)
+//#define BCM283X_PERI_BASE     (0x3F000000)
+//#define BCM283X_PER_BASE_40000000    (0x40000000)
+
+/* Base Address Registers Offset */
+#define ST_BASE_OFFSET     (0x003000)
+#define GPIO_PAD_OFFSET     (0x100000)
+#define CLOCK_BASE_OFFSET (0x101000)
+#define GPIO_BASE_OFFSET (0x200000)
+#define SPI0_BASE_OFFSET (0x204000)
+#define BSC0_BASE_OFFSET (0x205000)
+#define GPIO_PWM_OFFSET     (0x20C000)
+#define AUX_BASE_OFFSET     (0x215000)
+#define SPI1_BASE_OFFSET (0x215080)
+#define SPI2_BASE_OFFSET (0x2150C0)
+#define BSC1_BASE_OFFSET (0x804000)
+#define BSC2_BASE_OFFSET (0x805000)
+
+/* IRQ */
+#define IRQ_SYSTEM_TIMER_0 0
+#define IRQ_SYSTEM_TIMER_1  1
+#define IRQ_SYSTEM_TIMER_2 2
+#define IRQ_SYSTEM_TIMER_3 3
+#define IRQ_USB      9
+#define IRQ_AUX      29
+#define IRQ_PCM      55
+#define IRQ_ARM_TIMER     64
+#define IRQ_ARM_MAILBOX     65
+
+/* Interrupt Controler */
+#define IRQ_BASE     (PER_BASE + 0xB200)
+#define IRQ_PEND_BASIC      HWREG32(IRQ_BASE + 0x0000)
+#define IRQ_PEND1    HWREG32(IRQ_BASE + 0x0004)
+#define IRQ_PEND2    HWREG32(IRQ_BASE + 0x0008)
+#define IRQ_FIQ_CONTROL     HWREG32(IRQ_BASE + 0x000C)
+#define IRQ_ENABLE1  HWREG32(IRQ_BASE + 0x0010)
+#define IRQ_ENABLE2  HWREG32(IRQ_BASE + 0x0014)
+#define IRQ_ENABLE_BASIC    HWREG32(IRQ_BASE + 0x0018)
+#define IRQ_DISABLE1 HWREG32(IRQ_BASE + 0x001C)
+#define IRQ_DISABLE2 HWREG32(IRQ_BASE + 0x0020)
+#define IRQ_DISABLE_BASIC   HWREG32(IRQ_BASE + 0x0024)
+
+
+/* Defines for WDT*/
+#define PM_BASE  (PER_BASE  + GPIO_PAD_OFFSET)
+#define PM_RSTC  HWREG32(PM_BASE + 0x001C)
+#define PM_RSTS  HWREG32(PM_BASE + 0x0020)
+#define PM_WDOG  HWREG32(PM_BASE + 0x0024)
+
+#define PM_PASSWORD     0x5a000000
+#define PM_WDOG_TIME_SET    0x000fffff
+#define PM_RSTC_WRCFG_CLR    0xffffffcf
+#define PM_RSTS_HADWRH_SET    0x00000040
+#define PM_RSTC_WRCFG_SET    0x00000030
+#define PM_RSTC_WRCFG_FULL_RESET    0x00000020
+#define PM_RSTC_RESET 0x00000102
+#define PM_RSTS_PARTITION_CLR 0xfffffaaa
+
+/* Defines for System Timer */
+#define STIMER_BASE  (PER_BASE  + ST_BASE_OFFSET)
+#define STIMER_CS    HWREG32(STIMER_BASE + 0x0000)
+#define STIMER_CLO   HWREG32(STIMER_BASE + 0x0004)
+#define STIMER_CHI   HWREG32(STIMER_BASE + 0x0008)
+#define STIMER_C0    HWREG32(STIMER_BASE + 0x000C)
+#define STIMER_C1    HWREG32(STIMER_BASE + 0x0010)
+#define STIMER_C2    HWREG32(STIMER_BASE + 0x0014)
+#define STIMER_C3    HWREG32(STIMER_BASE + 0x0018)
+
+#define DELAY_MICROS(micros) \
+    do{ \
+ rt_uint32_t compare = STIMER_CLO + micros * 25; \
+ while (STIMER_CLO < compare); \
+    } while (0) \
+
+/* Defines for GPIO */
+#define BCM283X_GPIO_BASE     (PER_BASE + GPIO_BASE_OFFSET)
+#define BCM283X_GPIO_GPFSEL(n) HWREG32(BCM283X_GPIO_BASE + 0x0000 + 0x4 * n) /* GPIO Function Select 32bit R/W */
+#define BCM283X_GPIO_GPSET(n) HWREG32(BCM283X_GPIO_BASE + 0x001C + 0x4 * n) /* GPIO Pin Output Set */
+#define BCM283X_GPIO_GPCLR(n) HWREG32(BCM283X_GPIO_BASE + 0x0028 + 0x4 * n) /* GPIO Pin Output Clear */
+#define BCM2835_GPIO_GPLEV(n) HWREG32(BCM283X_GPIO_BASE + 0x0034 + 0x4 * n) /* GPIO Pin Level */
+#define BCM283X_GPIO_GPEDS(n) HWREG32(BCM283X_GPIO_BASE + 0x0040 + 0x4 * n) /* GPIO Pin Event Detect Status */
+#define BCM283X_GPIO_GPREN(n) HWREG32(BCM283X_GPIO_BASE + 0x004c + 0x4 * n) /* GPIO Pin Rising Edge Detect Enable */
+#define BCM283X_GPIO_GPFEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0058 + 0x4 * n) /* GPIO Pin Falling Edge Detect Enable */
+#define BCM283X_GPIO_GPHEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0064 + 0x4 * n) /* GPIO Pin High Detect Enable  */
+#define BCM283X_GPIO_GPLEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0070 + 0x4 * n) /* GPIO Pin Low Detect Enable */
+#define BCM283X_GPIO_GPAREN(n) HWREG32(BCM283X_GPIO_BASE + 0x007C + 0x4 * n) /* GPIO Pin Async. Rising Edge Detect */
+#define BCM283X_GPIO_GPAFEN(n) HWREG32(BCM283X_GPIO_BASE + 0x0088 + 0x4 * n) /* GPIO Pin Async. Falling Edge Detect */
+#define BCM283X_GPIO_GPPUD     HWREG32(BCM283X_GPIO_BASE + 0x0094)     /* GPIO Pin Pull-up/down Enable */
+#define BCM283X_GPIO_GPPUDCLK(n)    HWREG32(BCM283X_GPIO_BASE + 0x0098 + 0x4 * n) /* GPIO Pin Pull-up/down Enable Clock */
+
+#define GPIO_FSEL_NUM(pin)  (pin/10)
+#define GPIO_FSEL_SHIFT(pin)  ((pin%10)*3)
+#define GPIO_FSEL(pin, mode) \
+    do{ \
+ __sync_synchronize(); \
+ BCM283X_GPIO_GPFSEL(GPIO_FSEL_NUM(pin)) |= ((mode & BCM283X_GPIO_FSEL_MASK) << GPIO_FSEL_SHIFT(pin)); \
+    } while (0) \
+
+/* Defines for I2C */
+#define BCM283X_BSC0_BASE     (PER_BASE + BSC0_BASE_OFFSET)    //for i2c0
+#define BCM283X_BSC1_BASE     (PER_BASE + BSC1_BASE_OFFSET)    //for i2c1
+#define BCM283X_BSC2_BASE     (PER_BASE + BSC2_BASE_OFFSET)    //for hdmi i2c not use
+
+#define BCM283X_BSC_C(BASE)  HWREG32(BASE + 0x0000)    /* BSC Master Control */
+#define BCM283X_BSC_S(BASE)  HWREG32(BASE + 0x0004)    /* BSC Master Status */
+#define BCM283X_BSC_DLEN(BASE)      HWREG32(BASE + 0x0008)    /* BSC Master Data Length */
+#define BCM283X_BSC_A(BASE)  HWREG32(BASE + 0x000c)    /* BSC Master Slave Address */
+#define BCM283X_BSC_FIFO(BASE)      HWREG32(BASE + 0x0010)    /* BSC Master Data FIFO */
+#define BCM283X_BSC_DIV(BASE)       HWREG32(BASE + 0x0014)    /* BSC Master Clock Divider */
+#define BCM283X_BSC_DEL(BASE)       HWREG32(BASE + 0x0018)    /* BSC Master Data Delay */
+#define BCM283X_BSC_CLKT(BASE)      HWREG32(BASE + 0x001c)    /* BSC Master Clock Stretch Timeout */
+
+/* Register masks for C Register */
+#define BSC_C_I2CEN      0x00008000 /* I2C Enable, 0 = disabled, 1 = enabled */
+#define BSC_C_INTR      0x00000400 /* Interrupt on RX */
+#define BSC_C_INTT      0x00000200 /* Interrupt on TX */
+#define BSC_C_INTD      0x00000100 /* Interrupt on DONE */
+#define BSC_C_ST      0x00000080 /* Start transfer, 1 = Start a new transfer */
+#define BSC_C_CLEAR_1   0x00000020 /* Clear FIFO Clear */
+#define BSC_C_CLEAR_2   0x00000010 /* Clear FIFO Clear */
+#define BSC_C_READ       0x00000001 /* Read transfer */
+
+/* Register masks for S Register */
+#define BSC_S_CLKT      0x00000200 /* Clock stretch timeout */
+#define BSC_S_ERR      0x00000100 /* ACK error */
+#define BSC_S_RXF       0x00000080 /* RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BSC_S_TXE       0x00000040 /* TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BSC_S_RXD       0x00000020 /* RXD FIFO contains data */
+#define BSC_S_TXD       0x00000010 /* TXD FIFO can accept data */
+#define BSC_S_RXR      0x00000008 /* RXR FIFO needs reading (full) */
+#define BSC_S_TXW      0x00000004 /* TXW FIFO needs writing (full) */
+#define BSC_S_DONE      0x00000002 /* Transfer DONE */
+#define BSC_S_TA      0x00000001 /* Transfer Active */
+
+#define BSC_FIFO_SIZE  (16)  /* BSC FIFO size */
+
+/* Defines for SPI */
+#define BCM283X_SPI0_BASE     (PER_BASE + SPI0_BASE_OFFSET)
+#define BCM283X_SPI1_BASE     (PER_BASE + SPI1_BASE_OFFSET)
+#define BCM283X_SPI2_BASE     (PER_BASE + SPI2_BASE_OFFSET)
+
+#define BCM283X_SPI0_CS(BASE) HWREG32(BASE + 0x0000) /* SPI Master Control and Status */
+#define BCM283X_SPI0_FIFO(BASE) HWREG32(BASE + 0x0004) /* SPI Master TX and RX FIFOs */
+#define BCM283X_SPI0_CLK(BASE) HWREG32(BASE + 0x0008) /* SPI Master Clock Divider */
+#define BCM283X_SPI0_DLEN(BASE) HWREG32(BASE + 0x000c) /* SPI Master Data Length */
+#define BCM283X_SPI0_LTOH(BASE) HWREG32(BASE + 0x0010) /* SPI LOSSI mode TOH */
+#define BCM283X_SPI0_DC(BASE) HWREG32(BASE + 0x0014) /* SPI DMA DREQ Controls */
+
+/* Register masks for SPI0_CS */
+#define BCM283X_SPI0_CS_LEN_LONG    0x02000000 /* Enable Long data word in Lossi mode if DMA_LEN is set */
+#define BCM283X_SPI0_CS_DMA_LEN 0x01000000 /* Enable DMA mode in Lossi mode */
+#define BCM283X_SPI0_CS_CSPOL2 0x00800000 /* Chip Select 2 Polarity */
+#define BCM283X_SPI0_CS_CSPOL1 0x00400000 /* Chip Select 1 Polarity */
+#define BCM283X_SPI0_CS_CSPOL0 0x00200000 /* Chip Select 0 Polarity */
+#define BCM283X_SPI0_CS_RXF     0x00100000 /* RXF - RX FIFO Full */
+#define BCM283X_SPI0_CS_RXR     0x00080000 /* RXR RX FIFO needs Reading (full) */
+#define BCM283X_SPI0_CS_TXD     0x00040000 /* TXD TX FIFO can accept Data */
+#define BCM283X_SPI0_CS_RXD     0x00020000 /* RXD RX FIFO contains Data */
+#define BCM283X_SPI0_CS_DONE 0x00010000 /* Done transfer Done */
+#define BCM283X_SPI0_CS_TE_EN 0x00008000 /* Unused */
+#define BCM283X_SPI0_CS_LMONO 0x00004000 /* Unused */
+#define BCM283X_SPI0_CS_LEN     0x00002000 /* LEN LoSSI enable */
+#define BCM283X_SPI0_CS_REN     0x00001000 /* REN Read Enable */
+#define BCM283X_SPI0_CS_ADCS 0x00000800 /* ADCS Automatically Deassert Chip Select */
+#define BCM283X_SPI0_CS_INTR 0x00000400 /* INTR Interrupt on RXR */
+#define BCM283X_SPI0_CS_INTD 0x00000200 /* INTD Interrupt on Done */
+#define BCM283X_SPI0_CS_DMAEN 0x00000100 /* DMAEN DMA Enable */
+#define BCM283X_SPI0_CS_TA     0x00000080 /* Transfer Active */
+#define BCM283X_SPI0_CS_CSPOL 0x00000040 /* Chip Select Polarity */
+#define BCM283X_SPI0_CS_CLEAR 0x00000030 /* Clear FIFO Clear RX and TX */
+#define BCM283X_SPI0_CS_CLEAR_RX    0x00000020 /* Clear FIFO Clear RX  */
+#define BCM283X_SPI0_CS_CLEAR_TX    0x00000010 /* Clear FIFO Clear TX  */
+#define BCM283X_SPI0_CS_CPOL 0x00000008 /* Clock Polarity */
+#define BCM283X_SPI0_CS_CPHA 0x00000004 /* Clock Phase */
+#define BCM283X_SPI0_CS_CS     0x00000003 /* Chip Select */
+
+/* ARM Timer */
+#define ARM_TIMER_BASE  (PER_BASE + 0xB000)
+#define ARM_TIMER_LOAD  HWREG32(ARM_TIMER_BASE + 0x400)
+#define ARM_TIMER_VALUE  HWREG32(ARM_TIMER_BASE + 0x404)
+#define ARM_TIMER_CTRL  HWREG32(ARM_TIMER_BASE + 0x408)
+#define ARM_TIMER_IRQCLR     HWREG32(ARM_TIMER_BASE + 0x40C)
+#define ARM_TIMER_RAWIRQ     HWREG32(ARM_TIMER_BASE + 0x410)
+#define ARM_TIMER_MASKIRQ     HWREG32(ARM_TIMER_BASE + 0x414)
+#define ARM_TIMER_RELOAD     HWREG32(ARM_TIMER_BASE + 0x418)
+#define ARM_TIMER_PREDIV     HWREG32(ARM_TIMER_BASE + 0x41C)
+#define ARM_TIMER_CNTR  HWREG32(ARM_TIMER_BASE + 0x420)
+
+/* ARM Core Timer */
+#define C0TIMER_INTCTL   HWREG32(PER_BASE_40000000 + 0x40)  /* Core0 timers Interrupt control */
+#define C1TIMER_INTCTL  HWREG32(PER_BASE_40000000 + 0x44)  /* Core1 timers Interrupt control */
+#define C2TIMER_INTCTL  HWREG32(PER_BASE_40000000 + 0x48)  /* Core2 timers Interrupt control */
+#define C3TIMER_INTCTL  HWREG32(PER_BASE_40000000 + 0x4C)  /* Core3 timers Interrupt control */
+#define CORETIMER_INTCTL(n)     HWREG32(PER_BASE_40000000 + 0x40 + n*4)  /* Coren timers Interrupt control */
+
+/* ARM Core Mailbox interrupt */
+#define C0MB_INTCTL      HWREG32(PER_BASE_40000000 + 0x50)  /* Core0 Mailboxes Interrupt control */
+#define C1MB_INTCTL      HWREG32(PER_BASE_40000000 + 0x54)  /* Core1 Mailboxes Interrupt control */
+#define C2MB_INTCTL      HWREG32(PER_BASE_40000000 + 0x58)  /* Core2 Mailboxes Interrupt control */
+#define C3MB_INTCTL      HWREG32(PER_BASE_40000000 + 0x5C)  /* Core3 Mailboxes Interrupt control */
+#define COREMB_INTCTL(n)     HWREG32(PER_BASE_40000000 + 0x50 + 4*n)  /* Coren Mailboxes Interrupt control */
+
+/* ARM Core IRQ/FIQ status */
+#define C0_IRQSOURCE  HWREG32(PER_BASE_40000000 + 0x60)  /* Core0 IRQ Source */
+#define C1_IRQSOURCE  HWREG32(PER_BASE_40000000 + 0x64)  /* Core1 IRQ Source */
+#define C2_IRQSOURCE  HWREG32(PER_BASE_40000000 + 0x68)  /* Core2 IRQ Source */
+#define C3_IRQSOURCE  HWREG32(PER_BASE_40000000 + 0x6C)  /* Core3 IRQ Source */
+#define C0_FIQSOURCE  HWREG32(PER_BASE_40000000 + 0x70)  /* Core0 FIQ Source */
+#define C1_FIQSOURCE  HWREG32(PER_BASE_40000000 + 0x74)  /* Core1 FIQ Source */
+#define C2_FIQSOURCE  HWREG32(PER_BASE_40000000 + 0x78)  /* Core2 FIQ Source */
+#define C3_FIQSOURCE  HWREG32(PER_BASE_40000000 + 0x7C)  /* Core3 FIQ Source */
+#define CORE_IRQSOURCE(n)     HWREG32(PER_BASE_40000000 + 0x60+ n*0x4)
+#define CORE_FIQSOURCE(n)     HWREG32(PER_BASE_40000000 + 0x70+ n*0x4)
+
+#define CORE_MAILBOX3_SET(n) HWREG32(PER_BASE_40000000 + 0x8C + n*0x10)
+#define CORE_MAILBOX3_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xCC + n*0x10)
+#define CORE_MAILBOX2_SET(n) HWREG32(PER_BASE_40000000 + 0x88 + n*0x10)
+#define CORE_MAILBOX2_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC8 + n*0x10)
+#define CORE_MAILBOX1_SET(n) HWREG32(PER_BASE_40000000 + 0x84 + n*0x10)
+#define CORE_MAILBOX1_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC4 + n*0x10)
+#define CORE_MAILBOX0_SET(n) HWREG32(PER_BASE_40000000 + 0x80 + n*0x10)
+#define CORE_MAILBOX0_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC0 + n*0x10)
+
+/* For SMP IPI use MailBox0 */
+#define IPI_MAILBOX_SET  CORE_MAILBOX0_SET
+#define IPI_MAILBOX_CLEAR     CORE_MAILBOX0_CLEAR
+#define IPI_MAILBOX_INT_MASK (0x01)
+
+enum spi_bit_order
+{
+    BCM283X_SPI_BIT_ORDER_LSBFIRST = 0,  /*!< LSB First */
+    BCM283X_SPI_BIT_ORDER_MSBFIRST = 1   /*!< MSB First */
+};
+
+enum spi_mode
+{
+    BCM283X_SPI_MODE0 = 0,  /*!< CPOL = 0, CPHA = 0 */
+    BCM283X_SPI_MODE1 = 1,  /*!< CPOL = 0, CPHA = 1 */
+    BCM283X_SPI_MODE2 = 2,  /*!< CPOL = 1, CPHA = 0 */
+    BCM283X_SPI_MODE3 = 3   /*!< CPOL = 1, CPHA = 1 */
+};
+
+enum spi_chip_select
+{
+    BCM283X_SPI_CS0 = 0,     /*!< Chip Select 0 */
+    BCM283X_SPI_CS1 = 1,     /*!< Chip Select 1 */
+    BCM283X_SPI_CS2 = 2,     /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */
+    BCM283X_SPI_CS_NONE = 3  /*!< No CS, control it yourself */
+};
+
+enum spi_clock_divider
+{
+    BCM283X_SPI_CLOCK_DIVIDER_65536 = 0,       /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_32768 = 32768,   /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_16384 = 16384,   /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_8192 = 8192,    /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_4096 = 4096,    /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_2048 = 2048,    /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_1024 = 1024,    /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_512  = 512,     /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_256  = 256,     /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_128  = 128,     /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_64   = 64,      /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_32   = 32,      /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_16   = 16,      /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_8    = 8,       /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_4    = 4,       /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */
+    BCM283X_SPI_CLOCK_DIVIDER_2    = 2,       /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/
+    BCM283X_SPI_CLOCK_DIVIDER_1    = 1 /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */
+};
+
+/*redefine for raspi*/
+typedef gpio_function_select raspi_pin_select;
+typedef enum
+{
+    RPI_GPIO_P1_01 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_02 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_03 = BCM_GPIO_PIN_2,
+    RPI_GPIO_P1_04 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_05 = BCM_GPIO_PIN_3,
+    RPI_GPIO_P1_06 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_07 = BCM_GPIO_PIN_4,
+    RPI_GPIO_P1_08 = BCM_GPIO_PIN_14,
+    RPI_GPIO_P1_09 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_10 = BCM_GPIO_PIN_15,
+    RPI_GPIO_P1_11 = BCM_GPIO_PIN_17,
+    RPI_GPIO_P1_12 = BCM_GPIO_PIN_18,
+    RPI_GPIO_P1_13 = BCM_GPIO_PIN_27,
+    RPI_GPIO_P1_14 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_15 = BCM_GPIO_PIN_22,
+    RPI_GPIO_P1_16 = BCM_GPIO_PIN_23,
+    RPI_GPIO_P1_17 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_18 = BCM_GPIO_PIN_24,
+    RPI_GPIO_P1_19 = BCM_GPIO_PIN_10,
+    RPI_GPIO_P1_20 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_21 = BCM_GPIO_PIN_9,
+    RPI_GPIO_P1_22 = BCM_GPIO_PIN_25,
+    RPI_GPIO_P1_23 = BCM_GPIO_PIN_11,
+    RPI_GPIO_P1_24 = BCM_GPIO_PIN_8,
+    RPI_GPIO_P1_25 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_26 = BCM_GPIO_PIN_7,
+    RPI_GPIO_P1_27 = BCM_GPIO_PIN_0,
+    RPI_GPIO_P1_28 = BCM_GPIO_PIN_1,
+    RPI_GPIO_P1_29 = BCM_GPIO_PIN_5,
+    RPI_GPIO_P1_30 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_31 = BCM_GPIO_PIN_6,
+    RPI_GPIO_P1_32 = BCM_GPIO_PIN_12,
+    RPI_GPIO_P1_33 = BCM_GPIO_PIN_13,
+    RPI_GPIO_P1_34 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_35 = BCM_GPIO_PIN_19,
+    RPI_GPIO_P1_36 = BCM_GPIO_PIN_16,
+    RPI_GPIO_P1_37 = BCM_GPIO_PIN_26,
+    RPI_GPIO_P1_38 = BCM_GPIO_PIN_20,
+    RPI_GPIO_P1_39 = BCM_GPIO_PIN_NULL,
+    RPI_GPIO_P1_40 = BCM_GPIO_PIN_21,
+} raspi_gpio_pin;
+
+typedef enum
+{
+    BCM283X_I2C_CLOCK_DIVIDER_2500  = 2500,      /* 2500 = 10us = 100 kHz */
+    BCM283X_I2C_CLOCK_DIVIDER_626   = 626,       /* 622 = 2.504us = 399.3610 kHz */
+    BCM283X_I2C_CLOCK_DIVIDER_150   = 150,       /* 150 = 60ns = 1.666 MHz (default at reset) */
+    BCM283X_I2C_CLOCK_DIVIDER_148   = 148 /* 148 = 59ns = 1.689 MHz */
+} i2c_clock_divider;
+
+typedef enum
+{
+    BCM283X_I2C_REASON_OK    = 0x00,      /* Success */
+    BCM283X_I2C_REASON_ERROR_NACK   = 0x01,      /* Received a NACK */
+    BCM283X_I2C_REASON_ERROR_CLKT   = 0x02,      /* Received Clock Stretch Timeout */
+    BCM283X_I2C_REASON_ERROR_DATA   = 0x04       /* Not all data is sent / received */
+} i2c_reason_codes;
+
+#endif

BIN
bsp/raspberry-pi/raspi3-32/figures/GPIO-Pinout-Diagram-2.png


BIN
bsp/raspberry-pi/raspi3-32/figures/raspberrypi-console.png


BIN
bsp/raspberry-pi/raspi3-32/figures/raspi3_b.jpg


BIN
bsp/raspberry-pi/raspi3-32/figures/raspi3_f.jpg


+ 149 - 0
bsp/raspberry-pi/raspi3-32/link.lds

@@ -0,0 +1,149 @@
+/*
+ * File      : link.lds
+ * COPYRIGHT (C) 2017, 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:
+ * 2017-5-30     bernard       first version
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+
+SECTIONS
+{
+    . = 0x00008000;
+    . = ALIGN(4);
+    .text :
+    {
+        *(.vectors)
+        *(.text)                        /* remaining code */
+        *(.text.*)                      /* remaining code */
+
+        *(.rodata)                      /* read-only data (constants) */
+        *(.rodata*)
+        *(.glue_7)
+        *(.glue_7t)
+        *(.gnu.linkonce.t*)
+
+        /* section information for finsh shell */
+        . = ALIGN(4);
+        __fsymtab_start = .;
+        KEEP(*(FSymTab))
+        __fsymtab_end = .;
+        . = ALIGN(4);
+        __vsymtab_start = .;
+        KEEP(*(VSymTab))
+        __vsymtab_end = .;
+        . = ALIGN(4);
+
+        /* section information for initial. */
+        . = ALIGN(4);
+        __rt_init_start = .;
+        KEEP(*(SORT(.rti_fn*)))
+        __rt_init_end = .;
+        . = ALIGN(4);
+
+        . = ALIGN(4);
+        _etext = .;
+    }
+
+    .eh_frame_hdr :
+    {
+         *(.eh_frame_hdr)
+         *(.eh_frame_entry)
+    }
+    .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+
+    . = ALIGN(4);
+    .data :
+    {
+     *(.data)
+     *(.data.*)
+
+     *(.data1)
+     *(.data1.*)
+
+     . = ALIGN(8);
+     _gp = ABSOLUTE(.);     /* Base of small data */
+
+     *(.sdata)
+     *(.sdata.*)
+    }
+
+    . = ALIGN(4);
+    .ctors :
+    {
+        PROVIDE(__ctors_start__ = .);
+        KEEP(*(SORT(.ctors.*)))
+        KEEP(*(.ctors))
+        PROVIDE(__ctors_end__ = .);
+    }
+
+    .dtors :
+    {
+        PROVIDE(__dtors_start__ = .);
+        KEEP(*(SORT(.dtors.*)))
+        KEEP(*(.dtors))
+        PROVIDE(__dtors_end__ = .);
+    }
+
+    . = ALIGN(4);
+    .bss :
+    {
+        PROVIDE(__bss_start = .);
+        *(.bss)
+        *(.bss.*)
+        *(.dynbss)
+        *(COMMON)
+        PROVIDE(__bss_end = .);
+    }
+    _end = .;
+
+    /* Stabs debugging sections.  */
+    .stab          0 : { *(.stab) }
+    .stabstr       0 : { *(.stabstr) }
+    .stab.excl     0 : { *(.stab.excl) }
+    .stab.exclstr  0 : { *(.stab.exclstr) }
+    .stab.index    0 : { *(.stab.index) }
+    .stab.indexstr 0 : { *(.stab.indexstr) }
+    .comment       0 : { *(.comment) }
+    /* DWARF debug sections.
+     * Symbols in the DWARF debugging sections are relative to the beginning
+     * of the section so we begin them at 0.  */
+    /* DWARF 1 */
+    .debug          0 : { *(.debug) }
+    .line           0 : { *(.line) }
+    /* GNU DWARF 1 extensions */
+    .debug_srcinfo  0 : { *(.debug_srcinfo) }
+    .debug_sfnames  0 : { *(.debug_sfnames) }
+    /* DWARF 1.1 and DWARF 2 */
+    .debug_aranges  0 : { *(.debug_aranges) }
+    .debug_pubnames 0 : { *(.debug_pubnames) }
+    /* DWARF 2 */
+    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+    .debug_abbrev   0 : { *(.debug_abbrev) }
+    .debug_line     0 : { *(.debug_line) }
+    .debug_frame    0 : { *(.debug_frame) }
+    .debug_str      0 : { *(.debug_str) }
+    .debug_loc      0 : { *(.debug_loc) }
+    .debug_macinfo  0 : { *(.debug_macinfo) }
+    /* SGI/MIPS DWARF 2 extensions */
+    .debug_weaknames 0 : { *(.debug_weaknames) }
+    .debug_funcnames 0 : { *(.debug_funcnames) }
+    .debug_typenames 0 : { *(.debug_typenames) }
+    .debug_varnames  0 : { *(.debug_varnames) }
+}

+ 391 - 0
bsp/raspberry-pi/raspi3-32/rtconfig.h

@@ -0,0 +1,391 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* Automatically generated file; DO NOT EDIT. */
+/* RT-Thread Project Configuration */
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+/* RT_USING_ARCH_DATA_TYPE is not set */
+#define RT_USING_SMP
+#define RT_CPUS_NR 4
+#define RT_ALIGN_SIZE 4
+/* RT_THREAD_PRIORITY_8 is not set */
+#define RT_THREAD_PRIORITY_32
+/* RT_THREAD_PRIORITY_256 is not set */
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 100
+#define RT_USING_OVERFLOW_CHECK
+#define RT_USING_HOOK
+#define RT_USING_IDLE_HOOK
+#define RT_IDLE_HOOK_LIST_SIZE 4
+#define IDLE_THREAD_STACK_SIZE 256
+/* RT_USING_TIMER_SOFT is not set */
+#define RT_DEBUG
+#define RT_DEBUG_COLOR
+/* RT_DEBUG_INIT_CONFIG is not set */
+/* RT_DEBUG_THREAD_CONFIG is not set */
+/* RT_DEBUG_SCHEDULER_CONFIG is not set */
+/* RT_DEBUG_IPC_CONFIG is not set */
+/* RT_DEBUG_TIMER_CONFIG is not set */
+/* RT_DEBUG_IRQ_CONFIG is not set */
+/* RT_DEBUG_MEM_CONFIG is not set */
+/* RT_DEBUG_SLAB_CONFIG is not set */
+/* RT_DEBUG_MEMHEAP_CONFIG is not set */
+/* RT_DEBUG_MODULE_CONFIG is not set */
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+/* RT_USING_SIGNALS is not set */
+
+/* Memory Management */
+
+#define RT_USING_MEMPOOL
+#define RT_USING_MEMHEAP
+/* RT_USING_NOHEAP is not set */
+#define RT_USING_SMALL_MEM
+/* RT_USING_SLAB is not set */
+/* RT_USING_MEMHEAP_AS_HEAP is not set */
+#define RT_USING_MEMTRACE
+#define RT_USING_HEAP
+
+/* Kernel Device Object */
+
+#define RT_USING_DEVICE
+#define RT_USING_DEVICE_OPS
+/* RT_USING_INTERRUPT_INFO is not set */
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 128
+#define RT_CONSOLE_DEVICE_NAME "uart1"
+#define RT_VER_NUM 0x40002
+#define ARCH_ARM
+/* RT_USING_CPU_FFS is not set */
+#define ARCH_ARM_CORTEX_A
+#define ARCH_ARM_CORTEX_A7
+/* ARCH_CPU_STACK_GROWS_UPWARD is not set */
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 2048
+#define RT_MAIN_THREAD_PRIORITY 10
+
+/* C++ features */
+
+/* RT_USING_CPLUSPLUS is not set */
+
+/* Command shell */
+
+#define RT_USING_FINSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_USING_DESCRIPTION
+/* FINSH_ECHO_DISABLE_DEFAULT is not set */
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 4096
+#define FINSH_CMD_SIZE 80
+/* FINSH_USING_AUTH is not set */
+#define FINSH_USING_MSH
+#define FINSH_USING_MSH_DEFAULT
+#define FINSH_USING_MSH_ONLY
+#define FINSH_ARG_MAX 10
+
+/* Device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_WORKDIR
+#define DFS_FILESYSTEMS_MAX 2
+#define DFS_FILESYSTEM_TYPES_MAX 2
+#define DFS_FD_MAX 16
+/* RT_USING_DFS_MNTTABLE is not set */
+#define RT_USING_DFS_ELMFAT
+
+/* elm-chan's FatFs, Generic FAT Filesystem Module */
+
+#define RT_DFS_ELM_CODE_PAGE 437
+#define RT_DFS_ELM_WORD_ACCESS
+/* RT_DFS_ELM_USE_LFN_0 is not set */
+/* RT_DFS_ELM_USE_LFN_1 is not set */
+/* RT_DFS_ELM_USE_LFN_2 is not set */
+#define RT_DFS_ELM_USE_LFN_3
+#define RT_DFS_ELM_USE_LFN 3
+#define RT_DFS_ELM_MAX_LFN 255
+#define RT_DFS_ELM_DRIVES 2
+#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
+/* RT_DFS_ELM_USE_ERASE is not set */
+#define RT_DFS_ELM_REENTRANT
+#define RT_USING_DFS_DEVFS
+/* RT_USING_DFS_ROMFS is not set */
+/* RT_USING_DFS_RAMFS is not set */
+/* RT_USING_DFS_UFFS is not set */
+/* RT_USING_DFS_JFFS2 is not set */
+
+/* Device Drivers */
+
+#define RT_USING_DEVICE_IPC
+#define RT_PIPE_BUFSZ 512
+/* RT_USING_SYSTEM_WORKQUEUE is not set */
+#define RT_USING_SERIAL
+/* RT_SERIAL_USING_DMA is not set */
+#define RT_SERIAL_RB_BUFSZ 64
+/* RT_USING_CAN is not set */
+#define RT_USING_HWTIMER
+/* RT_USING_CPUTIME is not set */
+#define RT_USING_I2C
+/* RT_USING_I2C_BITOPS is not set */
+#define RT_USING_PIN
+/* RT_USING_ADC is not set */
+/* RT_USING_PWM is not set */
+/* RT_USING_MTD_NOR is not set */
+/* RT_USING_MTD_NAND is not set */
+/* RT_USING_PM is not set */
+#define RT_USING_RTC
+/* RT_USING_ALARM is not set */
+/* RT_USING_SOFT_RTC is not set */
+#define RT_USING_SDIO
+#define RT_SDIO_STACK_SIZE 512
+#define RT_SDIO_THREAD_PRIORITY 15
+#define RT_MMCSD_STACK_SIZE 1024
+#define RT_MMCSD_THREAD_PREORITY 22
+#define RT_MMCSD_MAX_PARTITION 16
+/* RT_SDIO_DEBUG is not set */
+#define RT_USING_SPI
+/* RT_USING_QSPI is not set */
+/* RT_USING_SPI_MSD is not set */
+/* RT_USING_SFUD is not set */
+/* RT_USING_ENC28J60 is not set */
+/* RT_USING_SPI_WIFI is not set */
+#define RT_USING_WDT
+/* RT_USING_AUDIO is not set */
+/* RT_USING_SENSOR is not set */
+/* RT_USING_TOUCH is not set */
+/* RT_USING_HWCRYPTO is not set */
+/* RT_USING_WIFI is not set */
+
+/* Using USB */
+
+/* RT_USING_USB_HOST is not set */
+/* RT_USING_USB_DEVICE is not set */
+
+/* POSIX layer and C standard library */
+
+#define RT_USING_LIBC
+/* RT_USING_PTHREADS is not set */
+#define RT_USING_POSIX
+/* RT_USING_POSIX_MMAP is not set */
+/* RT_USING_POSIX_TERMIOS is not set */
+/* RT_USING_POSIX_AIO is not set */
+/* RT_USING_MODULE is not set */
+
+/* Network */
+
+/* Socket abstraction layer */
+
+/* RT_USING_SAL is not set */
+
+/* Network interface device */
+
+/* RT_USING_NETDEV is not set */
+
+/* light weight TCP/IP stack */
+
+/* RT_USING_LWIP is not set */
+
+/* AT commands */
+
+/* RT_USING_AT is not set */
+
+/* VBUS(Virtual Software BUS) */
+
+/* RT_USING_VBUS is not set */
+
+/* Utilities */
+
+/* RT_USING_RYM is not set */
+/* RT_USING_ULOG is not set */
+/* RT_USING_UTEST is not set */
+/* RT_USING_LWP is not set */
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+/* PKG_USING_PAHOMQTT is not set */
+/* PKG_USING_WEBCLIENT is not set */
+/* PKG_USING_WEBNET is not set */
+/* PKG_USING_MONGOOSE is not set */
+/* PKG_USING_WEBTERMINAL is not set */
+/* PKG_USING_CJSON is not set */
+/* PKG_USING_JSMN is not set */
+/* PKG_USING_LIBMODBUS is not set */
+/* PKG_USING_FREEMODBUS is not set */
+/* PKG_USING_LJSON is not set */
+/* PKG_USING_EZXML is not set */
+/* PKG_USING_NANOPB is not set */
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+/* PKG_USING_WLANMARVELL is not set */
+
+/* Wiced WiFi */
+
+/* PKG_USING_WLAN_WICED is not set */
+/* PKG_USING_RW007 is not set */
+/* PKG_USING_COAP is not set */
+/* PKG_USING_NOPOLL is not set */
+/* PKG_USING_NETUTILS is not set */
+/* PKG_USING_AT_DEVICE is not set */
+/* PKG_USING_ATSRV_SOCKET is not set */
+/* PKG_USING_WIZNET is not set */
+
+/* IoT Cloud */
+
+/* PKG_USING_ONENET is not set */
+/* PKG_USING_GAGENT_CLOUD is not set */
+/* PKG_USING_ALI_IOTKIT is not set */
+/* PKG_USING_AZURE is not set */
+/* PKG_USING_TENCENT_IOTHUB is not set */
+/* PKG_USING_NIMBLE is not set */
+/* PKG_USING_OTA_DOWNLOADER is not set */
+/* PKG_USING_IPMSG is not set */
+/* PKG_USING_LSSDP is not set */
+/* PKG_USING_AIRKISS_OPEN is not set */
+/* PKG_USING_LIBRWS is not set */
+/* PKG_USING_TCPSERVER is not set */
+
+/* security packages */
+
+/* PKG_USING_MBEDTLS is not set */
+/* PKG_USING_libsodium is not set */
+/* PKG_USING_TINYCRYPT is not set */
+
+/* language packages */
+
+/* PKG_USING_LUA is not set */
+/* PKG_USING_JERRYSCRIPT is not set */
+/* PKG_USING_MICROPYTHON is not set */
+
+/* multimedia packages */
+
+/* PKG_USING_OPENMV is not set */
+/* PKG_USING_MUPDF is not set */
+/* PKG_USING_STEMWIN is not set */
+
+/* tools packages */
+
+/* PKG_USING_CMBACKTRACE is not set */
+/* PKG_USING_EASYFLASH is not set */
+/* PKG_USING_EASYLOGGER is not set */
+/* PKG_USING_SYSTEMVIEW is not set */
+/* PKG_USING_RDB is not set */
+/* PKG_USING_QRCODE is not set */
+/* PKG_USING_ULOG_EASYFLASH is not set */
+/* PKG_USING_ADBD is not set */
+
+/* system packages */
+
+/* PKG_USING_GUIENGINE is not set */
+/* PKG_USING_PERSIMMON is not set */
+/* PKG_USING_CAIRO is not set */
+/* PKG_USING_PIXMAN is not set */
+/* PKG_USING_LWEXT4 is not set */
+/* PKG_USING_PARTITION is not set */
+/* PKG_USING_FAL is not set */
+/* PKG_USING_SQLITE is not set */
+/* PKG_USING_RTI is not set */
+/* PKG_USING_LITTLEVGL2RTT is not set */
+/* PKG_USING_CMSIS is not set */
+/* PKG_USING_DFS_YAFFS is not set */
+/* PKG_USING_LITTLEFS is not set */
+/* PKG_USING_THREAD_POOL is not set */
+
+/* peripheral libraries and drivers */
+
+/* PKG_USING_SENSORS_DRIVERS is not set */
+/* PKG_USING_REALTEK_AMEBA is not set */
+/* PKG_USING_SHT2X is not set */
+/* PKG_USING_STM32_SDIO is not set */
+/* PKG_USING_ICM20608 is not set */
+/* PKG_USING_U8G2 is not set */
+/* PKG_USING_BUTTON is not set */
+/* PKG_USING_PCF8574 is not set */
+/* PKG_USING_SX12XX is not set */
+/* PKG_USING_SIGNAL_LED is not set */
+/* PKG_USING_LEDBLINK is not set */
+/* PKG_USING_WM_LIBRARIES is not set */
+/* PKG_USING_KENDRYTE_SDK is not set */
+/* PKG_USING_INFRARED is not set */
+/* PKG_USING_ROSSERIAL is not set */
+/* PKG_USING_AT24CXX is not set */
+/* PKG_USING_MOTIONDRIVER2RTT is not set */
+/* PKG_USING_AD7746 is not set */
+/* PKG_USING_PCA9685 is not set */
+/* PKG_USING_I2C_TOOLS is not set */
+/* PKG_USING_NRF24L01 is not set */
+/* PKG_USING_TOUCH_DRIVERS is not set */
+/* PKG_USING_LCD_DRIVERS is not set */
+
+/* miscellaneous packages */
+
+/* PKG_USING_LIBCSV is not set */
+/* PKG_USING_OPTPARSE is not set */
+/* PKG_USING_FASTLZ is not set */
+/* PKG_USING_MINILZO is not set */
+/* PKG_USING_QUICKLZ is not set */
+/* PKG_USING_MULTIBUTTON is not set */
+/* PKG_USING_CANFESTIVAL is not set */
+/* PKG_USING_ZLIB is not set */
+/* PKG_USING_DSTR is not set */
+/* PKG_USING_TINYFRAME is not set */
+/* PKG_USING_KENDRYTE_DEMO is not set */
+/* PKG_USING_DIGITALCTRL is not set */
+
+/* samples: kernel and components samples */
+
+/* PKG_USING_KERNEL_SAMPLES is not set */
+/* PKG_USING_FILESYSTEM_SAMPLES is not set */
+/* PKG_USING_NETWORK_SAMPLES is not set */
+/* PKG_USING_PERIPHERAL_SAMPLES is not set */
+/* PKG_USING_HELLO is not set */
+/* PKG_USING_VI is not set */
+/* PKG_USING_NNOM is not set */
+/* PKG_USING_LIBANN is not set */
+#define BCM2836_SOC
+
+/* Hardware Drivers Config */
+
+/* BCM Peripheral Drivers */
+
+#define BSP_USING_UART
+/* RT_USING_UART0 is not set */
+#define RT_USING_UART1
+#define BSP_USING_PIN
+#define BSP_USING_SYSTIMER
+#define RT_USING_SYSTIMER1
+#define RT_USING_SYSTIMER3
+#define BSP_USING_I2C
+#define BSP_USING_I2C0
+#define BSP_USING_I2C1
+#define BSP_USING_SPI
+#define BSP_USING_SPI0_BUS
+#define BSP_USING_SPI0_DEVICE0
+#define BSP_USING_SPI0_DEVICE1
+#define BSP_USING_WDT
+#define BSP_USING_RTC
+/* BSP_USING_ALARM is not set */
+#define BSP_USING_SDIO
+#define BSP_USING_SDIO0
+#define BSP_USING_HDMI
+
+#endif

+ 52 - 0
bsp/raspberry-pi/raspi3-32/rtconfig.py

@@ -0,0 +1,52 @@
+import os
+
+# toolchains options
+ARCH        ='armv8-a'
+CPU         ='cortex-a53'
+CROSS_TOOL  ='gcc'
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = r'../../..'
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+
+PLATFORM    = 'gcc'
+EXEC_PATH   = r'/usr/bin'
+if os.getenv('RTT_EXEC_PATH'):
+    EXEC_PATH = os.getenv('RTT_EXEC_PATH')
+
+BUILD = 'debug'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX = 'arm-none-eabi-'
+    CC      = PREFIX + 'gcc'
+    CXX     = PREFIX + 'g++'
+    AS      = PREFIX + 'gcc'
+    AR      = PREFIX + 'ar'
+    LINK    = PREFIX + 'gcc'
+    TARGET_EXT = 'elf'
+    SIZE    = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY  = PREFIX + 'objcopy'
+
+    DEVICE = ' -mfloat-abi=softfp -march=armv8-a -mtune=cortex-a53 -ftree-vectorize -ffast-math'
+    CFLAGS = DEVICE + ' -Wall'
+    AFLAGS = ' -c' + ' -march=armv8-a -x assembler-with-cpp -D__ASSEMBLY__'
+    LFLAGS  = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
+    CPATH   = ''
+    LPATH   = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -gdwarf-2'
+        AFLAGS += ' -gdwarf-2'
+    else:
+        CFLAGS += ' -O2'
+
+    CXXFLAGS = CFLAGS
+
+DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
+POST_ACTION = OBJCPY + ' -O binary $TARGET kernel7.img\n' + SIZE + ' $TARGET \n'

+ 418 - 0
bsp/raspberry-pi/raspi3-64/.config

@@ -0,0 +1,418 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# RT-Thread Project Configuration
+#
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+# CONFIG_RT_USING_SMP is not set
+CONFIG_RT_ALIGN_SIZE=4
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=100
+CONFIG_RT_USING_OVERFLOW_CHECK=y
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=2048
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=2048
+CONFIG_RT_DEBUG=y
+CONFIG_RT_DEBUG_COLOR=y
+# CONFIG_RT_DEBUG_INIT_CONFIG is not set
+# CONFIG_RT_DEBUG_THREAD_CONFIG is not set
+# CONFIG_RT_DEBUG_SCHEDULER_CONFIG is not set
+# CONFIG_RT_DEBUG_IPC_CONFIG is not set
+# CONFIG_RT_DEBUG_TIMER_CONFIG is not set
+# CONFIG_RT_DEBUG_IRQ_CONFIG is not set
+# CONFIG_RT_DEBUG_MEM_CONFIG is not set
+# CONFIG_RT_DEBUG_SLAB_CONFIG is not set
+# CONFIG_RT_DEBUG_MEMHEAP_CONFIG is not set
+# CONFIG_RT_DEBUG_MODULE_CONFIG is not set
+
+#
+# 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=y
+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=y
+CONFIG_RT_USING_HEAP=y
+
+#
+# Kernel Device Object
+#
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_DEVICE_OPS=y
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=128
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart1"
+CONFIG_RT_VER_NUM=0x40002
+CONFIG_ARCH_CPU_64BIT=y
+CONFIG_ARCH_ARM=y
+# CONFIG_RT_USING_CPU_FFS is not set
+CONFIG_ARCH_ARM_CORTEX_AARCH64=y
+CONFIG_ARCH_ARM_CORTEX_A53=y
+# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=2048
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+
+#
+# C++ features
+#
+# CONFIG_RT_USING_CPLUSPLUS is not set
+
+#
+# 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_ECHO_DISABLE_DEFAULT is not set
+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=y
+CONFIG_FINSH_ARG_MAX=10
+
+#
+# Device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FILESYSTEMS_MAX=2
+CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
+CONFIG_DFS_FD_MAX=16
+# CONFIG_RT_USING_DFS_MNTTABLE is not set
+# CONFIG_RT_USING_DFS_ELMFAT is not set
+CONFIG_RT_USING_DFS_DEVFS=y
+# 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 is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_PIPE_BUFSZ=512
+# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set
+CONFIG_RT_USING_SERIAL=y
+# CONFIG_RT_SERIAL_USING_DMA is not set
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# 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 is not set
+CONFIG_RT_USING_PIN=y
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_PM is not set
+# CONFIG_RT_USING_RTC is not set
+# CONFIG_RT_USING_SDIO is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH is not set
+# CONFIG_RT_USING_HWCRYPTO is not set
+# 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 is not set
+CONFIG_RT_USING_POSIX=y
+# CONFIG_RT_USING_POSIX_MMAP is not set
+# CONFIG_RT_USING_POSIX_TERMIOS is not set
+# CONFIG_RT_USING_POSIX_AIO is not set
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Network
+#
+
+#
+# Socket abstraction layer
+#
+# CONFIG_RT_USING_SAL is not set
+
+#
+# Network interface device
+#
+# CONFIG_RT_USING_NETDEV is not set
+
+#
+# light weight TCP/IP stack
+#
+# CONFIG_RT_USING_LWIP is not set
+
+#
+# AT commands
+#
+# CONFIG_RT_USING_AT is not set
+
+#
+# VBUS(Virtual Software BUS)
+#
+# CONFIG_RT_USING_VBUS is not set
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+# CONFIG_RT_USING_UTEST is not set
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET 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_JSMN is not set
+# CONFIG_PKG_USING_LIBMODBUS is not set
+# CONFIG_PKG_USING_FREEMODBUS 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
+# CONFIG_PKG_USING_RW007 is not set
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_PPP_DEVICE is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOTHUB is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER is not set
+# CONFIG_PKG_USING_PROTOBUF_C is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT 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_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+
+#
+# multimedia packages
+#
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+# CONFIG_PKG_USING_WAVPLAYER is not set
+# CONFIG_PKG_USING_TJPGD is not set
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ADBD is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_DHRYSTONE is not set
+
+#
+# system packages
+#
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_FAL is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_LITTLEVGL2RTT is not set
+# CONFIG_PKG_USING_CMSIS is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+# CONFIG_PKG_USING_ROBOTS is not set
+
+#
+# peripheral libraries and drivers
+#
+# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_WM_LIBRARIES is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_AGILE_BUTTON is not set
+# CONFIG_PKG_USING_AGILE_LED is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
+# CONFIG_PKG_USING_LCD_DRIVERS is not set
+# CONFIG_PKG_USING_MAX17048 is not set
+# CONFIG_PKG_USING_RPLIDAR is not set
+
+#
+# miscellaneous packages
+#
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+# CONFIG_PKG_USING_ZLIB is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+# CONFIG_PKG_USING_UPACKER is not set
+# CONFIG_PKG_USING_UPARAM is not set
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_UKAL is not set
+CONFIG_BCM2836_SOC=y
+# CONFIG_BSP_SUPPORT_FPU is not set
+
+#
+# Hardware Drivers Config
+#
+
+#
+# BCM Peripheral Drivers
+#
+CONFIG_BSP_USING_UART=y
+# CONFIG_RT_USING_UART0 is not set
+CONFIG_RT_USING_UART1=y
+CONFIG_BSP_USING_PIN=y
+# CONFIG_BSP_USING_SYSTIMER is not set
+# CONFIG_BSP_USING_I2C is not set
+# CONFIG_BSP_USING_SPI is not set
+# CONFIG_BSP_USING_WDT is not set
+# CONFIG_BSP_USING_RTC is not set
+# CONFIG_BSP_USING_SDIO is not set
+
+#
+# Board Peripheral Drivers
+#
+# CONFIG_BSP_USING_HDMI is not set

File diff suppressed because it is too large
+ 125 - 0
bsp/raspberry-pi/raspi3-64/.cproject


+ 54 - 0
bsp/raspberry-pi/raspi3-64/.project

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+  <name>raspi2</name>
+  <comment />
+  <projects>
+	</projects>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+      <triggers>clean,full,incremental,</triggers>
+      <arguments>
+			</arguments>
+    </buildCommand>
+    <buildCommand>
+      <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+      <triggers>full,incremental,</triggers>
+      <arguments>
+			</arguments>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.cdt.core.cnature</nature>
+    <nature>org.eclipse.cdt.core.rttnature</nature>
+    <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+    <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+  </natures>
+  <linkedResources>
+    <link>
+      <name>rt-thread</name>
+      <type>2</type>
+      <locationURI>virtual:/virtual</locationURI>
+    </link>
+    <link>
+      <name>rt-thread/components</name>
+      <type>2</type>
+      <locationURI>$%7BPARENT-2-PROJECT_LOC%7D/components</locationURI>
+    </link>
+    <link>
+      <name>rt-thread/include</name>
+      <type>2</type>
+      <locationURI>$%7BPARENT-2-PROJECT_LOC%7D/include</locationURI>
+    </link>
+    <link>
+      <name>rt-thread/libcpu</name>
+      <type>2</type>
+      <locationURI>$%7BPARENT-2-PROJECT_LOC%7D/libcpu</locationURI>
+    </link>
+    <link>
+      <name>rt-thread/src</name>
+      <type>2</type>
+      <locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
+    </link>
+  </linkedResources>
+</projectDescription>

+ 29 - 0
bsp/raspberry-pi/raspi3-64/Kconfig

@@ -0,0 +1,29 @@
+mainmenu "RT-Thread Project 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"
+
+config BCM2836_SOC
+    bool
+    select ARCH_ARM_CORTEX_A53
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    select ARCH_CPU_64BIT
+    default y
+
+source "driver/Kconfig"

+ 100 - 0
bsp/raspberry-pi/raspi3-64/README.md

@@ -0,0 +1,100 @@
+# Raspberry PI 3-64板级支持包说明
+
+## 1. 简介
+
+树莓派由注册于英国的慈善组织“Raspberry Pi 基金会”开发,莓派3有三个发行版本:
+
+* B : 4核 Broadcom BCM2837 (ARMv8-A) 1.2GHz,双核VideoCore IV GPU,1GB内存,100 Base-T Ethernet
+* B+: 4核 Broadcom BCM2837B0 Cortex-A53 (ARMv8) 1.4GHz, 1GB LPDDR2 SDRAM, GigaE over USB 2.0
+* A+: 4核 Broadcom BCM2837B0 Cortex-A53 (ARMv8) 1.4GHz, 512MB LPDDR2 SDRAM
+
+这份RT-Thread BSP是针对 Raspberry Pi 3 64位模式的一份移植,树莓派价格便宜, 使用者甚众,是研究和运行RT-Thread的可选平台之一。
+
+
+## 2. 编译说明
+
+### 2.1 Window上的环境搭建
+
+Windows环境下推荐使用[env工具][1]进行编译。
+
+首先下载Linux上的gcc工具,版本为gcc-arm-8.3选择aarch64-elf就可以。
+
+将推荐将gcc解压到`\env\tools\gnu_gcc\arm_gcc`目录下。
+
+接着修改`bsp\raspberry-pi\raspi3-64\rtconfig.py`
+
+修改路径:
+
+```
+EXEC_PATH = r'E:/env_released_1.1.2/env/tools/gnu_gcc/arm_gcc/gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf/bin'
+```
+
+然后在`bsp\raspberry-pi\raspi3-64\`下输入scons编译即可。
+
+### 2.2 Linux上的环境搭建
+
+Linux下推荐使用[gcc工具][2]。Linux版本下gcc版本可采用`gcc-arm-8.3-2019.03-x86_64-aarch64-elf`。
+
+直接进入`bsp\raspberry-pi\raspi3-64`,输入scons编译即可。
+
+
+## 3. 执行
+
+### 3.1 下载[raspbian镜像][3],生成可以运行的raspbian SD卡
+
+Windows下,去[etcher.io][4]下载etcher,这是个可以烧写img的工具
+
+解开下载的镜像文件, linux下使用如下的命令
+
+```
+unzip 2018-06-27-raspbian-stretch-lite.zip
+```
+
+准备一张空SD卡,linux环境下,插入电脑并执行
+
+```
+sudo dd if=2018-06-27-raspbian-stretch-lite.img of=/dev/xxx bs=32M conv=fsync
+```
+
+**注意: /dev/xxx 要换成真实环境中的SD卡所在设置,千万不要弄错。**
+
+Windows环境下,执行etcher选择解压后的2018-06-27-raspbian-stretch-lite.img文件和SD卡就可以开始烧写了。
+
+最后把kernel8.img放入SD boot分区,删除其它 kernel*.img。
+
+### 3.2 准备好串口线
+
+目前版本是使用raspi3的 GPIO 14, GPIO 15来作路口输出,连线情况如下图所示(图片中的板子是pi2,GPIO引脚是一样的):
+
+![raspi2](figures/raspi_uart.png)
+
+串口参数: 115200 8N1 ,硬件和软件流控为关。
+
+按上面的方法做好SD卡后,插入树莓派,通电可以在串口上看到如下所示的输出信息:
+
+```text
+ heap: 0x00020b20 - 0x00400000
+
+ \ | /
+- RT -     Thread Operating System
+ / | \     3.1.0 build Aug 23 2019
+ 2006 - 2019 Copyright by rt-thread team
+Hello RT-Thread!
+msh >
+```
+
+## 4. 支持情况
+
+| 驱动 | 支持情况  |  备注  |
+| ------ | ----  | :------:  |
+| UART | 支持 | UART0|
+
+## 5. 联系人信息
+
+维护人:[bernard][5]
+
+[1]: https://www.rt-thread.org/page/download.html
+[2]: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
+[3]: https://downloads.raspberrypi.org/raspbian_lite_latest
+[4]: https://etcher.io
+[5]: https://github.com/BernardXiong

+ 14 - 0
bsp/raspberry-pi/raspi3-64/SConscript

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

+ 30 - 0
bsp/raspberry-pi/raspi3-64/SConstruct

@@ -0,0 +1,30 @@
+import os
+import sys
+import rtconfig
+
+from rtconfig import RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+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)
+env['ASCOM'] = env['ASPPCOM']
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
+
+# make a building
+DoBuilding(TARGET, objs)
+

+ 9 - 0
bsp/raspberry-pi/raspi3-64/applications/SConscript

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

+ 19 - 0
bsp/raspberry-pi/raspi3-64/applications/main.c

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30     bernard       the first version
+ */
+
+#include <rtthread.h>
+
+int main(int argc, char** argv)
+{
+    rt_kprintf("Hi, this is RT-Thread!!\n");
+
+    return 0;
+}
+

+ 16 - 0
bsp/raspberry-pi/raspi3-64/applications/mnt.c

@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30     bernard       the first version
+ */
+
+#include <rtthread.h>
+
+int mnt_init(void)
+{
+    return 0;
+}

+ 45 - 0
bsp/raspberry-pi/raspi3-64/applications/test/gpio.h

@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 bzt (bztsrc@github)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#define MMIO_BASE       0x3F000000
+
+#define GPFSEL0         ((volatile unsigned int*)(MMIO_BASE+0x00200000))
+#define GPFSEL1         ((volatile unsigned int*)(MMIO_BASE+0x00200004))
+#define GPFSEL2         ((volatile unsigned int*)(MMIO_BASE+0x00200008))
+#define GPFSEL3         ((volatile unsigned int*)(MMIO_BASE+0x0020000C))
+#define GPFSEL4         ((volatile unsigned int*)(MMIO_BASE+0x00200010))
+#define GPFSEL5         ((volatile unsigned int*)(MMIO_BASE+0x00200014))
+#define GPSET0          ((volatile unsigned int*)(MMIO_BASE+0x0020001C))
+#define GPSET1          ((volatile unsigned int*)(MMIO_BASE+0x00200020))
+#define GPCLR0          ((volatile unsigned int*)(MMIO_BASE+0x00200028))
+#define GPLEV0          ((volatile unsigned int*)(MMIO_BASE+0x00200034))
+#define GPLEV1          ((volatile unsigned int*)(MMIO_BASE+0x00200038))
+#define GPEDS0          ((volatile unsigned int*)(MMIO_BASE+0x00200040))
+#define GPEDS1          ((volatile unsigned int*)(MMIO_BASE+0x00200044))
+#define GPHEN0          ((volatile unsigned int*)(MMIO_BASE+0x00200064))
+#define GPHEN1          ((volatile unsigned int*)(MMIO_BASE+0x00200068))
+#define GPPUD           ((volatile unsigned int*)(MMIO_BASE+0x00200094))
+#define GPPUDCLK0       ((volatile unsigned int*)(MMIO_BASE+0x00200098))
+#define GPPUDCLK1       ((volatile unsigned int*)(MMIO_BASE+0x0020009C))

+ 103 - 0
bsp/raspberry-pi/raspi3-64/applications/test/uart.c

@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2018 bzt (bztsrc@github)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "gpio.h"
+
+/* Auxilary mini UART registers */
+#define AUX_ENABLE      ((volatile unsigned int*)(MMIO_BASE+0x00215004))
+#define AUX_MU_IO       ((volatile unsigned int*)(MMIO_BASE+0x00215040))
+#define AUX_MU_IER      ((volatile unsigned int*)(MMIO_BASE+0x00215044))
+#define AUX_MU_IIR      ((volatile unsigned int*)(MMIO_BASE+0x00215048))
+#define AUX_MU_LCR      ((volatile unsigned int*)(MMIO_BASE+0x0021504C))
+#define AUX_MU_MCR      ((volatile unsigned int*)(MMIO_BASE+0x00215050))
+#define AUX_MU_LSR      ((volatile unsigned int*)(MMIO_BASE+0x00215054))
+#define AUX_MU_MSR      ((volatile unsigned int*)(MMIO_BASE+0x00215058))
+#define AUX_MU_SCRATCH  ((volatile unsigned int*)(MMIO_BASE+0x0021505C))
+#define AUX_MU_CNTL     ((volatile unsigned int*)(MMIO_BASE+0x00215060))
+#define AUX_MU_STAT     ((volatile unsigned int*)(MMIO_BASE+0x00215064))
+#define AUX_MU_BAUD     ((volatile unsigned int*)(MMIO_BASE+0x00215068))
+
+/**
+ * Set baud rate and characteristics (115200 8N1) and map to GPIO
+ */
+void uart_init()
+{
+    register unsigned int r;
+
+    /* initialize UART */
+    *AUX_ENABLE |=1;       // enable UART1, AUX mini uart
+    *AUX_MU_CNTL = 0;
+    *AUX_MU_LCR = 3;       // 8 bits
+    *AUX_MU_MCR = 0;
+    *AUX_MU_IER = 0;
+    *AUX_MU_IIR = 0xc6;    // disable interrupts
+    *AUX_MU_BAUD = 270;    // 115200 baud
+    /* map UART1 to GPIO pins */
+    r=*GPFSEL1;
+    r&=~((7<<12)|(7<<15)); // gpio14, gpio15
+    r|=(2<<12)|(2<<15);    // alt5
+    *GPFSEL1 = r;
+    *GPPUD = 0;            // enable pins 14 and 15
+    r=150; while(r--) { asm volatile("nop"); }
+    *GPPUDCLK0 = (1<<14)|(1<<15);
+    r=150; while(r--) { asm volatile("nop"); }
+    *GPPUDCLK0 = 0;        // flush GPIO setup
+    *AUX_MU_CNTL = 3;      // enable Tx, Rx
+}
+
+/**
+ * Send a character
+ */
+void uart_send(unsigned int c) {
+    /* wait until we can send */
+    do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x20));
+    /* write the character to the buffer */
+    *AUX_MU_IO=c;
+}
+
+/**
+ * Receive a character
+ */
+char uart_getc() {
+    char r;
+    /* wait until something is in the buffer */
+    do{asm volatile("nop");}while(!(*AUX_MU_LSR&0x01));
+    /* read it and return */
+    r=(char)(*AUX_MU_IO);
+    /* convert carrige return to newline */
+    return r=='\r'?'\n':r;
+}
+
+/**
+ * Display a string
+ */
+void uart_puts(char *s) {
+    while(*s) {
+        /* convert newline to carrige return + newline */
+        if(*s=='\n')
+            uart_send('\r');
+        uart_send(*s++);
+    }
+}

+ 29 - 0
bsp/raspberry-pi/raspi3-64/applications/test/uart.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2018 bzt (bztsrc@github)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+void uart_init();
+void uart_send(unsigned int c);
+char uart_getc();
+void uart_puts(char *s);

+ 112 - 0
bsp/raspberry-pi/raspi3-64/driver/Kconfig

@@ -0,0 +1,112 @@
+
+config BSP_SUPPORT_FPU
+    bool "Using Float"
+    default n
+
+menu "Hardware Drivers Config"
+    menu "BCM Peripheral Drivers"
+        menuconfig BSP_USING_UART
+            bool "Using UART"
+            select RT_USING_SERIAL
+            default y
+
+            if BSP_USING_UART
+                config RT_USING_UART0
+                bool "Enabel UART 0"
+                default y
+
+                config RT_USING_UART1
+                    bool "Enabel UART 1"
+                    default n
+            endif
+         
+        config BSP_USING_PIN
+            bool "Using PIN"
+            select RT_USING_PIN
+            default y
+
+        menuconfig BSP_USING_SYSTIMER
+            bool "Enable SYSTIMER"
+            select BSP_USING_SYSTIMER
+            default n
+
+        if  BSP_USING_SYSTIMER
+            config RT_USING_SYSTIMER1
+                bool "Enable sys timer1"
+                default n
+            config RT_USING_SYSTIMER3
+                bool "Enable sys timer3"
+                default n
+        endif
+
+        menuconfig BSP_USING_I2C
+            bool "Enable I2C"
+            select RT_USING_I2C
+            default n
+
+        if BSP_USING_I2C
+            config BSP_USING_I2C0
+                bool "Enable I2C0"
+                default n
+            config BSP_USING_I2C1
+                bool "Enable I2C1"
+                default n
+        endif
+
+        menuconfig BSP_USING_SPI
+            bool "Enable SPI"
+            select RT_USING_SPI
+            default n
+        
+        if BSP_USING_SPI
+            config BSP_USING_SPI0
+                bool "Enable SPI0"
+                default n
+            config BSP_USING_SPI1
+                bool "Enable SPI1"
+                default n
+        endif
+
+        config BSP_USING_WDT
+            bool "Enable WDT"
+            select RT_USING_WDT
+            default n
+
+        menuconfig BSP_USING_RTC
+            bool "Enable RTC"
+            select RT_USING_RTC
+            default n
+
+        if BSP_USING_RTC
+            config BSP_USING_ALARM
+                bool "Enable Alarm"
+                select RT_USING_ALARM
+                default n
+        endif
+        
+        menuconfig BSP_USING_SDIO
+            bool "Enable SDIO"
+            select RT_USING_SDIO
+            default n
+
+        if BSP_USING_SDIO
+            config BSP_USING_SDIO0
+                bool "Enable SDIO0"
+                select RT_USING_SDIO
+                default n
+        endif
+    endmenu
+
+    menu "Board Peripheral Drivers"
+        menuconfig BSP_USING_HDMI
+            bool "Enable HDMI"
+            select BSP_USING_SPI
+            default n
+
+        if BSP_USING_HDMI
+            config BSP_USING_HDMI_DISPLAY
+                bool "HDMI DISPLAY"
+                default n
+        endif
+    endmenu
+endmenu

+ 32 - 0
bsp/raspberry-pi/raspi3-64/driver/SConscript

@@ -0,0 +1,32 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Split('''
+board.c
+bcm283x.c
+drv_uart.c
+mbox.c
+''')
+CPPPATH = [cwd]
+
+if GetDepend('BSP_USING_SYSTIMER'):
+    src += ['drv_timer.c']
+if GetDepend('BSP_USING_PIN'):
+    src += ['drv_gpio.c']
+if GetDepend('BSP_USING_I2C'):
+    src += ['drv_i2c.c']
+if GetDepend('BSP_USING_WDT'):
+    src += ['drv_wdt.c']
+if GetDepend('BSP_USING_SPI'):
+    src += ['drv_spi.c']
+if GetDepend('BSP_USING_SDIO'):
+    src += ['drv_sdio.c']
+if GetDepend('BSP_USING_RTC'):
+    src += ['drv_rtc.c']
+if GetDepend('BSP_USING_HDMI'):
+    src += ['drv_fb.c']
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 575 - 0
bsp/raspberry-pi/raspi3-64/driver/bcm283x.c

@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "bcm283x.h"
+
+rt_uint32_t bcm283x_peri_read(volatile rt_ubase_t addr)
+{
+    rt_uint32_t ret;
+    __sync_synchronize();
+    ret = HWREG32(addr);
+    __sync_synchronize();
+    return ret;
+}
+
+rt_uint32_t bcm283x_peri_read_nb(volatile rt_ubase_t addr)
+{
+    return HWREG32(addr);
+}
+
+void bcm283x_peri_write(volatile rt_ubase_t addr, rt_uint32_t value)
+{
+    __sync_synchronize();
+    HWREG32(addr) = value;
+    __sync_synchronize();
+}
+
+void bcm283x_peri_write_nb(volatile rt_ubase_t addr, rt_uint32_t value)
+{
+    HWREG32(addr) = value;
+}
+
+void bcm283x_peri_set_bits(volatile rt_ubase_t addr, rt_uint32_t value, rt_uint32_t mask)
+{
+    rt_uint32_t v = bcm283x_peri_read(addr);
+    v = (v & ~mask) | (value & mask);
+    bcm283x_peri_write(addr, v);
+}
+
+void bcm283x_gpio_fsel(rt_uint8_t pin, rt_uint8_t mode)
+{
+    volatile rt_ubase_t addr = (BCM283X_GPIO_BASE + BCM283X_GPIO_GPFSEL0 + (pin / 10) * 4);
+    rt_uint8_t   shift = (pin % 10) * 3;
+    rt_uint32_t  mask = BCM283X_GPIO_FSEL_MASK << shift;
+    rt_uint32_t  value = mode << shift;
+
+    bcm283x_peri_set_bits(addr, value, mask);
+}
+
+void bcm283x_gpio_set(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPSET0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    bcm283x_peri_write(addr, 1 << shift);
+}
+
+void bcm283x_gpio_clr(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPCLR0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    bcm283x_peri_write(addr, 1 << shift);
+}
+
+rt_uint8_t bcm283x_gpio_lev(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM2835_GPIO_GPLEV0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = bcm283x_peri_read(addr);
+    return (value & (1 << shift)) ? HIGH : LOW;
+}
+
+rt_uint8_t bcm283x_gpio_eds(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = bcm283x_peri_read(addr);
+    return (value & (1 << shift)) ? HIGH : LOW;
+}
+
+/* Write a 1 to clear the bit in EDS */
+void bcm283x_gpio_set_eds(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_write(addr, value);
+}
+
+/* Rising edge detect enable */
+void bcm283x_gpio_ren(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+
+void bcm283x_gpio_clr_ren(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* Falling edge detect enable */
+void bcm283x_gpio_fen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+void bcm283x_gpio_clr_fen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* High detect enable */
+void bcm283x_gpio_hen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+
+void bcm283x_gpio_clr_hen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* Low detect enable */
+void bcm283x_gpio_len(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+
+void bcm283x_gpio_clr_len(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* Async rising edge detect enable */
+void bcm283x_gpio_aren(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+void bcm283x_gpio_clr_aren(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* Async falling edge detect enable */
+void bcm283x_gpio_afen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, value, value);
+}
+void bcm283x_gpio_clr_afen(rt_uint8_t pin)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    rt_uint32_t value = 1 << shift;
+    bcm283x_peri_set_bits(addr, 0, value);
+}
+
+/* Set pullup/down */
+void bcm283x_gpio_pud(rt_uint8_t pud)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUD;
+    bcm283x_peri_write(addr, pud);
+}
+
+/* Pullup/down clock
+// Clocks the value of pud into the GPIO pin
+*/
+void bcm283x_gpio_pudclk(rt_uint8_t pin, rt_uint8_t on)
+{
+    volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUDCLK0 + (pin / 32) * 4;
+    rt_uint8_t shift = pin % 32;
+    bcm283x_peri_write(addr, (on? 1 : 0) << shift);
+}
+
+void bcm283x_gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud)
+{
+    bcm283x_gpio_pud(pud);
+    bcm283x_clo_delayMicros(10);
+
+    bcm283x_gpio_pudclk(pin, 1);
+    bcm283x_clo_delayMicros(10);
+
+    bcm283x_gpio_pud(BCM283X_GPIO_PUD_OFF);
+    bcm283x_gpio_pudclk(pin, 0);
+}
+
+
+void bcm283x_gpio_write(rt_uint8_t pin, rt_uint8_t val)
+{
+    if (val)
+        bcm283x_gpio_set(pin);
+    else
+        bcm283x_gpio_clr(pin);
+}
+
+rt_uint64_t bcm283x_st_read(void)
+{
+    volatile rt_ubase_t addr;
+    rt_uint32_t hi, lo;
+    rt_uint64_t st;
+
+    addr = BCM283X_ST_BASE + BCM283X_ST_CHI;
+    hi = bcm283x_peri_read(addr);
+
+    addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
+    lo = bcm283x_peri_read(addr);
+
+    addr = BCM283X_ST_BASE + BCM283X_ST_CHI;
+    st = bcm283x_peri_read(addr);
+
+    /* Test for overflow */
+    if (st == hi)
+    {
+        rt_kprintf(">> 1crash???\n");
+        st <<= 32;
+        st += lo;
+        rt_kprintf(">> 2crash!!!\n");
+    }
+    else
+    {
+        st <<= 32;
+        addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
+        st += bcm283x_peri_read(addr);
+    }
+    return st;
+}
+
+/* microseconds */
+void bcm283x_delayMicroseconds(rt_uint64_t micros)
+{
+    rt_uint64_t start;
+
+    start =  bcm283x_st_read();
+    rt_kprintf("bcm283x_st_read result: %d\n", start);
+
+    /* Not allowed to access timer registers (result is not as precise)*/
+    if (start==0)
+        return;
+
+    bcm283x_st_delay(start, micros);
+}
+
+void bcm283x_clo_delayMicros(rt_uint32_t micros)
+{
+    volatile rt_uint32_t addr;
+    rt_uint32_t compare;
+
+    addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
+    compare = bcm283x_peri_read(addr) + micros;
+    while(bcm283x_peri_read(addr) < compare);
+}
+
+void bcm283x_st_delay(rt_uint64_t offset_micros, rt_uint64_t micros)
+{
+    rt_uint64_t compare = offset_micros + micros;
+    while(bcm283x_st_read() < compare);
+}
+
+
+/* Read an number of bytes from I2C */
+rt_uint8_t bcm283x_i2c_read(rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len)
+{
+    volatile rt_uint32_t  dlen    = base + BCM283X_BSC_DLEN;
+    volatile rt_uint32_t  fifo    = base + BCM283X_BSC_FIFO;
+    volatile rt_uint32_t  status  = base + BCM283X_BSC_S;
+    volatile rt_uint32_t  control = base + BCM283X_BSC_C;
+
+    rt_uint32_t remaining = len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
+    /* Clear Status */
+    bcm283x_peri_write_nb(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
+    /* Set Data Length */
+    bcm283x_peri_write_nb(dlen, len);
+    /* Start read */
+    bcm283x_peri_write_nb(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST | BCM283X_BSC_C_READ);
+
+    /* wait for transfer to complete */
+    while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE))
+    {
+        /* we must empty the FIFO as it is populated and not use any delay */
+        while (remaining && bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD)
+        {
+            /* Read from FIFO, no barrier */
+            buf[i] = bcm283x_peri_read_nb(fifo);
+            i++;
+            remaining--;
+        }
+    }
+
+    /* transfer has finished - grab any remaining stuff in FIFO */
+    while (remaining && (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD))
+    {
+        /* Read from FIFO, no barrier */
+        buf[i] = bcm283x_peri_read_nb(fifo);
+        i++;
+        remaining--;
+    }
+
+    /* Received a NACK */
+    if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+
+    /* Received Clock Stretch Timeout */
+    else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+
+    /* Not all data is received */
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+
+    bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
+
+    return reason;
+}
+
+int bcm283x_i2c_begin(int no)
+{
+    if (0 == no)
+    {
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */
+    }
+    else
+    {
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_ALT0); /* SDA */
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_ALT0); /* SCL */
+    }
+    return 0;
+}
+
+void bcm283x_i2c_end(int no)
+{
+    if (0 == no)
+    {
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */
+    }
+    else
+    {
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_INPT); /* SDA */
+        bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_INPT); /* SCL */
+    }
+}
+
+void bcm283x_i2c_setSlaveAddress(int no, rt_uint8_t saddr)
+{
+    volatile rt_uint32_t addr;
+    if (0 == no)
+        addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_A;
+    else
+        addr = PER_BASE + BCM283X_BSC1_BASE + BCM283X_BSC_A;
+
+    bcm283x_peri_write(addr, saddr);
+}
+
+void bcm283x_i2c_setClockDivider(int no, rt_uint16_t divider)
+{
+    volatile rt_uint32_t addr;
+    if (0 == no)
+        addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV;
+    else
+        addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV;
+    bcm283x_peri_write(addr, divider);
+}
+
+void bcm283x_i2c_set_baudrate(int no, rt_uint32_t baudrate)
+{
+    rt_uint32_t divider;
+    divider = (BCM283X_CORE_CLK_HZ / baudrate) & 0xFFFE;
+    bcm283x_i2c_setClockDivider(no, (rt_uint16_t)divider);
+}
+
+/* Writes an number of bytes to I2C */
+rt_uint8_t bcm283x_i2c_write(rt_uint32_t base, const rt_uint8_t * buf, rt_uint32_t len)
+{
+    volatile rt_uint32_t dlen    = base + BCM283X_BSC_DLEN;
+    volatile rt_uint32_t fifo    = base + BCM283X_BSC_FIFO;
+    volatile rt_uint32_t status  = base + BCM283X_BSC_S;
+    volatile rt_uint32_t control = base + BCM283X_BSC_C;
+
+    rt_uint32_t remaining = len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
+    /* Clear Status */
+    bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
+    /* Set Data Length */
+    bcm283x_peri_write(dlen, len);
+    /* pre populate FIFO with max buffer */
+    while(remaining && (i < BCM283X_BSC_FIFO_SIZE))
+    {
+        bcm283x_peri_write_nb(fifo, buf[i]);
+        i++;
+        remaining--;
+    }
+
+    /* Enable device and start transfer */
+    bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST);
+
+    /* Transfer is over when BCM2835_BSC_S_DONE */
+    while(!(bcm283x_peri_read(status) & BCM283X_BSC_S_DONE))
+    {
+        while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_TXD))
+        {
+        /* Write to FIFO */
+            bcm283x_peri_write(fifo, buf[i]);
+            i++;
+            remaining--;
+        }
+    }
+
+    /* Received a NACK */
+    if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+
+    /* Received Clock Stretch Timeout */
+    else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+
+    /* Not all data is sent */
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+
+    bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
+
+    return reason;
+}
+
+rt_uint8_t bcm283x_i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len)
+{
+    volatile rt_uint32_t dlen    = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DLEN;
+    volatile rt_uint32_t fifo    = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_FIFO;
+    volatile rt_uint32_t status  = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_S;
+    volatile rt_uint32_t control = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_C;
+
+    rt_uint32_t remaining = cmds_len;
+    rt_uint32_t i = 0;
+    rt_uint8_t reason = BCM283X_I2C_REASON_OK;
+
+    /* Clear FIFO */
+    bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
+
+    /* Clear Status */
+    bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
+
+    /* Set Data Length */
+    bcm283x_peri_write(dlen, cmds_len);
+
+    /* pre populate FIFO with max buffer */
+    while(remaining && (i < BCM283X_BSC_FIFO_SIZE))
+    {
+        bcm283x_peri_write_nb(fifo, cmds[i]);
+        i++;
+        remaining--;
+    }
+
+    /* Enable device and start transfer */
+    bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST);
+
+    /* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */
+    while (!(bcm283x_peri_read(status) & BCM283X_BSC_S_TA))
+    {
+        /* Linux may cause us to miss entire transfer stage */
+        if (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE)
+            break;
+    }
+
+    remaining = buf_len;
+    i = 0;
+
+    /* Send a repeated start with read bit set in address */
+    bcm283x_peri_write(dlen, buf_len);
+    bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST  | BCM283X_BSC_C_READ);
+
+    /* Wait for write to complete and first byte back. */
+    bcm283x_clo_delayMicros(100);
+
+    /* wait for transfer to complete */
+    while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE))
+    {
+        /* we must empty the FIFO as it is populated and not use any delay */
+        while (remaining && bcm283x_peri_read(status) & BCM283X_BSC_S_RXD)
+        {
+            /* Read from FIFO, no barrier */
+            buf[i] = bcm283x_peri_read_nb(fifo);
+            i++;
+            remaining--;
+        }
+    }
+
+    /* transfer has finished - grab any remaining stuff in FIFO */
+    while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_RXD))
+    {
+        /* Read from FIFO */
+        buf[i] = bcm283x_peri_read(fifo);
+        i++;
+        remaining--;
+    }
+
+    /* Received a NACK */
+    if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_NACK;
+    }
+
+    /* Received Clock Stretch Timeout */
+    else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_CLKT;
+    }
+
+    /* Not all data is sent */
+    else if (remaining)
+    {
+        reason = BCM283X_I2C_REASON_ERROR_DATA;
+    }
+
+    bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
+
+    return reason;
+}

+ 641 - 0
bsp/raspberry-pi/raspi3-64/driver/bcm283x.h

@@ -0,0 +1,641 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2019-07-15     RT-Thread    the first version
+ * 2019-07-29     zdzn         add macro definition
+ */
+
+#ifndef __BCM283X_H__
+#define __BCM283X_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#define PER_BASE    		(0x3F000000)
+#define PER_BASE_40000000 	(0x40000000)
+
+
+#define HIGH 0x1
+#define LOW  0x0
+
+#define BCM283X_CORE_CLK_HZ		250000000	/* 50 MHz */
+
+/*! Offsets for the bases of various peripherals within the peripherals block
+ *   Base Address of the System Timer registers
+ */
+/*! Base Address of the Pads registers */
+#define BCM283X_GPIO_PADS               0x100000
+/*! Base Address of the Clock/timer registers */
+#define BCM283X_CLOCK_BASE              0x101000
+/*! Base Address of the GPIO registers */
+//#define BCM283X_GPIO_BASE               0x200000
+/*! Base Address of the SPI0 registers */
+#define BCM283X_SPI0_BASE               0x204000
+/*! Base Address of the PWM registers */
+#define BCM283X_GPIO_PWM                0x20C000
+/*! Base Address of the AUX registers */
+#define BCM283X_AUX_BASE				0x215000
+/*! Base Address of the AUX_SPI1 registers */
+#define BCM283X_SPI1_BASE				0x215080
+/*! Base Address of the AUX_SPI2 registers */
+#define BCM283X_SPI2_BASE				0x2150C0
+
+/*! Base Address of the BSC0 registers */
+#define BCM283X_BSC0_BASE 				0x205000    //for i2c0
+/*! Base Address of the BSC1 registers */
+#define BCM283X_BSC1_BASE				0x804000    //for i2c1
+/*! Base Address of the BSC1 registers */
+#define BCM283X_BSC2_BASE				0x805000    //for hdmi i2c not use 
+
+/*
+ *  GPIO
+ */
+#define GPIO_BASE       (PER_BASE + 0x200000)
+#define GPIO_GPFSEL0    HWREG32(GPIO_BASE + 0x0000)  /* GPIO Function Select 0 32bit R/W */
+#define GPIO_GPFSEL1    HWREG32(GPIO_BASE + 0x0004)  /* GPIO Function Select 1 32bit R/W */
+#define GPIO_GPFSEL2    HWREG32(GPIO_BASE + 0x0008)  /* GPIO Function Select 2 32bit R/W */
+#define GPIO_GPFSEL4    HWREG32(GPIO_BASE + 0x0010)  /* GPIO Function Select 4 32bit R/W */
+#define GPIO_GPFSEL5    HWREG32(GPIO_BASE + 0x0014)  /* GPIO Function Select 5 32bit R/W */
+#define GPIO_GPSET0     HWREG32(GPIO_BASE + 0x001C)
+#define GPIO_GPSET1     HWREG32(GPIO_BASE + 0x0020)
+#define GPIO_GPCLR0     HWREG32(GPIO_BASE + 0x0028)
+#define GPIO_GPCLR1     HWREG32(GPIO_BASE + 0x002C)
+#define GPIO_GPEDS0     HWREG32(GPIO_BASE + 0x0040)  /* GPIO Pin Event Detect Status */
+#define GPIO_GPEDS1     HWREG32(GPIO_BASE + 0x0044)
+#define GPIO_GPREN0     HWREG32(GPIO_BASE + 0x004c)  /* GPIO Pin Rising Edge Detect Enable */
+#define GPIO_GPREN1     HWREG32(GPIO_BASE + 0x0050)
+#define GPIO_GPFEN0     HWREG32(GPIO_BASE + 0x0058) /* GPIO Pin Falling Edge Detect Enable */
+#define GPIO_GPFEN1     HWREG32(GPIO_BASE + 0x005C) 
+#define GPIO_GPHEN0     HWREG32(GPIO_BASE + 0x0064) /* GPIO Pin High Detect Enable  */
+#define GPIO_GPHEN1     HWREG32(GPIO_BASE + 0x0068)
+#define GPIO_GPLEN0     HWREG32(GPIO_BASE + 0x0070) /* GPIO Pin Low Detect Enable 0 */
+#define GPIO_GPLEN1     HWREG32(GPIO_BASE + 0x0074)
+#define GPIO_GPAREN0    HWREG32(GPIO_BASE + 0x007C) /* GPIO Pin Async. Rising Edge Detect */
+#define GPIO_GPAREN1    HWREG32(GPIO_BASE + 0x0080)
+#define GPIO_GPAFEN0    HWREG32(GPIO_BASE + 0x0088) /* GPIO Pin Async. Falling Edge Detect */
+#define GPIO_GPAFEN1    HWREG32(GPIO_BASE + 0x008C)
+#define GPIO_GPPUD      HWREG32(GPIO_BASE + 0x0094)  /* GPIO Pin Pull-up/down Enable */
+#define GPIO_GPPUDCLK0  HWREG32(GPIO_BASE + 0x0098)  /* GPIO Pin Pull-up/down Enable Clock 0 */
+#define GPIO_GPPUDCLK1  HWREG32(GPIO_BASE + 0x009C)  /* GPIO Pin Pull-up/down Enable Clock 1 */
+
+#define BCM283X_GPIO_BASE       (PER_BASE + 0x200000)
+#define BCM283X_GPIO_GPFSEL0    (0x0000)  /* GPIO Function Select 0 32bit R/W */
+#define BCM283X_GPIO_GPFSEL1    (0x0004)  /* GPIO Function Select 1 32bit R/W */
+#define BCM283X_GPIO_GPFSEL2    (0x0008)  /* GPIO Function Select 2 32bit R/W */
+#define BCM283X_GPIO_GPFSEL4    (0x0010)  /* GPIO Function Select 4 32bit R/W */
+#define BCM283X_GPIO_GPFSEL5    (0x0014)  /* GPIO Function Select 5 32bit R/W */
+#define BCM283X_GPIO_GPSET0     (0x001C)
+#define BCM283X_GPIO_GPSET1     (0x0020)
+#define BCM283X_GPIO_GPCLR0     (0x0028)
+#define BCM283X_GPIO_GPCLR1     (0x002C)
+#define BCM2835_GPIO_GPLEV0     (0x0034)  /*!< GPIO Pin Level 0 */
+#define BCM2835_GPIO_GPLEV1     (0x0038)  /*!< GPIO Pin Level 1 */
+#define BCM283X_GPIO_GPEDS0     (0x0040)  /* GPIO Pin Event Detect Status */
+#define BCM283X_GPIO_GPEDS1     (0x0044)
+#define BCM283X_GPIO_GPREN0     (0x004c)  /* GPIO Pin Rising Edge Detect Enable */
+#define BCM283X_GPIO_GPREN1     (0x0050)
+#define BCM283X_GPIO_GPFEN0     (0x0058) /* GPIO Pin Falling Edge Detect Enable */
+#define BCM283X_GPIO_GPFEN1     (0x005C)
+#define BCM283X_GPIO_GPHEN0     (0x0064) /* GPIO Pin High Detect Enable  */
+#define BCM283X_GPIO_GPHEN1     (0x0068)
+#define BCM283X_GPIO_GPLEN0     (0x0070) /* GPIO Pin Low Detect Enable 0 */
+#define BCM283X_GPIO_GPLEN1     (0x0074)
+#define BCM283X_GPIO_GPAREN0    (0x007C) /* GPIO Pin Async. Rising Edge Detect */
+#define BCM283X_GPIO_GPAREN1    (0x0080)
+#define BCM283X_GPIO_GPAFEN0    (0x0088) /* GPIO Pin Async. Falling Edge Detect */
+#define BCM283X_GPIO_GPAFEN1    (0x008C)
+#define BCM283X_GPIO_GPPUD      (0x0094)  /* GPIO Pin Pull-up/down Enable */
+#define BCM283X_GPIO_GPPUDCLK0  (0x0098)  /* GPIO Pin Pull-up/down Enable Clock 0 */
+#define BCM283X_GPIO_GPPUDCLK1  (0x009C)  /* GPIO Pin Pull-up/down Enable Clock 1 */
+
+enum gpio_function_select
+{
+    BCM283X_GPIO_FSEL_INPT  = 0x00,   /*!< Input 0b000 */
+    BCM283X_GPIO_FSEL_OUTP  = 0x01,   /*!< Output 0b001 */
+    BCM283X_GPIO_FSEL_ALT0  = 0x04,   /*!< Alternate function 0 0b100 */
+    BCM283X_GPIO_FSEL_ALT1  = 0x05,   /*!< Alternate function 1 0b101 */
+    BCM283X_GPIO_FSEL_ALT2  = 0x06,   /*!< Alternate function 2 0b110, */
+    BCM283X_GPIO_FSEL_ALT3  = 0x07,   /*!< Alternate function 3 0b111 */
+    BCM283X_GPIO_FSEL_ALT4  = 0x03,   /*!< Alternate function 4 0b011 */
+    BCM283X_GPIO_FSEL_ALT5  = 0x02,   /*!< Alternate function 5 0b010 */
+    BCM283X_GPIO_FSEL_MASK  = 0x07    /*!< Function select bits mask 0b111 */
+};
+
+enum gpio_pud_mode
+{
+    BCM283X_GPIO_PUD_OFF     = 0x00,   /*!< Off ? disable pull-up/down 0b00 */
+    BCM283X_GPIO_PUD_DOWN    = 0x01,   /*!< Enable Pull Down control 0b01 */
+    BCM283X_GPIO_PUD_UP      = 0x02    /*!< Enable Pull Up control 0b10  */
+};
+
+/* Defines for BSC I2C
+ * GPIO register offsets from BCM283X_BSC*_BASE.
+ * Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
+ */
+/* I2C Address Map offset address */
+#define BCM283X_BSC_C 			0x0000 /*!< BSC Master Control */
+#define BCM283X_BSC_S 			0x0004 /*!< BSC Master Status */
+#define BCM283X_BSC_DLEN		0x0008 /*!< BSC Master Data Length */
+#define BCM283X_BSC_A 			0x000c /*!< BSC Master Slave Address */
+#define BCM283X_BSC_FIFO		0x0010 /*!< BSC Master Data FIFO */
+#define BCM283X_BSC_DIV			0x0014 /*!< BSC Master Clock Divider */
+#define BCM283X_BSC_DEL			0x0018 /*!< BSC Master Data Delay */
+#define BCM283X_BSC_CLKT		0x001c /*!< BSC Master Clock Stretch Timeout */
+
+/* Register masks for C Register */
+#define BCM283X_BSC_C_I2CEN 		0x00008000 /*!< I2C Enable, 0 = disabled, 1 = enabled */
+#define BCM283X_BSC_C_INTR 		0x00000400 /*!< Interrupt on RX */
+#define BCM283X_BSC_C_INTT 		0x00000200 /*!< Interrupt on TX */
+#define BCM283X_BSC_C_INTD 		0x00000100 /*!< Interrupt on DONE */
+#define BCM283X_BSC_C_ST 		0x00000080 /*!< Start transfer, 1 = Start a new transfer */
+#define BCM283X_BSC_C_CLEAR_1 		0x00000020 /*!< Clear FIFO Clear */
+#define BCM283X_BSC_C_CLEAR_2 		0x00000010 /*!< Clear FIFO Clear */
+#define BCM283X_BSC_C_READ 		0x00000001 /*!<	Read transfer */
+
+/* Register masks for S Register */
+#define BCM283X_BSC_S_CLKT 		0x00000200 /*!< Clock stretch timeout */
+#define BCM283X_BSC_S_ERR 		0x00000100 /*!< ACK error */
+#define BCM283X_BSC_S_RXF 		0x00000080 /*!< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BCM283X_BSC_S_TXE 		0x00000040 /*!< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full */
+#define BCM283X_BSC_S_RXD 		0x00000020 /*!< RXD FIFO contains data */
+#define BCM283X_BSC_S_TXD 		0x00000010 /*!< TXD FIFO can accept data */
+#define BCM283X_BSC_S_RXR 		0x00000008 /*!< RXR FIFO needs reading (full) */
+#define BCM283X_BSC_S_TXW 		0x00000004 /*!< TXW FIFO needs writing (full) */
+#define BCM283X_BSC_S_DONE 		0x00000002 /*!< Transfer DONE */
+#define BCM283X_BSC_S_TA 		0x00000001 /*!< Transfer Active */
+
+#define BCM283X_BSC_FIFO_SIZE   	16  /*!< BSC FIFO size */
+
+enum  i2c_clock_divider
+{
+    BCM283X_I2C_CLOCK_DIVIDER_2500   = 2500,      /*!< 2500 = 10us = 100 kHz */
+    BCM283X_I2C_CLOCK_DIVIDER_626    = 626,       /*!< 622 = 2.504us = 399.3610 kHz */
+    BCM283X_I2C_CLOCK_DIVIDER_150    = 150,       /*!< 150 = 60ns = 1.666 MHz (default at reset) */
+    BCM283X_I2C_CLOCK_DIVIDER_148    = 148        /*!< 148 = 59ns = 1.689 MHz */
+};
+
+enum i2c_reason_codes
+{
+    BCM283X_I2C_REASON_OK   	     = 0x00,      /*!< Success */
+    BCM283X_I2C_REASON_ERROR_NACK    = 0x01,      /*!< Received a NACK */
+    BCM283X_I2C_REASON_ERROR_CLKT    = 0x02,      /*!< Received Clock Stretch Timeout */
+    BCM283X_I2C_REASON_ERROR_DATA    = 0x04       /*!< Not all data is sent / received */
+};
+
+/*
+ *  Interrupt Controler
+ */
+#define IRQ_BASE            (PER_BASE + 0xB200)
+#define IRQ_PEND_BASIC      HWREG32(IRQ_BASE + 0x00)
+#define IRQ_PEND1           HWREG32(IRQ_BASE + 0x04)
+#define IRQ_PEND2           HWREG32(IRQ_BASE + 0x08)
+#define IRQ_FIQ_CONTROL     HWREG32(IRQ_BASE + 0x0C)
+#define IRQ_ENABLE1         HWREG32(IRQ_BASE + 0x10)
+#define IRQ_ENABLE2         HWREG32(IRQ_BASE + 0x14)
+#define IRQ_ENABLE_BASIC    HWREG32(IRQ_BASE + 0x18)
+#define IRQ_DISABLE1        HWREG32(IRQ_BASE + 0x1C)
+#define IRQ_DISABLE2        HWREG32(IRQ_BASE + 0x20)
+#define IRQ_DISABLE_BASIC   HWREG32(IRQ_BASE + 0x24)
+
+/*
+ *  System Timer
+ */
+#define STIMER_BASE         (PER_BASE  + 0x3000)
+#define STIMER_CS           HWREG32(STIMER_BASE + 0x00)
+#define STIMER_CLO          HWREG32(STIMER_BASE + 0x04)
+#define STIMER_CHI          HWREG32(STIMER_BASE + 0x08)
+#define STIMER_C0           HWREG32(STIMER_BASE + 0x0C)
+#define STIMER_C1           HWREG32(STIMER_BASE + 0x10)
+#define STIMER_C2           HWREG32(STIMER_BASE + 0x14)
+#define STIMER_C3           HWREG32(STIMER_BASE + 0x18)
+
+/* Defines for ST */
+#define BCM283X_ST_BASE 		(PER_BASE  + 0x3000)
+#define BCM283X_ST_CS 			0x0000 /*!< System Timer Control/Status */
+#define BCM283X_ST_CLO 			0x0004 /*!< System Timer Counter Lower 32 bits */
+#define BCM283X_ST_CHI 			0x0008 /*!< System Timer Counter Upper 32 bits */
+#define BCM283X_ST_C0 			0x000C
+#define BCM283X_ST_C1 			0x0010
+#define BCM283X_ST_C2 			0x0014
+#define BCM283X_ST_C3 			0x0018
+
+/*
+ * ARM Timer
+ */
+#define ARM_TIMER_BASE		(PER_BASE + 0xB000)
+#define ARM_TIMER_LOAD		HWREG32(ARM_TIMER_BASE + 0x400)
+#define ARM_TIMER_VALUE		HWREG32(ARM_TIMER_BASE + 0x404)
+#define ARM_TIMER_CTRL		HWREG32(ARM_TIMER_BASE + 0x408)
+#define ARM_TIMER_IRQCLR	HWREG32(ARM_TIMER_BASE + 0x40C)
+#define ARM_TIMER_RAWIRQ	HWREG32(ARM_TIMER_BASE + 0x410)
+#define ARM_TIMER_MASKIRQ	HWREG32(ARM_TIMER_BASE + 0x414)
+#define ARM_TIMER_RELOAD	HWREG32(ARM_TIMER_BASE + 0x418)
+#define ARM_TIMER_PREDIV	HWREG32(ARM_TIMER_BASE + 0x41C)
+#define ARM_TIMER_CNTR		HWREG32(ARM_TIMER_BASE + 0x420)
+
+/*
+ *  Core Timer
+ */
+#define CTIMER_CTL          HWREG32(PER_BASE_40000000 + 0x00)  /* Control register */
+#define CTIMER_PRE          HWREG32(PER_BASE_40000000 + 0x08)  /* Core timer prescaler */
+#define CTIMER_LS32B        HWREG32(PER_BASE_40000000 + 0x1C)  /* Core timer access LS 32 bits */
+#define CTIMER_MS32B        HWREG32(PER_BASE_40000000 + 0x20)  /* Core timer access MS 32 bits */
+
+/*
+ *  ARM Core Timer
+ */
+#define C0TIMER_INTCTL      HWREG32(PER_BASE_40000000 + 0x40)  /* Core0 timers Interrupt control */
+#define C1TIMER_INTCTL      HWREG32(PER_BASE_40000000 + 0x44)  /* Core1 timers Interrupt control */
+#define C2TIMER_INTCTL      HWREG32(PER_BASE_40000000 + 0x48)  /* Core2 timers Interrupt control */
+#define C3TIMER_INTCTL      HWREG32(PER_BASE_40000000 + 0x4C)  /* Core3 timers Interrupt control */
+#define CORETIMER_INTCTL(n)      HWREG32(PER_BASE_40000000 + 0x40 + n*4)  /* Core3 timers Interrupt control */
+/*
+ *  ARM Core Mailbox interrupt
+ */
+#define C0MB_INTCTL         HWREG32(PER_BASE_40000000 + 0x50)  /* Core0 Mailboxes Interrupt control */
+#define C1MB_INTCTL         HWREG32(PER_BASE_40000000 + 0x54)  /* Core1 Mailboxes Interrupt control */
+#define C2MB_INTCTL         HWREG32(PER_BASE_40000000 + 0x58)  /* Core2 Mailboxes Interrupt control */
+#define C3MB_INTCTL         HWREG32(PER_BASE_40000000 + 0x5C)  /* Core3 Mailboxes Interrupt control */
+#define COREMB_INTCTL(n)    HWREG32(PER_BASE_40000000 + 0x50 + 4*n)  /* Core3 Mailboxes Interrupt control */
+/*
+ *  ARM Core IRQ/FIQ status
+ */
+#define C0_IRQSOURCE        HWREG32(PER_BASE_40000000 + 0x60)  /* Core0 IRQ Source */
+#define C1_IRQSOURCE        HWREG32(PER_BASE_40000000 + 0x64)  /* Core1 IRQ Source */
+#define C2_IRQSOURCE        HWREG32(PER_BASE_40000000 + 0x68)  /* Core2 IRQ Source */
+#define C3_IRQSOURCE        HWREG32(PER_BASE_40000000 + 0x6C)  /* Core3 IRQ Source */
+#define C0_FIQSOURCE        HWREG32(PER_BASE_40000000 + 0x70)  /* Core0 FIQ Source */
+#define C1_FIQSOURCE        HWREG32(PER_BASE_40000000 + 0x74)  /* Core1 FIQ Source */
+#define C2_FIQSOURCE        HWREG32(PER_BASE_40000000 + 0x78)  /* Core2 FIQ Source */
+#define C3_FIQSOURCE        HWREG32(PER_BASE_40000000 + 0x7C)  /* Core3 FIQ Source */
+#define CORE_IRQSOURCE(n)        HWREG32(PER_BASE_40000000 + 0x60+ n*0x4)
+#define CORE_FIQSOURCE(n)        HWREG32(PER_BASE_40000000 + 0x70+ n*0x4)
+
+#define CORE_MAILBOX3_SET(n)        HWREG32(PER_BASE_40000000 + 0x8C + n*0x10)
+#define CORE_MAILBOX3_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xCC + n*0x10)
+#define CORE_MAILBOX2_SET(n)        HWREG32(PER_BASE_40000000 + 0x88 + n*0x10)
+#define CORE_MAILBOX2_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC8 + n*0x10)
+#define CORE_MAILBOX1_SET(n)        HWREG32(PER_BASE_40000000 + 0x84 + n*0x10)
+#define CORE_MAILBOX1_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC4 + n*0x10)
+#define CORE_MAILBOX0_SET(n)        HWREG32(PER_BASE_40000000 + 0x80 + n*0x10)
+#define CORE_MAILBOX0_CLEAR(n)      HWREG32(PER_BASE_40000000 + 0xC0 + n*0x10)
+
+/* for smp ipi using mailbox0 */
+#define IPI_MAILBOX_SET   CORE_MAILBOX0_SET
+
+#define IPI_MAILBOX_CLEAR CORE_MAILBOX0_CLEAR
+#define IPI_MAILBOX_INT_MASK     (0x01)
+
+#define IRQ_ARM_TIMER           64
+#define IRQ_ARM_MAILBOX         65
+#define IRQ_ARM_DB0             66
+#define IRQ_ARM_DB1             67
+#define IRQ_ARM_GPU0_HALT       68
+#define IRQ_ARM_GPU1_HALT       69
+#define IRQ_ARM_ILLEGAL_ACC1    70
+#define IRQ_ARM_ILLEGAL_ACC0    71
+
+#define IRQ_SYSTIMER_MATCH_1    1
+#define IRQ_SYSTIMER_MATCH_3    3
+
+#define IRQ_AUX                 29
+#define IRQ_IIC_SPI_SLV         43
+#define IRQ_PWA0                45
+#define IRQ_PWA1                46
+#define IRQ_SMI                 48
+#define IRQ_GPIO0               49
+#define IRQ_GPIO1               50
+#define IRQ_GPIO2               51
+#define IRQ_GPIO3               52
+#define IRQ_IIC                 53
+#define IRQ_SPI                 54
+#define IRQ_PCM                 55
+#define IRQ_UART                57
+
+/* CLOCK */
+#define BCM283X_PLLA			0
+#define BCM283X_PLLB			1
+#define BCM283X_PLLC			2
+#define BCM283X_PLLD			3
+#define BCM283X_PLLH			4
+
+#define BCM283X_PLLA_CORE		5
+#define BCM283X_PLLA_PER		6
+#define BCM283X_PLLB_ARM		7
+#define BCM283X_PLLC_CORE0		8
+#define BCM283X_PLLC_CORE1		9
+#define BCM283X_PLLC_CORE2		10
+#define BCM283X_PLLC_PER		11
+#define BCM283X_PLLD_CORE		12
+#define BCM283X_PLLD_PER		13
+#define BCM283X_PLLH_RCAL		14
+#define BCM283X_PLLH_AUX		15
+#define BCM283X_PLLH_PIX		16
+
+#define BCM283X_CLOCK_TIMER		17
+#define BCM283X_CLOCK_OTP		18
+#define BCM283X_CLOCK_UART		19
+#define BCM283X_CLOCK_VPU		20
+#define BCM283X_CLOCK_V3D		21
+#define BCM283X_CLOCK_ISP		22
+#define BCM283X_CLOCK_H264		23
+#define BCM283X_CLOCK_VEC		24
+#define BCM283X_CLOCK_HSM		25
+#define BCM283X_CLOCK_SDRAM		26
+#define BCM283X_CLOCK_TSENS		27
+#define BCM283X_CLOCK_EMMC		28
+#define BCM283X_CLOCK_PERI_IMAGE	29
+#define BCM283X_CLOCK_COUNT		30
+
+#define CM_PASSWORD		0x5a000000
+
+#define CM_GNRICCTL		0x000
+#define CM_GNRICDIV		0x004
+#define CM_VPUCTL		0x008
+#define CM_VPUDIV		0x00c
+#define CM_SYSCTL		0x010
+#define CM_SYSDIV		0x014
+#define CM_PERIACTL		0x018
+#define CM_PERIADIV		0x01c
+#define CM_PERIICTL		0x020
+#define CM_PERIIDIV		0x024
+#define CM_H264CTL		0x028
+#define CM_H264DIV		0x02c
+#define CM_ISPCTL		0x030
+#define CM_ISPDIV		0x034
+#define CM_V3DCTL		0x038
+#define CM_V3DDIV		0x03c
+#define CM_CAM0CTL		0x040
+#define CM_CAM0DIV		0x044
+#define CM_CAM1CTL		0x048
+#define CM_CAM1DIV		0x04c
+#define CM_CCP2CTL		0x050
+#define CM_CCP2DIV		0x054
+#define CM_DSI0ECTL		0x058
+#define CM_DSI0EDIV		0x05c
+#define CM_DSI0PCTL		0x060
+#define CM_DSI0PDIV		0x064
+#define CM_DPICTL		0x068
+#define CM_DPIDIV		0x06c
+#define CM_GP0CTL		0x070
+#define CM_GP0DIV		0x074
+#define CM_GP1CTL		0x078
+#define CM_GP1DIV		0x07c
+#define CM_GP2CTL		0x080
+#define CM_GP2DIV		0x084
+#define CM_HSMCTL		0x088
+#define CM_HSMDIV		0x08c
+#define CM_OTPCTL		0x090
+#define CM_OTPDIV		0x094
+#define CM_PWMCTL		0x0a0
+#define CM_PWMDIV		0x0a4
+#define CM_SMICTL		0x0b0
+#define CM_SMIDIV		0x0b4
+#define CM_TSENSCTL		0x0e0
+#define CM_TSENSDIV		0x0e4
+#define CM_TIMERCTL		0x0e8
+#define CM_TIMERDIV		0x0ec
+#define CM_UARTCTL		0x0f0
+#define CM_UARTDIV		0x0f4
+#define CM_VECCTL		0x0f8
+#define CM_VECDIV		0x0fc
+#define CM_PULSECTL		0x190
+#define CM_PULSEDIV		0x194
+#define CM_SDCCTL		0x1a8
+#define CM_SDCDIV		0x1ac
+#define CM_ARMCTL		0x1b0
+#define CM_EMMCCTL		0x1c0
+#define CM_EMMCDIV		0x1c4
+
+#define BCM283X_AUX_IRQ			0x0000  /*!< xxx */
+#define BCM283X_AUX_ENABLE		0x0004  /*!< */
+#define BCM283X_AUX_ENABLE_UART1	0x01    /*!<  */
+#define BCM283X_AUX_ENABLE_SPI0		0x02	/*!< SPI0 (SPI1 in the device) */
+#define BCM283X_AUX_ENABLE_SPI1		0x04	/*!< SPI1 (SPI2 in the device) */
+#define BCM283X_AUX_SPI_CNTL0		0x0000  /*!< */
+#define BCM283X_AUX_SPI_CNTL1 		0x0004  /*!< */
+#define BCM283X_AUX_SPI_STAT 		0x0008  /*!< */
+#define BCM283X_AUX_SPI_PEEK		0x000C  /*!< Read but do not take from FF */
+#define BCM283X_AUX_SPI_IO		0x0020  /*!< Write = TX, read=RX */
+#define BCM283X_AUX_SPI_TXHOLD		0x0030  /*!< Write = TX keep CS, read=RX */
+#define BCM283X_AUX_SPI_CLOCK_MIN	30500		/*!< 30,5kHz */
+#define BCM283X_AUX_SPI_CLOCK_MAX	125000000 	/*!< 125Mhz */
+#define BCM283X_AUX_SPI_CNTL0_SPEED	0xFFF00000  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_SPEED_MAX	0xFFF      /*!< */
+#define BCM283X_AUX_SPI_CNTL0_SPEED_SHIFT 20        /*!< */
+#define BCM283X_AUX_SPI_CNTL0_CS0_N     0x000C0000 /*!< CS 0 low */
+#define BCM283X_AUX_SPI_CNTL0_CS1_N     0x000A0000 /*!< CS 1 low */
+#define BCM283X_AUX_SPI_CNTL0_CS2_N 	0x00060000 /*!< CS 2 low */
+#define BCM283X_AUX_SPI_CNTL0_POSTINPUT	0x00010000  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_VAR_CS	0x00008000  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_VAR_WIDTH	0x00004000  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_DOUTHOLD	0x00003000  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_ENABLE	0x00000800  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_CPHA_IN	0x00000400  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_CLEARFIFO	0x00000200  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_CPHA_OUT	0x00000100  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_CPOL	0x00000080  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_MSBF_OUT	0x00000040  /*!< */
+#define BCM283X_AUX_SPI_CNTL0_SHIFTLEN	0x0000003F  /*!< */
+#define BCM283X_AUX_SPI_CNTL1_CSHIGH	0x00000700  /*!< */
+#define BCM283X_AUX_SPI_CNTL1_IDLE	0x00000080  /*!< */
+#define BCM283X_AUX_SPI_CNTL1_TXEMPTY	0x00000040  /*!< */
+#define BCM283X_AUX_SPI_CNTL1_MSBF_IN	0x00000002  /*!< */
+#define BCM283X_AUX_SPI_CNTL1_KEEP_IN	0x00000001  /*!< */
+#define BCM283X_AUX_SPI_STAT_TX_LVL	0xFF000000  /*!< */
+#define BCM283X_AUX_SPI_STAT_RX_LVL	0x00FF0000  /*!< */
+#define BCM283X_AUX_SPI_STAT_TX_FULL	0x00000400  /*!< */
+#define BCM283X_AUX_SPI_STAT_TX_EMPTY	0x00000200  /*!< */
+#define BCM283X_AUX_SPI_STAT_RX_FULL	0x00000100  /*!< */
+#define BCM283X_AUX_SPI_STAT_RX_EMPTY	0x00000080  /*!< */
+#define BCM283X_AUX_SPI_STAT_BUSY	0x00000040  /*!< */
+#define BCM283X_AUX_SPI_STAT_BITCOUNT	0x0000003F  /*!< */
+
+/* Defines for SPI */
+#define BCM283X_SPI0_CS                      0x0000 /*!< SPI Master Control and Status */
+#define BCM283X_SPI0_FIFO                    0x0004 /*!< SPI Master TX and RX FIFOs */
+#define BCM283X_SPI0_CLK                     0x0008 /*!< SPI Master Clock Divider */
+#define BCM283X_SPI0_DLEN                    0x000c /*!< SPI Master Data Length */
+#define BCM283X_SPI0_LTOH                    0x0010 /*!< SPI LOSSI mode TOH */
+#define BCM283X_SPI0_DC                      0x0014 /*!< SPI DMA DREQ Controls */
+
+/* Register masks for SPI0_CS */
+#define BCM283X_SPI0_CS_LEN_LONG             0x02000000 /*!< Enable Long data word in Lossi mode if DMA_LEN is set */
+#define BCM283X_SPI0_CS_DMA_LEN              0x01000000 /*!< Enable DMA mode in Lossi mode */
+#define BCM283X_SPI0_CS_CSPOL2               0x00800000 /*!< Chip Select 2 Polarity */
+#define BCM283X_SPI0_CS_CSPOL1               0x00400000 /*!< Chip Select 1 Polarity */
+#define BCM283X_SPI0_CS_CSPOL0               0x00200000 /*!< Chip Select 0 Polarity */
+#define BCM283X_SPI0_CS_RXF                  0x00100000 /*!< RXF - RX FIFO Full */
+#define BCM283X_SPI0_CS_RXR                  0x00080000 /*!< RXR RX FIFO needs Reading (full) */
+#define BCM283X_SPI0_CS_TXD                  0x00040000 /*!< TXD TX FIFO can accept Data */
+#define BCM283X_SPI0_CS_RXD                  0x00020000 /*!< RXD RX FIFO contains Data */
+#define BCM283X_SPI0_CS_DONE                 0x00010000 /*!< Done transfer Done */
+#define BCM283X_SPI0_CS_TE_EN                0x00008000 /*!< Unused */
+#define BCM283X_SPI0_CS_LMONO                0x00004000 /*!< Unused */
+#define BCM283X_SPI0_CS_LEN                  0x00002000 /*!< LEN LoSSI enable */
+#define BCM283X_SPI0_CS_REN                  0x00001000 /*!< REN Read Enable */
+#define BCM283X_SPI0_CS_ADCS                 0x00000800 /*!< ADCS Automatically Deassert Chip Select */
+#define BCM283X_SPI0_CS_INTR                 0x00000400 /*!< INTR Interrupt on RXR */
+#define BCM283X_SPI0_CS_INTD                 0x00000200 /*!< INTD Interrupt on Done */
+#define BCM283X_SPI0_CS_DMAEN                0x00000100 /*!< DMAEN DMA Enable */
+#define BCM283X_SPI0_CS_TA                   0x00000080 /*!< Transfer Active */
+#define BCM283X_SPI0_CS_CSPOL                0x00000040 /*!< Chip Select Polarity */
+#define BCM283X_SPI0_CS_CLEAR                0x00000030 /*!< Clear FIFO Clear RX and TX */
+#define BCM283X_SPI0_CS_CLEAR_RX             0x00000020 /*!< Clear FIFO Clear RX  */
+#define BCM283X_SPI0_CS_CLEAR_TX             0x00000010 /*!< Clear FIFO Clear TX  */
+#define BCM283X_SPI0_CS_CPOL                 0x00000008 /*!< Clock Polarity */
+#define BCM283X_SPI0_CS_CPHA                 0x00000004 /*!< Clock Phase */
+#define BCM283X_SPI0_CS_CS                   0x00000003 /*!< Chip Select */
+
+enum spi_bit_order
+{
+    BCM283X_SPI_BIT_ORDER_LSBFIRST = 0,  /*!< LSB First */
+    BCM283X_SPI_BIT_ORDER_MSBFIRST = 1   /*!< MSB First */
+};
+
+enum spi_mode
+{
+    BCM283X_SPI_MODE0 = 0,  /*!< CPOL = 0, CPHA = 0 */
+    BCM283X_SPI_MODE1 = 1,  /*!< CPOL = 0, CPHA = 1 */
+    BCM283X_SPI_MODE2 = 2,  /*!< CPOL = 1, CPHA = 0 */
+    BCM283X_SPI_MODE3 = 3   /*!< CPOL = 1, CPHA = 1 */
+};
+
+enum spi_chip_select
+{
+    BCM283X_SPI_CS0 = 0,     /*!< Chip Select 0 */
+    BCM283X_SPI_CS1 = 1,     /*!< Chip Select 1 */
+    BCM283X_SPI_CS2 = 2,     /*!< Chip Select 2 (ie pins CS1 and CS2 are asserted) */
+    BCM283X_SPI_CS_NONE = 3  /*!< No CS, control it yourself */
+};
+
+enum spi_clock_divider
+{
+    BCM283X_SPI_CLOCK_DIVIDER_65536 = 0,       /*!< 65536 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_32768 = 32768,   /*!< 32768 = 7.629394531kHz on Rpi2, 12.20703125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_16384 = 16384,   /*!< 16384 = 15.25878906kHz on Rpi2, 24.4140625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_8192  = 8192,    /*!< 8192 = 30.51757813kHz on Rpi2, 48.828125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_4096  = 4096,    /*!< 4096 = 61.03515625kHz on Rpi2, 97.65625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_2048  = 2048,    /*!< 2048 = 122.0703125kHz on Rpi2, 195.3125kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_1024  = 1024,    /*!< 1024 = 244.140625kHz on Rpi2, 390.625kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_512   = 512,     /*!< 512 = 488.28125kHz on Rpi2, 781.25kHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_256   = 256,     /*!< 256 = 976.5625kHz on Rpi2, 1.5625MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_128   = 128,     /*!< 128 = 1.953125MHz on Rpi2, 3.125MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_64    = 64,      /*!< 64 = 3.90625MHz on Rpi2, 6.250MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_32    = 32,      /*!< 32 = 7.8125MHz on Rpi2, 12.5MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_16    = 16,      /*!< 16 = 15.625MHz on Rpi2, 25MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_8     = 8,       /*!< 8 = 31.25MHz on Rpi2, 50MHz on RPI3 */
+    BCM283X_SPI_CLOCK_DIVIDER_4     = 4,       /*!< 4 = 62.5MHz on Rpi2, 100MHz on RPI3. Dont expect this speed to work reliably. */
+    BCM283X_SPI_CLOCK_DIVIDER_2     = 2,       /*!< 2 = 125MHz on Rpi2, 200MHz on RPI3, fastest you can get. Dont expect this speed to work reliably.*/
+    BCM283X_SPI_CLOCK_DIVIDER_1     = 1        /*!< 1 = 3.814697260kHz on Rpi2, 6.1035156kHz on RPI3, same as 0/65536 */
+};
+
+/* BCM IO pin */
+enum bcm_gpio_pin
+{
+    BCM_GPIO_PIN_0 = 0,
+    BCM_GPIO_PIN_1,
+    BCM_GPIO_PIN_2,
+    BCM_GPIO_PIN_3,
+    BCM_GPIO_PIN_4,
+    BCM_GPIO_PIN_5,
+    BCM_GPIO_PIN_6,
+    BCM_GPIO_PIN_7,
+    BCM_GPIO_PIN_8,
+    BCM_GPIO_PIN_9,
+    BCM_GPIO_PIN_10,
+    BCM_GPIO_PIN_11,
+    BCM_GPIO_PIN_12,
+    BCM_GPIO_PIN_13,
+    BCM_GPIO_PIN_14,
+    BCM_GPIO_PIN_15,
+    BCM_GPIO_PIN_16,
+    BCM_GPIO_PIN_17,
+    BCM_GPIO_PIN_18,
+    BCM_GPIO_PIN_19,
+    BCM_GPIO_PIN_20,
+    BCM_GPIO_PIN_21,
+    BCM_GPIO_PIN_22,
+    BCM_GPIO_PIN_23,
+    BCM_GPIO_PIN_24,
+    BCM_GPIO_PIN_25,
+    BCM_GPIO_PIN_26,
+    BCM_GPIO_PIN_27,
+    BCM_GPIO_PIN_28,
+    BCM_GPIO_PIN_29,
+    BCM_GPIO_PIN_30,
+    BCM_GPIO_PIN_31,
+    BCM_GPIO_PIN_32,
+    BCM_GPIO_PIN_33,
+    BCM_GPIO_PIN_34,
+    BCM_GPIO_PIN_35,
+    BCM_GPIO_PIN_36,
+    BCM_GPIO_PIN_37,
+    BCM_GPIO_PIN_38,
+    BCM_GPIO_PIN_39,
+    BCM_GPIO_PIN_40,
+    BCM_GPIO_PIN_41,
+    BCM_GPIO_PIN_42,
+    BCM_GPIO_PIN_43,
+    BCM_GPIO_PIN_44,
+    BCM_GPIO_PIN_45,
+    BCM_GPIO_PIN_46,
+    BCM_GPIO_PIN_47,
+    BCM_GPIO_PIN_48,
+    BCM_GPIO_PIN_49,
+    BCM_GPIO_PIN_50,
+    BCM_GPIO_PIN_51,
+    BCM_GPIO_PIN_52,
+    BCM_GPIO_PIN_53,
+    BCM_GPIO_PIN_NUM,
+};
+
+rt_uint32_t bcm283x_peri_read(volatile rt_ubase_t addr);
+rt_uint32_t bcm283x_peri_read_nb(volatile rt_ubase_t addr);
+void bcm283x_peri_write(volatile rt_ubase_t addr, rt_uint32_t value);
+void bcm283x_peri_write_nb(volatile rt_ubase_t addr, rt_uint32_t value);
+void bcm283x_peri_set_bits(volatile rt_ubase_t addr, rt_uint32_t value, rt_uint32_t mask);
+
+void bcm283x_gpio_fsel(rt_uint8_t pin, rt_uint8_t mode);
+void bcm283x_gpio_set(rt_uint8_t pin);
+void bcm283x_gpio_clr(rt_uint8_t pin);
+
+rt_uint8_t bcm283x_gpio_lev(rt_uint8_t pin);
+rt_uint8_t bcm283x_gpio_eds(rt_uint8_t pin);
+void bcm283x_gpio_set_eds(rt_uint8_t pin);
+void bcm283x_gpio_ren(rt_uint8_t pin);
+void bcm283x_gpio_clr_ren(rt_uint8_t pin);
+void bcm283x_gpio_fen(rt_uint8_t pin);
+void bcm283x_gpio_clr_fen(rt_uint8_t pin);
+void bcm283x_gpio_hen(rt_uint8_t pin);
+void bcm283x_gpio_clr_hen(rt_uint8_t pin);
+void bcm283x_gpio_len(rt_uint8_t pin);
+void bcm283x_gpio_clr_len(rt_uint8_t pin);
+void bcm283x_gpio_aren(rt_uint8_t pin);
+void bcm283x_gpio_clr_aren(rt_uint8_t pin);
+void bcm283x_gpio_afen(rt_uint8_t pin);
+void bcm283x_gpio_clr_afen(rt_uint8_t pin);
+void bcm283x_gpio_pud(rt_uint8_t pud);
+void bcm283x_gpio_pudclk(rt_uint8_t pin, rt_uint8_t on);
+void bcm283x_gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud);
+void bcm283x_gpio_write(rt_uint8_t pin, rt_uint8_t val);
+void bcm283x_st_delay(rt_uint64_t offset_micros, rt_uint64_t micros);
+rt_uint64_t bcm283x_st_read(void);
+void bcm283x_delayMicroseconds(rt_uint64_t micros);
+void bcm283x_clo_delayMicros(rt_uint32_t micros);
+
+int bcm283x_i2c_begin(int no);
+void bcm283x_i2c_end(int no);
+void bcm283x_i2c_setSlaveAddress(int no, rt_uint8_t saddr);
+void bcm283x_i2c_setClockDivider(int no, rt_uint16_t divider);
+void bcm283x_i2c_set_baudrate(int no, rt_uint32_t baudrate);
+rt_uint8_t bcm283x_i2c_read(rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len);
+rt_uint8_t bcm283x_i2c_write(rt_uint32_t base, const rt_uint8_t * buf, rt_uint32_t len);
+rt_uint8_t bcm283x_i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len);
+
+#endif
+

+ 298 - 0
bsp/raspberry-pi/raspi3-64/driver/board.c

@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+
+#include "board.h"
+#include "drv_uart.h"
+#include "drv_timer.h"
+
+#include "cp15.h"
+
+#ifdef RT_USING_SMP
+extern void rt_hw_ipi_handler_install(int ipi_vector, rt_isr_handler_t ipi_isr_handler);
+
+void ipi_handler(){
+    rt_scheduler_ipi_handler(0,RT_NULL);
+}
+#endif
+
+void rt_hw_timer_isr(int vector, void *parameter)
+{
+    ARM_TIMER_IRQCLR = 0;
+    rt_tick_increase();
+}
+
+int rt_hw_timer_init()
+{
+    __DSB();
+    rt_hw_interrupt_install(IRQ_ARM_TIMER, rt_hw_timer_isr, RT_NULL, "tick");
+    rt_hw_interrupt_umask(IRQ_ARM_TIMER);
+    /* timer_clock = apb_clock/(pre_divider + 1) */
+    ARM_TIMER_PREDIV = (250 - 1);
+
+    ARM_TIMER_RELOAD = 0;
+    ARM_TIMER_LOAD   = 0;
+    ARM_TIMER_IRQCLR = 0;
+    ARM_TIMER_CTRL   = 0;
+
+    ARM_TIMER_RELOAD = 10000;
+    ARM_TIMER_LOAD   = 10000;
+
+    /* 23-bit counter, enable interrupt, enable timer */
+    ARM_TIMER_CTRL   = (1 << 1) | (1 << 5) | (1 << 7);
+    return 0;
+}
+
+void idle_wfi(void)
+{
+    asm volatile ("wfi");
+}
+
+#define MMU_LEVEL_MASK 0x1ffUL
+#define MMU_MAP_ERROR_VANOTALIGN  -1
+#define MMU_MAP_ERROR_PANOTALIGN  -2
+#define MMU_MAP_ERROR_NOPAGE      -3
+#define MMU_MAP_ERROR_CONFLICT    -4
+
+unsigned char main_tbl[4096] __attribute__((aligned (4096)));
+unsigned char __page_start[4096*100] __attribute__((aligned (4096)));
+unsigned long __page_off = 0;
+unsigned long get_free_page(void) {
+    __page_off += 4096;
+    return (unsigned long)(__page_start + __page_off - 4096);
+}
+
+#define MEM_ATTR_MEM ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x1UL << 2))
+#define MEM_ATTR_IO ((0x1UL << 10) | (0x2UL << 8) | (0x0UL << 6) | (0x2UL << 2))
+
+static int map_single_page_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, unsigned long attr) {
+    int level;
+    unsigned long* cur_lv_tbl = lv0_tbl;
+    unsigned long page;
+    unsigned long off;
+    int level_shift = 39;
+
+    if (va & (0x200000UL - 1)) {
+        return MMU_MAP_ERROR_VANOTALIGN;
+    }
+    if (pa & (0x200000UL - 1)) {
+        return MMU_MAP_ERROR_PANOTALIGN;
+    }
+    for (level = 0; level < 2; level++) {
+        off = (va >> level_shift);
+        off &= MMU_LEVEL_MASK;
+        if ((cur_lv_tbl[off] & 1) == 0) {
+            page = get_free_page();
+            if (!page) {
+                return MMU_MAP_ERROR_NOPAGE;
+            }
+            rt_memset((void *)page, 0, 4096);
+            cur_lv_tbl[off] = page | 0x3UL;
+        }
+        page = cur_lv_tbl[off];
+        if (!(page & 0x2)) {
+            //is block! error!
+            return MMU_MAP_ERROR_CONFLICT;
+        }
+        cur_lv_tbl = (unsigned long*)(page & 0x0000fffffffff000UL);
+        level_shift -= 9;
+    }
+    attr &= 0xfff0000000000ffcUL;
+    pa |= (attr | 0x1UL); //block
+    off = (va >> 21);
+    off &= MMU_LEVEL_MASK;
+    cur_lv_tbl[off] = pa;
+    return 0;
+}
+
+int armv8_map_2M(unsigned long* lv0_tbl, unsigned long va, unsigned long pa, int count, unsigned long attr)
+{
+	int i;
+    int ret;
+
+	if (va & (0x200000 - 1))
+	{
+		return -1;
+	}
+	if (pa & (0x200000 - 1))
+	{
+		return -1;
+	}
+	for (i = 0; i < count; i++)
+	{
+		ret = map_single_page_2M(lv0_tbl, va, pa, attr);
+		va += 0x200000;
+		pa += 0x200000;
+        if (ret != 0)
+        {
+            return ret;
+        }
+	}
+    return 0;
+}
+
+/**
+ *  Initialize the Hardware related stuffs. Called from rtthread_startup() 
+ *  after interrupt disabled.
+ */
+void rt_hw_board_init(void)
+{
+    /* mmu set */
+    unsigned long val64;
+    unsigned long val32; //val32不是uint32_t,val32只是表示相关的那个寄存器是32位的
+    int ret;
+
+    val64 = 0x007f6eUL;
+    asm volatile("msr MAIR_EL1, %0\n dsb sy\n"::"r"(val64));
+    asm volatile("mrs %0, MAIR_EL1\n dsb sy\n":"=r"(val64));
+
+    //TCR_EL1
+    val32 = (16UL << 0)
+        | (0x0UL << 6)
+        | (0x0UL << 7)
+        | (0x3UL << 8)
+        | (0x3UL << 10)
+        | (0x2UL << 12)
+        | (0x0UL << 14)
+        | (0x0UL << 16)
+        | (0x0UL << 22)
+        | (0x1UL << 23)
+        | (0x2UL << 30)
+        | (0x1UL << 32)
+        | (0x0UL << 35)
+        | (0x0UL << 36)
+        | (0x0UL << 37)
+        | (0x0UL << 38);
+    asm volatile("msr TCR_EL1, %0\n"::"r"(val32));
+    asm volatile("mrs %0, TCR_EL1\n":"=r"(val32));
+
+    asm volatile("msr TTBR0_EL1, %0\n dsb sy\n"::"r"(main_tbl));
+    asm volatile("mrs %0, TTBR0_EL1\n dsb sy\n":"=r"(val64));
+
+    rt_memset(main_tbl, 0, 4096);
+
+	ret = armv8_map_2M((unsigned long *)main_tbl, 0x0, 0x0, 32, MEM_ATTR_MEM); //32*2M = 64M
+    if (ret)
+    {
+        goto skip_mmu;
+    }
+	ret = armv8_map_2M((unsigned long *)main_tbl, 0x3f000000, 0x3f000000, 8, MEM_ATTR_IO); //8*2M = 16M
+    if (ret)
+    {
+        goto skip_mmu;
+    }
+
+	//关闭指令cache
+	__asm__ volatile("mrs %0, SCTLR_EL1\n":"=r"(val64));
+	val64 &= ~0x1000; //disable I
+	__asm__ volatile("dmb sy\n msr SCTLR_EL1, %0\n isb sy\n"::"r"(val64));
+
+	//清除指令cache
+	__asm__ volatile("IC IALLUIS\n dsb sy\n isb sy\n");
+	//清除tlb
+	__asm__ volatile("tlbi vmalle1\n dsb sy\n isb sy\n");
+
+	//SCTLR_EL1, turn on mmu
+	asm volatile("mrs %0, SCTLR_EL1\n":"=r"(val32));
+	val32 |= 0x1005; //enable mmu, I C M
+	asm volatile("dmb sy\n msr SCTLR_EL1, %0\nisb sy\n"::"r"(val32));
+
+skip_mmu:
+
+    /* initialize hardware interrupt */
+    rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
+    rt_hw_vector_init();    // in libcpu/interrupt.c. == rt_cpu_vector_set_base((rt_ubase_t)&system_vectors);
+
+    /* initialize uart */
+    rt_hw_uart_init();      // driver/drv_uart.c
+    /* initialize timer for os tick */
+    rt_hw_timer_init();
+    rt_thread_idle_sethook(idle_wfi);
+
+#ifdef RT_USING_CONSOLE
+    /* set console device */
+    rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
+#endif /* RT_USING_CONSOLE */
+
+#ifdef RT_USING_HEAP
+    /* initialize memory system */
+    rt_kprintf("heap: 0x%08x - 0x%08x\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+    rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
+#endif
+
+#ifdef RT_USING_COMPONENTS_INIT
+    rt_components_board_init();
+#endif
+	rt_kprintf("__page_off = %x\n", __page_off);
+}
+
+#ifdef RT_USING_SMP
+void _reset(void);
+void secondary_cpu_start(void);
+
+void rt_hw_secondary_cpu_up(void)
+{
+    int i;
+    int retry,val;
+    rt_cpu_dcache_clean_flush();
+    rt_cpu_icache_flush();
+    /*TODO maybe, there is some bug */
+    for(i=RT_CPUS_NR-1; i>0; i-- )
+    {
+        rt_kprintf("boot cpu:%d\n", i);
+        setup_bootstrap_addr(i, (int)_reset);
+        __SEV();
+        __DSB();
+        __ISB();
+        retry = 10;
+        rt_thread_delay(RT_TICK_PER_SECOND/1000);
+        do
+        {
+            val = CORE_MAILBOX3_CLEAR(i);
+            if (val == 0)
+            {
+                rt_kprintf("start OK: CPU %d \n",i);
+                break;
+            }
+            rt_thread_delay(RT_TICK_PER_SECOND);
+
+            retry --;
+            if (retry <= 0)
+            {
+                rt_kprintf("can't start for CPU %d \n",i);
+                break;
+            }
+        }while (1);
+    }
+    __DSB();
+    __SEV();
+}
+
+void secondary_cpu_c_start(void)
+{
+    uint32_t id;
+    id = rt_hw_cpu_id();
+    rt_kprintf("cpu = 0x%08x\n",id);
+    rt_hw_timer_init();
+    rt_kprintf("cpu %d startup.\n",id);
+    rt_hw_vector_init();
+    enable_cpu_ipi_intr(id);
+    rt_hw_spin_lock(&_cpus_lock);
+    rt_system_scheduler_start();
+}
+
+void rt_hw_secondary_cpu_idle_exec(void)
+{
+    __WFE();
+}
+
+#endif

+ 29 - 0
bsp/raspberry-pi/raspi3-64/driver/board.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#ifndef BOARD_H__
+#define BOARD_H__
+
+#include <stdint.h>
+
+#include <rthw.h>
+#include <bcm283x.h>
+
+#define __REG32 HWREG32
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define RT_HW_HEAP_BEGIN    (void*)&__bss_end
+#define RT_HW_HEAP_END      (void*)(RT_HW_HEAP_BEGIN + 4 * 1024 * 1024)
+
+void rt_hw_board_init(void);
+
+#endif
+

+ 523 - 0
bsp/raspberry-pi/raspi3-64/driver/drv_fb.c

@@ -0,0 +1,523 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include "mbox.h"
+#include "drv_fb.h"
+#include "mmu.h"
+
+#define CHAR_W          8
+#define CHAR_H          12
+
+#define COLOR_DELTA     0.05
+static struct rt_hdmi_fb_device _hdmi;
+
+// https://github.com/xinu-os/xinu/blob/1789b7a50b5b73c2ea76ebd764c54a034097d04d/device/framebuffer_rpi/font.c
+unsigned char FONT[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*' '*/
+0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'!'*/
+0x00, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'"'*/
+0x00, 0x00, 0x14, 0x14, 0x3e, 0x14, 0x3e, 0x14, 0x14, 0x00, 0x00, 0x00, /*'#'*/
+0x00, 0x00, 0x08, 0x3c, 0x0a, 0x1c, 0x28, 0x1e, 0x08, 0x00, 0x00, 0x00, /*'$'*/
+0x00, 0x00, 0x06, 0x26, 0x10, 0x08, 0x04, 0x32, 0x30, 0x00, 0x00, 0x00, /*'%'*/
+0x00, 0x00, 0x1c, 0x02, 0x02, 0x04, 0x2a, 0x12, 0x2c, 0x00, 0x00, 0x00, /*'&'*/
+0x00, 0x18, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'''*/
+0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, /*'('*/
+0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x00, /*')'*/
+0x00, 0x00, 0x00, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x00, 0x00, 0x00, 0x00, /*'*'*/
+0x00, 0x00, 0x00, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /*'+'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*','*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'-'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*'.'*/
+0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, /*'/'*/
+0x00, 0x1c, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'0'*/
+0x00, 0x08, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'1'*/
+0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'2'*/
+0x00, 0x1c, 0x22, 0x20, 0x18, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'3'*/
+0x00, 0x10, 0x18, 0x18, 0x14, 0x14, 0x3e, 0x10, 0x38, 0x00, 0x00, 0x00, /*'4'*/
+0x00, 0x3e, 0x02, 0x02, 0x1e, 0x20, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'5'*/
+0x00, 0x18, 0x04, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'6'*/
+0x00, 0x3e, 0x22, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00, /*'7'*/
+0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'8'*/
+0x00, 0x1c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, /*'9'*/
+0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, /*':'*/
+0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x08, 0x04, 0x00, /*';'*/
+0x00, 0x00, 0x00, 0x30, 0x0c, 0x03, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, /*'<'*/
+0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, /*'='*/
+0x00, 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, /*'>'*/
+0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, /*'?'*/
+0x00, 0x00, 0x1c, 0x22, 0x3a, 0x3a, 0x1a, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'@'*/
+0x00, 0x00, 0x08, 0x14, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x00, 0x00, 0x00, /*'A'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'B'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x02, 0x02, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'C'*/
+0x00, 0x00, 0x0e, 0x12, 0x22, 0x22, 0x22, 0x12, 0x0e, 0x00, 0x00, 0x00, /*'D'*/
+0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'E'*/
+0x00, 0x00, 0x3e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'F'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x32, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'G'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'H'*/
+0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e, 0x00, 0x00, 0x00, /*'I'*/
+0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'J'*/
+0x00, 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'K'*/
+0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'L'*/
+0x00, 0x00, 0x22, 0x36, 0x2a, 0x2a, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'M'*/
+0x00, 0x00, 0x22, 0x26, 0x26, 0x2a, 0x32, 0x32, 0x22, 0x00, 0x00, 0x00, /*'N'*/
+0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'O'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'P'*/
+0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x30, 0x00, 0x00, /*'Q'*/
+0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x0a, 0x12, 0x22, 0x00, 0x00, 0x00, /*'R'*/
+0x00, 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'S'*/
+0x00, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'T'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'U'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'V'*/
+0x00, 0x00, 0x22, 0x22, 0x22, 0x2a, 0x2a, 0x36, 0x22, 0x00, 0x00, 0x00, /*'W'*/
+0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x14, 0x22, 0x22, 0x00, 0x00, 0x00, /*'X'*/
+0x00, 0x00, 0x22, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, /*'Y'*/
+0x00, 0x00, 0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x3e, 0x00, 0x00, 0x00, /*'Z'*/
+0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, /*'['*/
+0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, /*'\'*/
+0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, /*']'*/
+0x00, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'^'*/
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, /*'_'*/
+0x00, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'`'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'a'*/
+0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x00, 0x00, 0x00, /*'b'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x02, 0x02, 0x3c, 0x00, 0x00, 0x00, /*'c'*/
+0x00, 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x00, 0x00, 0x00, /*'d'*/
+0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x1c, 0x00, 0x00, 0x00, /*'e'*/
+0x00, 0x38, 0x04, 0x04, 0x1e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, /*'f'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'g'*/
+0x00, 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'h'*/
+0x00, 0x08, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'i'*/
+0x00, 0x10, 0x10, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0e, /*'j'*/
+0x00, 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x00, 0x00, 0x00, /*'k'*/
+0x00, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, /*'l'*/
+0x00, 0x00, 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x22, 0x00, 0x00, 0x00, /*'m'*/
+0x00, 0x00, 0x00, 0x00, 0x1a, 0x26, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, /*'n'*/
+0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, /*'o'*/
+0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02, /*'p'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x20, /*'q'*/
+0x00, 0x00, 0x00, 0x00, 0x1a, 0x06, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, /*'r'*/
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x1c, 0x20, 0x1e, 0x00, 0x00, 0x00, /*'s'*/
+0x00, 0x08, 0x08, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, /*'t'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x32, 0x2c, 0x00, 0x00, 0x00, /*'u'*/
+0x00, 0x00, 0x00, 0x00, 0x36, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0x00, /*'v'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, 0x00, 0x00, /*'w'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, /*'x'*/
+0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20, 0x1c, /*'y'*/
+0x00, 0x00, 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, 0x00, 0x00, /*'z'*/
+0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, /*'{'*/
+0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, /*'|'*/
+0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x00, /*'}'*/
+0x00, 0x04, 0x2a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*'~'*/
+0x00, 0x00, 0x00, 0x08, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x00, 0x00, 0x00, /*DEL*/
+};
+
+void newline(fb_t* fb)
+{
+    uint8_t* to;
+    uint8_t* from;
+    int i;
+    fb->y++;
+    fb->x = 0;
+
+    if (fb->y == (fb->height / CHAR_H))
+    {
+
+        to = (uint8_t*) fb->addr;
+        from = to + (CHAR_H * fb->pitch);
+
+        for (i = 0; i < ((fb->height - CHAR_H) * fb->pitch); i++)
+        {
+            *to++ = *from++;
+        }
+
+        uint32_t *addr = (uint32_t*) (fb->addr) + (fb->height - CHAR_H) * fb->width;
+
+        for (i = 0; i < (CHAR_H * fb->width); i++)
+        {
+            *addr++ = fb->back;
+        }
+
+        fb->y--;
+    }
+}
+
+void clear_line(fb_t *fb, const int line)
+{
+    int i;
+    uint32_t* addr;
+    if (line > fb->height / CHAR_H)
+    {
+        fb->y = 0;
+    }
+    else
+    {
+        fb->y = line;
+    }
+
+    fb->x = 0;
+
+    addr = (uint32_t*) (fb->addr + (line * CHAR_H * fb->depth * fb->width));
+    for (i = 0; i < (CHAR_H * fb->width); i++)
+    {
+        *addr++ = fb->back;
+    }
+
+}
+
+void clear(fb_t *fb, const uint32_t color)
+{
+
+    uint32_t *addr = (uint32_t*) fb->addr;
+    uint32_t i;
+    for (i = 0; i < (fb->height * fb->width); i++)
+    {
+        *addr++ = color;
+    }
+    fb->x = 0;
+    fb->y = 0;
+
+}
+
+void fb_draw_char(fb_t *fb, char s)
+{
+    unsigned char* addr = (unsigned char*) fb->addr;
+    unsigned char *glyph = (unsigned char*) FONT + (s) * 12;
+    // calculate the offset on screen
+    int offs = (fb->y * CHAR_H * fb->pitch) + (fb->x * (CHAR_W + 1) * 4);
+    // variables
+    int i, j, line, mask, bytesperline = (CHAR_W + 7) / 8;
+    // display a character
+    for (j = 0; j < CHAR_H; j++)
+    {
+        // display one row
+        line = offs;
+        mask = 1;
+        for (i = 0; i < CHAR_W; i++)
+        {
+            // if bit set, we use white color, otherwise black
+            *((unsigned int*) (addr + line)) = ((int) *glyph) & mask ? fb->fore : fb->back;
+            mask <<= 1;
+            line += 4;
+        }
+        // adjust to next line
+        glyph += bytesperline;
+        offs += fb->pitch;
+    }
+}
+
+void fb_print(fb_t *fb, char *s)
+{
+
+    // draw next character if it's not zero
+    while (*s)
+    {
+        // handle carrige return
+        if (*s == '\r')
+        {
+            fb->x = 0;
+        }
+        else if (*s == '\n')
+        {
+            newline(fb);
+        }
+        else if (*s == '\t')
+        {
+            fb->x = ((fb->x + 4) >> 2) << 2;
+        }
+        else if (*s == '\b')
+        {
+            if (fb->x)
+            {
+                fb->x--;
+                fb_draw_char(fb, ' ');
+            }
+        }
+        else
+        {
+            fb_draw_char(fb, *s);
+            fb->x++;
+        }
+        // next character
+        if (fb->x == fb->width / CHAR_W)
+        {
+            newline(fb);
+        }
+        s++;
+    }
+}
+
+rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    return RT_EOK;
+}
+
+rt_err_t hdmi_fb_close(rt_device_t dev)
+{
+    return RT_EOK;
+}
+
+rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
+{
+#ifdef BSP_USING_USPI
+    char* buffer = (char *) buf;
+    if(keyboard_available())
+    {
+        int i = 0;
+        int j = 0;
+        while (i != size)
+        {
+            int ch = keyboard_getchar();
+            if(ch != -1)
+            buffer[j++] = ch;
+            i++;
+        }
+        return j;
+
+    }
+#endif
+    return 0;
+}
+
+rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    fb_print(&_hdmi.fb, (char *) buffer);
+#ifdef BSP_USING_HDMI_DISPLAY
+    rt_device_t uart = rt_device_find("uart1");
+    int old_flag = uart->open_flag;
+    uart->open_flag |= RT_DEVICE_FLAG_STREAM;
+    rt_device_write(uart, 0, buffer, size);
+    uart->open_flag = old_flag;
+#endif
+    return size;
+
+}
+
+rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
+{
+    return RT_EOK;
+}
+
+const static struct rt_device_ops hdmi_fb_ops = {
+    RT_NULL,
+    hdmi_fb_open,
+    hdmi_fb_close,
+    hdmi_fb_read,
+    hdmi_fb_write,
+    hdmi_fb_control
+};
+
+static struct rt_device_graphic_info _hdmi_info;
+
+static void hdmi_draw_rect(const char* pixel, int x1, int y1, int x2, int y2)
+{
+    int i, j;
+    int line;
+    for (j = y1; j <= y2; j++)
+    {
+        line = (j * _hdmi.fb.pitch) + (x1 * 4);
+        for (i = x1; i <= x2; i++)
+        {
+            // if bit set, we use white color, otherwise black
+            *((unsigned int*) (_hdmi_info.framebuffer + line)) = *(unsigned int*) pixel;
+            line += 4;
+        }
+    }
+
+}
+
+static void hdmi_set_pixel(const char* pixel, int x, int y)
+{
+    *(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) = *(uint32_t *) pixel;
+}
+
+static void hdmi_get_pixel(char* pixel, int x, int y)
+{
+    uint32_t ret = 0;
+    ret = (*(uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4)) & 0x00FFFFFF);
+    *pixel = ret;
+}
+
+static void hdmi_draw_hline(const char* pixel, int x1, int x2, int y)
+{
+    hdmi_draw_rect(pixel, x1, y, x2, y);
+}
+
+static void hdmi_draw_vline(const char* pixel, int x, int y1, int y2)
+{
+    hdmi_draw_rect(pixel, x, y1, x, y2);
+}
+
+static void hdmi_blit_line(const char* pixels, int x, int y, rt_size_t size)
+{
+    int i = 0;
+    uint32_t *pixel_base = (uint32_t*) (_hdmi.fb.addr + (y * _hdmi.fb.pitch + x * 4));
+    uint32_t *colors = (uint32_t *) pixels;
+    for (i = 0; i < size; i++)
+    {
+        pixel_base[i] = colors[i];
+    }
+}
+
+static struct rt_device_graphic_ops hdmi_ops = {
+    hdmi_set_pixel,
+    hdmi_get_pixel,
+    hdmi_draw_hline,
+    hdmi_draw_vline,
+    hdmi_blit_line
+};
+
+rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
+{
+    struct rt_device *device;
+    RT_ASSERT(hdmi_fb != RT_NULL);
+
+    device = &hdmi_fb->parent;
+    device->user_data = &hdmi_ops;
+
+    /* set device type */
+    device->type = RT_Device_Class_Graphic;
+    /* initialize device interface */
+#ifdef RT_USING_DEVICE_OPS
+    device->ops = &hdmi_fb_ops;
+#else
+    device->init = RT_NULL;
+    device->open = hdmi_fb_open;
+    device->close = hdmi_fb_close;
+    device->read = hdmi_fb_read;
+    device->write = hdmi_fb_write;
+    device->control = hdmi_fb_control;
+#endif
+
+    /* register to device manager */
+    rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
+
+    return RT_EOK;
+}
+
+/**
+ * Show a picture
+ */
+void print_fb_info()
+{
+    rt_kprintf("FrameBuffer Info: \n \t width %x\t height %x\t depth %x\t addr %x\t size %x\t \n", fb_info.width,
+            fb_info.height, fb_info.depth, fb_info.addr, fb_info.size);
+    rt_kprintf("call mbox:%x,%x,%x,%x,%x\n", mbox[0], mbox[1], mbox[2], mbox[3], mbox[4]);
+}
+
+void hdmi_fb_init()
+{
+    unsigned int *mbox = (unsigned int*) MBOX_ADDR;
+    mbox[0] = 35 * 4;
+    mbox[1] = MBOX_REQUEST;
+
+    mbox[2] = 0x48003;  //set phy wh
+    mbox[3] = 8;
+    mbox[4] = 8;
+    mbox[5] = 640;         //FrameBufferInfo.width
+    mbox[6] = 480;          //FrameBufferInfo.height
+
+    mbox[7] = 0x48004;  //set virt wh
+    mbox[8] = 8;
+    mbox[9] = 8;
+    mbox[10] = 640;        //FrameBufferInfo.virtual_width
+    mbox[11] = 480;         //FrameBufferInfo.virtual_height
+
+    mbox[12] = 0x48009; //set virt offset
+    mbox[13] = 8;
+    mbox[14] = 8;
+    mbox[15] = 0;           //FrameBufferInfo.x_offset
+    mbox[16] = 0;           //FrameBufferInfo.y.offset
+
+    mbox[17] = 0x48005; //set depth
+    mbox[18] = 4;
+    mbox[19] = 4;
+    mbox[20] = 32;          //FrameBufferInfo.depth
+
+    mbox[21] = 0x48006; //set pixel order
+    mbox[22] = 4;
+    mbox[23] = 4;
+    mbox[24] = 1;           //RGB, not BGR preferably
+
+    mbox[25] = 0x40001; //get framebuffer, gets alignment on request
+    mbox[26] = 8;
+    mbox[27] = 8;
+    mbox[28] = 4096;        //FrameBufferInfo.pointer
+    mbox[29] = 0;           //FrameBufferInfo.size
+
+    mbox[30] = 0x40008; //get pitch
+    mbox[31] = 4;
+    mbox[32] = 4;
+    mbox[33] = 0;           //FrameBufferInfo.pitch
+
+    mbox[34] = MBOX_TAG_LAST;
+    if (mbox_call(MBOX_CH_PROP, MMU_DISABLE) && mbox[20] == 32 && mbox[28] != 0)
+    {
+        mbox[28] &= 0x3FFFFFFF;
+        _hdmi.fb.width = mbox[5];
+        _hdmi.fb.height = mbox[6];
+        _hdmi.fb.pitch = mbox[33];
+        //_hdmi.fb.addr = (void*)((unsigned long)mbox[28]);
+        _hdmi.fb.addr = (rt_uint32_t) mbox[28];
+        _hdmi.fb.size = mbox[29];
+        _hdmi.fb.depth = 32;
+        _hdmi.fb.x = 0;
+        _hdmi.fb.y = 0;
+        _hdmi.fb.fore = CONSOLE_WHITE;
+        _hdmi.fb.back = CONSOLE_BLACK;
+        rt_hdmi_fb_device_init(&_hdmi, "hdmi");
+        rt_hw_change_mmu_table(_hdmi.fb.addr, _hdmi.fb.size, _hdmi.fb.addr, DEVICE_MEM);
+        fb_info.width = _hdmi.fb.width;
+        fb_info.height = _hdmi.fb.height;
+        fb_info.addr = _hdmi.fb.addr;
+        fb_info.size = _hdmi.fb.size;
+        fb_info.pitch = _hdmi.fb.pitch;
+        fb_info.depth = _hdmi.fb.depth;
+        _hdmi_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
+        _hdmi_info.bits_per_pixel = _hdmi.fb.depth;
+        _hdmi_info.width = _hdmi.fb.width;
+        _hdmi_info.height = _hdmi.fb.height;
+        _hdmi_info.framebuffer = (rt_uint8_t *) _hdmi.fb.addr;
+    }
+}
+

+ 60 - 0
bsp/raspberry-pi/raspi3-64/driver/drv_fb.h

@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-08-29     zdzn           first version
+ */
+#ifndef __DRV_FB_H__
+#define __DRV_FB_H__
+
+#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
+
+#define COLOR_BLACK RGB(0, 0, 0)
+
+#define COLOR_GREEN RGB(0, 255, 0)  
+ 
+#define COLOR_CYAN RGB(0, 255, 255) 
+
+#define COLOR_RED RGB(255, 0, 0)  
+
+#define COLOR_YELLOW RGB(255, 255, 0) 
+
+#define COLOR_WHITE RGB(255, 255, 255)   
+
+#define CONSOLE_WHITE COLOR_WHITE
+#define CONSOLE_BLACK COLOR_BLACK
+#define CONSOLE_GREEN COLOR_GREEN
+#define CONSOLE_CYAN COLOR_CYAN
+#define CONSOLE_RED COLOR_RED
+#define CONSOLE_YELLOW COLOR_YELLOW
+
+typedef struct
+{
+    rt_uint32_t width;
+    rt_uint32_t height;
+    rt_uint32_t vwidth;
+    rt_uint32_t vheight;
+    rt_uint32_t pitch;
+    rt_uint32_t depth;
+    rt_uint32_t fore;
+    rt_uint32_t back;
+    rt_uint32_t x;
+    rt_uint32_t y;
+    rt_uint32_t addr;
+    rt_uint32_t size;
+}fb_t;
+
+struct rt_hdmi_fb_device
+{
+    struct rt_device parent;
+    fb_t fb;
+};
+
+fb_t fb_info;
+void print_fb_info();
+void hdmi_fb_init();
+
+#endif/* __DRV_FB_H__ */

+ 473 - 0
bsp/raspberry-pi/raspi3-64/driver/drv_gpio.c

@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+#include "raspi.h"
+#include "drv_gpio.h"
+
+#ifdef BSP_USING_PIN
+
+struct rpi_pin_index
+{
+    rt_uint8_t phy_id;
+    rt_uint8_t bcm_id;
+    rt_uint8_t signal_name;
+    rt_uint8_t magic;
+};
+
+//raspi phy id and bcm id
+static struct rpi_pin_index phypin_index[] =
+{
+    {0, 0, 0, 0},
+    {1, 0, 0, 0},
+    {2, 0, 0, 0},
+    {3, BCM_GPIO_PIN_2, RPI_SDA1, PIN_MAGIC},
+    {4, 0, 0, 0},
+    {5, BCM_GPIO_PIN_3, RPI_SCL1, PIN_MAGIC},
+    {6, 0, 0, 0},
+    {7, BCM_GPIO_PIN_4, RPI_GPIO_GCLK,  PIN_MAGIC},
+    {8, BCM_GPIO_PIN_14, RPI_TXD0, PIN_MAGIC},
+    {9, 0, 0, 0},
+    {10, BCM_GPIO_PIN_15, RPI_RXD0, PIN_MAGIC},
+    {11, BCM_GPIO_PIN_17, RPI_GPIO_GEN0,  PIN_MAGIC},
+    {12, BCM_GPIO_PIN_18, RPI_GPIO_GEN1,  PIN_MAGIC},
+    {13, BCM_GPIO_PIN_27, RPI_GPIO_GEN2,  PIN_MAGIC},
+    {14, 0, 0, 0},
+    {15, BCM_GPIO_PIN_22, RPI_GPIO_GEN3,  PIN_MAGIC},
+    {16, BCM_GPIO_PIN_23, RPI_GPIO_GEN4, PIN_MAGIC},
+    {17, 0, 0, 0},
+    {18, BCM_GPIO_PIN_24, RPI_GPIO_GEN5, PIN_MAGIC},
+    {19, BCM_GPIO_PIN_10, RPI_SPI_MOSI, PIN_MAGIC},
+    {20, 0, 0, 0},
+    {21, BCM_GPIO_PIN_9, RPI_SPI_MISO, PIN_MAGIC},
+    {22, BCM_GPIO_PIN_25, RPI_GPIO_GEN6, PIN_MAGIC},
+    {23, BCM_GPIO_PIN_11, RPI_SPI_SCLK, PIN_MAGIC},
+    {24, BCM_GPIO_PIN_8, RPI_SPI_CE0_N, PIN_MAGIC},
+    {25, 0, 0, 0},
+    {26, BCM_GPIO_PIN_7, RPI_SPI_CE1_N, PIN_MAGIC},
+    {27, BCM_GPIO_PIN_0, RPI_SDA0, PIN_MAGIC},
+    {28, BCM_GPIO_PIN_1, RPI_SCL0, PIN_MAGIC},
+    {29, BCM_GPIO_PIN_5, RPI_CAM_CLK, PIN_MAGIC},
+    {30, 0, 0, 0},
+    {31, BCM_GPIO_PIN_6, RPI_LAN_RUN, PIN_MAGIC},
+    {32, BCM_GPIO_PIN_12, 0, PIN_MAGIC},
+    {33, BCM_GPIO_PIN_13, 0, PIN_MAGIC},
+    {34, 0, 0, 0},
+    {35, BCM_GPIO_PIN_19, 0, PIN_MAGIC},
+    {36, BCM_GPIO_PIN_16, RPI_STATUS_LED_N, PIN_MAGIC},
+    {37, BCM_GPIO_PIN_26, 0, PIN_MAGIC},
+    {38, BCM_GPIO_PIN_20, 0, PIN_MAGIC},
+    {39, 0, 0, 0},
+    {40, BCM_GPIO_PIN_21, RPI_CAM_GPIO,  PIN_MAGIC},
+};
+
+/*
+ * gpio_int[0] for BANK0 (pins 0-27)
+ * gpio_int[1] for BANK1 (pins 28-45)
+ * gpio_int[2] for BANK2 (pins 46-53)
+ */
+static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM];
+
+int gpio_set_func(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t func)
+{
+    RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    if (func & 0x8)
+    {
+        rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__);
+        return RT_EINVAL;
+    }
+
+    switch(func)
+    {
+    case 0x00:
+        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP);
+        break;
+    case 0x01:
+        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case 0x02:
+        bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
+        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case 0x03:
+        bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN);
+        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
+        break;
+    case 0x04:
+        bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF);
+        bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+int gpio_set_value(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t value)
+{
+
+    RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    if (value & 0xE)
+    {
+        rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__);
+        return RT_EINVAL;
+    }
+
+    bcm283x_gpio_write(pin, value);
+    return RT_EOK;
+}
+
+int gpio_get_value(enum gpio_code code, enum bcm_gpio_pin pin)
+{
+    rt_uint8_t data;
+
+    RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    data = bcm283x_gpio_lev(pin);
+    return data;
+}
+
+void gpio_set_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
+{
+    RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    rt_uint8_t index;
+    if (pin <= 27)
+    {
+        index = 0;
+    }
+    else if (pin <= 45)
+    {
+        index = 1;
+    }
+    else{
+        index = 2;
+    }
+    _g_gpio_irq_tbl[index].irq_cb[pin]    = irq_cb;
+    _g_gpio_irq_tbl[index].irq_arg[pin]   = irq_arg;
+}
+
+void gpio_set_irq_type(enum gpio_code port,  enum bcm_gpio_pin pin, rt_uint8_t irq_type)
+{
+
+    RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    rt_uint8_t index;
+    if (pin <= 27)
+    {
+        index = 0;
+    }
+    else if (pin <= 45)
+    {
+        index = 1;
+    }
+    else{
+        index = 2;
+    }
+    _g_gpio_irq_tbl[index].irq_type[pin] = irq_type;
+
+    switch(irq_type)
+    {
+    case 0x00:
+        bcm283x_gpio_ren(pin);
+        break;
+    case 0x01:
+        bcm283x_gpio_fen(pin);
+        break;
+    case 0x02:
+        bcm283x_gpio_aren(pin);
+        bcm283x_gpio_afen(pin);
+        break;
+    case 0x03:
+        bcm283x_gpio_hen(pin);
+        break;
+    case 0x04:
+        bcm283x_gpio_len(pin);
+        break;
+    }
+}
+
+static void gpio_ack_irq(int irq,  enum bcm_gpio_pin pin)
+{
+    rt_uint32_t data;
+    data = IRQ_PEND2;
+    data &= (0x0 << (irq - 32));
+    IRQ_PEND2 = data;
+
+    data = IRQ_DISABLE2;
+    data |= (0x1 << (irq - 32));
+    IRQ_DISABLE2 = data;
+}
+
+void gpio_irq_disable(enum gpio_code port,  enum bcm_gpio_pin pin)
+{
+    rt_uint8_t index;
+    int irq = 0;
+    RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    if (pin <= 27)
+    {
+        index = 0;
+        irq = IRQ_GPIO0;
+    }else if (pin <= 45){
+        index = 1;
+        irq = IRQ_GPIO1;
+    }else{
+        index = 2;
+        irq = IRQ_GPIO2;
+    }
+
+    gpio_ack_irq(irq, pin);
+
+    rt_uint8_t irq_type = _g_gpio_irq_tbl[index].irq_type[pin];
+
+    switch(irq_type)
+    {
+    case 0x00:
+        bcm283x_gpio_clr_ren(pin);
+        break;
+    case 0x01:
+        bcm283x_gpio_clr_fen(pin);
+        break;
+    case 0x02:
+        bcm283x_gpio_clr_aren(pin);
+        bcm283x_gpio_clr_afen(pin);
+        break;
+    case 0x03:
+        bcm283x_gpio_clr_hen(pin);
+        break;
+    case 0x04:
+        bcm283x_gpio_clr_len(pin);
+        break;
+    }
+}
+
+void gpio_clear_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin)
+{
+    rt_uint8_t index;
+    gpio_irq_disable(port, pin);
+
+    if (pin <= 27)
+    {
+        index = 0;
+    }
+    else if (pin <= 45)
+    {
+        index = 1;
+    }
+    else
+    {
+        index = 2;
+    }
+
+    _g_gpio_irq_tbl[index].irq_cb[pin]    = RT_NULL;
+    _g_gpio_irq_tbl[index].irq_arg[pin]   = RT_NULL;
+    _g_gpio_irq_tbl[index].irq_type[pin]  = RT_NULL;
+
+}
+
+
+void gpio_irq_enable(enum gpio_code port,  enum bcm_gpio_pin pin)
+{
+
+    rt_uint32_t offset;
+    rt_uint32_t data;
+
+    RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
+    RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
+
+    offset = pin;
+    if (pin <= 27)
+    {
+        offset = IRQ_GPIO0 - 32;
+    }
+    else if (pin <= 45)
+    {
+        offset = IRQ_GPIO1 - 32;
+    }
+    else
+    {
+        offset = IRQ_GPIO2 - 32;
+    }
+
+    data = IRQ_ENABLE2;
+    data |= 0x1 << offset;
+    IRQ_ENABLE2 = data;
+
+}
+
+//gpio_int[0] for BANK0 (pins 0-27)
+//gpio_int[1] for BANK1 (pins 28-45)
+//gpio_int[2] for BANK2 (pins 46-53)
+static void gpio_irq_handler(int irq, void *param)
+{
+    struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
+    rt_uint32_t pin;
+    rt_uint32_t addr;
+    rt_uint32_t value;
+    rt_uint32_t tmpvalue;
+
+    if (irq == IRQ_GPIO0)
+    {
+        /* 0~27 */
+        addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0; // 0~31
+        value = bcm283x_peri_read(addr);
+        value &= 0x0fffffff;
+        pin = 0;
+    }
+    else if (irq == IRQ_GPIO1)
+    {
+        /* 28-45 */
+        addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0;
+        tmpvalue = bcm283x_peri_read(addr);
+        tmpvalue &= (~0x0fffffff);
+
+        addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1;
+        value = bcm283x_peri_read(addr);
+        value &= 0x3fff;
+        value = (value<<4) | tmpvalue;
+
+        pin = 28;
+    }
+    else if (irq == IRQ_GPIO2)
+    {
+        /* 46-53 */
+        addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1;
+        value = bcm283x_peri_read(addr);
+        value &= (~0x3fff);
+        value &= 0xff600000;
+        pin = 46;
+    }
+
+    bcm283x_peri_write(addr,0);
+
+    while (value)
+    {
+        if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
+        {
+            irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
+            gpio_ack_irq(irq,pin);
+        }
+        pin++;
+        value = value >> 1;
+    }
+}
+
+static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return;
+    }
+
+    gpio_set_func(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode);
+}
+
+static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return;
+    }
+
+    gpio_set_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id, value);
+}
+
+static int pin_read(struct rt_device *device, rt_base_t pin)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return 0;
+    }
+
+    return gpio_get_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
+}
+
+static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return RT_ERROR;
+    }
+
+    gpio_set_irq_callback(GPIO_CODE_BCM , phypin_index[pin].bcm_id, hdr, args);
+    gpio_set_irq_type(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode);
+
+    return RT_EOK;
+}
+
+static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return RT_ERROR;
+    }
+
+    gpio_clear_irq_callback(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
+
+    return RT_EOK;
+}
+
+rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
+{
+    if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
+    {
+        rt_kprintf("pin:%d value wrongful", pin);
+        return RT_ERROR;
+    }
+
+    if (enabled)
+        gpio_irq_enable(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
+    else
+        gpio_irq_disable(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
+
+    return RT_EOK;
+}
+
+static const struct rt_pin_ops ops =
+{
+    pin_mode,
+    pin_write,
+    pin_read,
+    pin_attach_irq,
+    pin_detach_irq,
+    pin_irq_enable,
+};
+#endif
+
+int rt_hw_gpio_init(void)
+{
+#ifdef BSP_USING_PIN
+    rt_device_pin_register("gpio", &ops, RT_NULL);
+#endif
+
+    /* install ISR */
+    rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO0);
+
+    rt_hw_interrupt_install(IRQ_GPIO1, gpio_irq_handler, &_g_gpio_irq_tbl[1], "gpio1_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO1);
+
+    rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq");
+    rt_hw_interrupt_umask(IRQ_GPIO2);
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_gpio_init);

+ 42 - 0
bsp/raspberry-pi/raspi3-64/driver/drv_gpio.h

@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#ifndef __DRV_GPIO_H__
+#define __DRV_GPIO_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rtdebug.h>
+#include <rtdbg.h>
+
+#include "interrupt.h"
+#include "bcm283x.h"
+#include "raspi.h"
+#include "board.h"
+
+#define GPIO_IRQ_NUM 3
+
+struct gpio_irq_def
+{
+    void  *irq_arg[32];
+    void (*irq_cb[32])(void *param);
+    rt_uint8_t irq_type[32];
+};
+
+enum gpio_irq_clock
+{
+    GPIO_IRQ_LOSC_32KHZ = 0,
+    GPIO_IRQ_HOSC_24MHZ
+};
+
+int rt_hw_gpio_init(void);
+
+#endif /* __DRV_GPIO_H__ */

+ 177 - 0
bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c

@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2019-07-29     zdzn           first version
+ */
+
+#include "drv_i2c.h"
+
+#if defined (BSP_USING_I2C0)
+#define I2C1BUS_NAME  "i2c0"
+#endif /*BSP_USING_I2C0*/
+
+#if defined (BSP_USING_I2C1)
+#define I2C2BUS_NAME  "i2c1"
+#endif /*BSP_USING_I2C1*/
+
+static int i2c_byte_wait_us = 0;
+
+#ifdef BSP_USING_I2C0
+
+static struct raspi_i2c_bus raspi_i2c0 =
+{
+    .device_name = I2C1BUS_NAME,
+};
+
+static struct raspi_master_config_t raspi_i2c0_cfg =
+{
+    .sdl_pin = BCM_GPIO_PIN_0,
+    .scl_pin = BCM_GPIO_PIN_1,
+    .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
+    .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
+    .slave_address = 8,
+    .bsc_base = (PER_BASE + BCM283X_BSC0_BASE),
+    .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148,
+};
+
+#endif /* RT_USING_HW_I2C1 */
+
+#ifdef BSP_USING_I2C1
+static struct raspi_i2c_bus raspi_i2c1 =
+{
+    .device_name = I2C2BUS_NAME,
+};
+
+static struct raspi_master_config_t raspi_i2c1_cfg =
+{
+    .sdl_pin = BCM_GPIO_PIN_2,
+    .scl_pin = BCM_GPIO_PIN_3,
+    .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
+    .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0,
+    .slave_address = 9,
+    .bsc_base = (PER_BASE + BCM283X_BSC1_BASE),
+    .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148,
+};
+#endif /* RT_USING_HW_I2C2 */
+
+#if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1))
+
+static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num);
+static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num);
+static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                      rt_uint32_t,
+                                      rt_uint32_t);
+
+void i2c_master_init(struct raspi_master_config_t *cfg)
+{
+    volatile rt_uint32_t addr;
+    rt_uint32_t data;
+
+    bcm283x_gpio_fsel(cfg->sdl_pin, cfg->sdl_pin_mode); /* SDA */
+    bcm283x_gpio_fsel(cfg->scl_pin, cfg->scl_pin_mode); /* SCL */
+
+    addr = cfg->bsc_base + BCM283X_BSC_DIV;
+    data = bcm283x_peri_read(addr);
+    i2c_byte_wait_us = ( data * 1000000 / BCM283X_CORE_CLK_HZ) * 9;
+
+    addr = cfg->bsc_base + BCM283X_BSC_DIV;
+    bcm283x_peri_write(addr, cfg->clk_div);
+
+    //update
+    i2c_byte_wait_us = (cfg->clk_div * 1000000 * 9 / BCM283X_CORE_CLK_HZ);
+}
+
+static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num)
+{
+    volatile rt_uint32_t addr;
+    struct raspi_i2c_bus *raspi_i2c;
+    rt_size_t i;
+    RT_ASSERT(bus != RT_NULL);
+    raspi_i2c = (struct raspi_i2c_bus *) bus;
+    raspi_i2c->msg = msgs;
+    raspi_i2c->msg_ptr = 0;
+    raspi_i2c->msg_cnt = num;
+    raspi_i2c->dptr = 0;
+
+    addr = raspi_i2c->cfg->bsc_base + BCM283X_BSC_A;
+    bcm283x_peri_write(addr, msgs->addr);
+
+    for (i = 0; i < num; i++)
+    {
+        if ( raspi_i2c->msg[i].flags & RT_I2C_RD )
+        {
+            bcm283x_i2c_read(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num);
+        }
+        else
+        {
+            bcm283x_i2c_write(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num);
+        }
+    }
+    raspi_i2c->msg = RT_NULL;
+    raspi_i2c->msg_ptr = 0;
+    raspi_i2c->msg_cnt = 0;
+    raspi_i2c->dptr = 0;
+    return i;
+}
+
+static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus,
+                                    struct rt_i2c_msg msgs[],
+                                    rt_uint32_t num)
+{
+    return 0;
+}
+static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus,
+                                      rt_uint32_t cmd,
+                                      rt_uint32_t arg)
+{
+    return RT_ERROR;
+}
+
+static const struct rt_i2c_bus_device_ops raspi_i2c_ops =
+{
+    .master_xfer = raspi_i2c_mst_xfer,
+    .slave_xfer = raspi_i2c_slv_xfer,
+    .i2c_bus_control = raspi_i2c_bus_control,
+};
+
+static rt_err_t raspi_i2c_configure(struct raspi_i2c_bus *bus, struct raspi_master_config_t *cfg)
+{
+    RT_ASSERT(bus != RT_NULL);
+    RT_ASSERT(cfg != RT_NULL);
+
+    bus->device.ops = &raspi_i2c_ops;
+    bus->cfg = cfg;
+
+    i2c_master_init(cfg);
+    return RT_EOK;
+}
+#endif
+
+int rt_hw_i2c_init(void)
+{
+
+#if defined(BSP_USING_I2C0)
+    raspi_i2c_configure(&raspi_i2c0 , &raspi_i2c0_cfg);
+    rt_i2c_bus_device_register(&raspi_i2c0.device, raspi_i2c0.device_name);
+#endif  /* BSP_USING_I2C1 */
+
+#if defined(BSP_USING_I2C1)
+
+    raspi_i2c_configure(&raspi_i2c1 , &raspi_i2c1_cfg);
+    rt_i2c_bus_device_register(&raspi_i2c1.device, raspi_i2c1.device_name);
+
+#endif  /* BSP_USING_I2C2 */
+
+    return 0;
+}
+INIT_DEVICE_EXPORT(rt_hw_i2c_init);

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