[bsp] rpi 4b smart & rtos fixups (#7114)

* [bsp] rpi 4b smart & rtos fixups

* [format] remove spaces & modify readme

* [bsp] update rpi4b readme
This commit is contained in:
Shell 2023-03-29 18:31:05 +08:00 committed by GitHub
parent f2dd21ccee
commit adf17c427f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 3663 additions and 2348 deletions

View File

@ -9,32 +9,35 @@
CONFIG_RT_NAME_MAX=8
# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
# CONFIG_RT_USING_SMART is not set
# CONFIG_RT_USING_SMP is not set
CONFIG_RT_ALIGN_SIZE=8
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_TICK_PER_SECOND=1000
CONFIG_RT_USING_OVERFLOW_CHECK=y
CONFIG_RT_USING_HOOK=y
CONFIG_RT_HOOK_USING_FUNC_PTR=y
CONFIG_RT_USING_IDLE_HOOK=y
CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
CONFIG_IDLE_THREAD_STACK_SIZE=4096
CONFIG_IDLE_THREAD_STACK_SIZE=8192
CONFIG_SYSTEM_THREAD_STACK_SIZE=8192
CONFIG_RT_USING_TIMER_SOFT=y
CONFIG_RT_TIMER_THREAD_PRIO=4
CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096
CONFIG_RT_TIMER_THREAD_STACK_SIZE=8192
#
# kservice optimization
#
# CONFIG_RT_KSERVICE_USING_STDLIB is not set
CONFIG_RT_KSERVICE_USING_STDLIB=y
# CONFIG_RT_KSERVICE_USING_STDLIB_MEMORY is not set
# CONFIG_RT_KSERVICE_USING_TINY_SIZE is not set
# CONFIG_RT_USING_TINY_FFS is not set
CONFIG_RT_KPRINTF_USING_LONGLONG=y
CONFIG_RT_DEBUG=y
# CONFIG_RT_DEBUG_COLOR is not set
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
@ -60,13 +63,13 @@ CONFIG_RT_USING_MESSAGEQUEUE=y
# Memory Management
#
CONFIG_RT_PAGE_MAX_ORDER=11
CONFIG_RT_USING_MEMPOOL=y
CONFIG_RT_USING_SMALL_MEM=y
# CONFIG_RT_USING_SLAB is not set
# CONFIG_RT_USING_MEMPOOL is not set
# CONFIG_RT_USING_SMALL_MEM is not set
CONFIG_RT_USING_SLAB=y
# CONFIG_RT_USING_MEMHEAP is not set
CONFIG_RT_USING_SMALL_MEM_AS_HEAP=y
# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set
# CONFIG_RT_USING_MEMHEAP_AS_HEAP is not set
# CONFIG_RT_USING_SLAB_AS_HEAP is not set
CONFIG_RT_USING_SLAB_AS_HEAP=y
# CONFIG_RT_USING_USERHEAP is not set
# CONFIG_RT_USING_NOHEAP is not set
# CONFIG_RT_USING_MEMTRACE is not set
@ -79,13 +82,15 @@ CONFIG_RT_USING_HEAP=y
CONFIG_RT_USING_DEVICE=y
# CONFIG_RT_USING_DEVICE_OPS is not set
# CONFIG_RT_USING_DM is not set
# CONFIG_RT_USING_INTERRUPT_INFO is not set
CONFIG_RT_USING_INTERRUPT_INFO=y
CONFIG_RT_USING_CONSOLE=y
CONFIG_RT_CONSOLEBUF_SIZE=128
CONFIG_RT_CONSOLEBUF_SIZE=256
CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
CONFIG_RT_VER_NUM=0x50000
# CONFIG_RT_USING_STDC_ATOMIC is not set
CONFIG_ARCH_CPU_64BIT=y
CONFIG_RT_USING_CACHE=y
CONFIG_RT_USING_HW_ATOMIC=y
# CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
# CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
# CONFIG_RT_USING_CPU_FFS is not set
@ -99,7 +104,7 @@ CONFIG_ARCH_ARMV8=y
#
CONFIG_RT_USING_COMPONENTS_INIT=y
CONFIG_RT_USING_USER_MAIN=y
CONFIG_RT_MAIN_THREAD_STACK_SIZE=4096
CONFIG_RT_MAIN_THREAD_STACK_SIZE=8192
CONFIG_RT_MAIN_THREAD_PRIORITY=10
# CONFIG_RT_USING_LEGACY is not set
CONFIG_RT_USING_MSH=y
@ -107,7 +112,7 @@ CONFIG_RT_USING_FINSH=y
CONFIG_FINSH_USING_MSH=y
CONFIG_FINSH_THREAD_NAME="tshell"
CONFIG_FINSH_THREAD_PRIORITY=20
CONFIG_FINSH_THREAD_STACK_SIZE=4096
CONFIG_FINSH_THREAD_STACK_SIZE=8192
CONFIG_FINSH_USING_HISTORY=y
CONFIG_FINSH_HISTORY_LINES=5
CONFIG_FINSH_USING_SYMTAB=y
@ -120,9 +125,9 @@ CONFIG_FINSH_ARG_MAX=10
CONFIG_RT_USING_DFS=y
CONFIG_DFS_USING_POSIX=y
CONFIG_DFS_USING_WORKDIR=y
CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
CONFIG_DFS_FD_MAX=16
CONFIG_DFS_FILESYSTEMS_MAX=4
CONFIG_DFS_FILESYSTEM_TYPES_MAX=4
CONFIG_DFS_FD_MAX=32
# CONFIG_RT_USING_DFS_MNTTABLE is not set
CONFIG_RT_USING_DFS_ELMFAT=y
@ -151,7 +156,7 @@ CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_CROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
# CONFIG_RT_USING_DFS_TMPFS is not set
CONFIG_RT_USING_DFS_TMPFS=y
# CONFIG_RT_USING_DFS_NFS is not set
# CONFIG_RT_USING_FAL is not set
@ -169,41 +174,51 @@ CONFIG_RT_USING_SERIAL_V1=y
CONFIG_RT_SERIAL_USING_DMA=y
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
CONFIG_RT_USING_HWTIMER=y
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_I2C=y
# CONFIG_RT_I2C_DEBUG is not set
CONFIG_RT_USING_I2C_BITOPS=y
# CONFIG_RT_I2C_BITOPS_DEBUG is not set
# CONFIG_RT_USING_PHY is not set
CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_ADC is not set
# CONFIG_RT_USING_DAC is not set
# CONFIG_RT_USING_NULL is not set
# CONFIG_RT_USING_ZERO is not set
# CONFIG_RT_USING_RANDOM is not set
CONFIG_RT_USING_NULL=y
CONFIG_RT_USING_ZERO=y
CONFIG_RT_USING_RANDOM=y
# CONFIG_RT_USING_PWM is not set
# CONFIG_RT_USING_MTD_NOR is not set
# CONFIG_RT_USING_MTD_NAND is not set
# CONFIG_RT_USING_PM is not set
# CONFIG_RT_USING_FDT is not set
CONFIG_RT_USING_RTC=y
CONFIG_RT_USING_ALARM=y
# CONFIG_RT_USING_SOFT_RTC is not set
# CONFIG_RT_USING_ALARM is not set
CONFIG_RT_USING_SOFT_RTC=y
CONFIG_RT_USING_SDIO=y
CONFIG_RT_SDIO_STACK_SIZE=512
CONFIG_RT_SDIO_STACK_SIZE=8192
CONFIG_RT_SDIO_THREAD_PRIORITY=15
CONFIG_RT_MMCSD_STACK_SIZE=8192
CONFIG_RT_MMCSD_THREAD_PREORITY=22
CONFIG_RT_MMCSD_MAX_PARTITION=16
# CONFIG_RT_SDIO_DEBUG is not set
# CONFIG_RT_USING_SPI is not set
CONFIG_RT_USING_SPI=y
# CONFIG_RT_USING_SPI_BITOPS is not set
# 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_LCD is not set
CONFIG_RT_USING_TOUCH=y
# CONFIG_RT_TOUCH_PIN_IRQ is not set
CONFIG_RT_USING_LCD=y
# CONFIG_RT_USING_HWCRYPTO is not set
# CONFIG_RT_USING_PULSE_ENCODER is not set
# CONFIG_RT_USING_INPUT_CAPTURE is not set
# CONFIG_RT_USING_DEV_BUS is not set
CONFIG_RT_USING_DEV_BUS=y
# CONFIG_RT_USING_WIFI is not set
# CONFIG_RT_USING_VIRTIO is not set
@ -222,10 +237,18 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
#
# POSIX (Portable Operating System Interface) layer
#
# CONFIG_RT_USING_POSIX_FS is not set
# CONFIG_RT_USING_POSIX_DELAY is not set
# CONFIG_RT_USING_POSIX_CLOCK is not set
# CONFIG_RT_USING_POSIX_TIMER is not set
CONFIG_RT_USING_POSIX_FS=y
CONFIG_RT_USING_POSIX_DEVIO=y
CONFIG_RT_USING_POSIX_STDIO=y
# CONFIG_RT_USING_POSIX_POLL is not set
# CONFIG_RT_USING_POSIX_SELECT is not set
# CONFIG_RT_USING_POSIX_SOCKET is not set
CONFIG_RT_USING_POSIX_TERMIOS=y
# CONFIG_RT_USING_POSIX_AIO is not set
# CONFIG_RT_USING_POSIX_MMAN is not set
CONFIG_RT_USING_POSIX_DELAY=y
CONFIG_RT_USING_POSIX_CLOCK=y
CONFIG_RT_USING_POSIX_TIMER=y
# CONFIG_RT_USING_PTHREADS is not set
# CONFIG_RT_USING_MODULE is not set
@ -254,6 +277,7 @@ CONFIG_SAL_USING_LWIP=y
# CONFIG_SAL_USING_AT is not set
# CONFIG_SAL_USING_TLS is not set
CONFIG_SAL_USING_POSIX=y
# CONFIG_SAL_USING_AF_UNIX is not set
CONFIG_RT_USING_NETDEV=y
CONFIG_NETDEV_USING_IFCONFIG=y
CONFIG_NETDEV_USING_PING=y
@ -266,10 +290,10 @@ CONFIG_NETDEV_IPV6=0
CONFIG_RT_USING_LWIP=y
# CONFIG_RT_USING_LWIP_LOCAL_VERSION is not set
# CONFIG_RT_USING_LWIP141 is not set
CONFIG_RT_USING_LWIP203=y
# CONFIG_RT_USING_LWIP212 is not set
# CONFIG_RT_USING_LWIP203 is not set
CONFIG_RT_USING_LWIP212=y
# CONFIG_RT_USING_LWIP_LATEST is not set
CONFIG_RT_USING_LWIP_VER_NUM=0x20003
CONFIG_RT_USING_LWIP_VER_NUM=0x20102
# CONFIG_RT_USING_LWIP_IPV6 is not set
CONFIG_RT_LWIP_MEM_ALIGNMENT=4
CONFIG_RT_LWIP_IGMP=y
@ -283,30 +307,30 @@ CONFIG_IP_SOF_BROADCAST_RECV=1
#
# Static IPv4 Address
#
CONFIG_RT_LWIP_IPADDR="192.168.1.30"
CONFIG_RT_LWIP_GWADDR="192.168.1.1"
CONFIG_RT_LWIP_IPADDR="192.168.137.100"
CONFIG_RT_LWIP_GWADDR="192.168.137.1"
CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
CONFIG_RT_LWIP_UDP=y
CONFIG_RT_LWIP_TCP=y
CONFIG_RT_LWIP_RAW=y
# CONFIG_RT_LWIP_PPP is not set
CONFIG_RT_MEMP_NUM_NETCONN=8
CONFIG_RT_MEMP_NUM_NETCONN=16
CONFIG_RT_LWIP_PBUF_NUM=16
CONFIG_RT_LWIP_RAW_PCB_NUM=4
CONFIG_RT_LWIP_UDP_PCB_NUM=4
CONFIG_RT_LWIP_TCP_PCB_NUM=4
CONFIG_RT_LWIP_UDP_PCB_NUM=8
CONFIG_RT_LWIP_TCP_PCB_NUM=8
CONFIG_RT_LWIP_TCP_SEG_NUM=40
CONFIG_RT_LWIP_TCP_SND_BUF=8196
CONFIG_RT_LWIP_TCP_WND=8196
CONFIG_RT_LWIP_TCP_SND_BUF=8192
CONFIG_RT_LWIP_TCP_WND=8192
CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=10
CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=8
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=4096
CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=16384
# CONFIG_LWIP_NO_RX_THREAD is not set
# CONFIG_LWIP_NO_TX_THREAD is not set
CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=12
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=4096
CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=16384
CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=8
# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
CONFIG_RT_LWIP_REASSEMBLY_FRAG=y
CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
CONFIG_LWIP_NETIF_LINK_CALLBACK=1
CONFIG_SO_REUSE=1
@ -314,8 +338,8 @@ CONFIG_LWIP_SO_RCVTIMEO=1
CONFIG_LWIP_SO_SNDTIMEO=1
CONFIG_LWIP_SO_RCVBUF=1
CONFIG_LWIP_SO_LINGER=0
# CONFIG_RT_LWIP_NETIF_LOOPBACK is not set
CONFIG_LWIP_NETIF_LOOPBACK=0
CONFIG_RT_LWIP_NETIF_LOOPBACK=y
CONFIG_LWIP_NETIF_LOOPBACK=1
# CONFIG_RT_LWIP_STATS is not set
# CONFIG_RT_LWIP_USING_HW_CHECKSUM is not set
CONFIG_RT_LWIP_USING_PING=y
@ -326,11 +350,11 @@ CONFIG_RT_LWIP_USING_PING=y
#
# Utilities
#
CONFIG_RT_USING_RYM=y
# CONFIG_YMODEM_USING_CRC_TABLE is not set
CONFIG_YMODEM_USING_FILE_TRANSFER=y
# CONFIG_RT_USING_RYM is not set
# CONFIG_RT_USING_ULOG is not set
# CONFIG_RT_USING_UTEST is not set
CONFIG_RT_USING_UTEST=y
CONFIG_UTEST_THR_STACK_SIZE=8192
CONFIG_UTEST_THR_PRIORITY=20
# CONFIG_RT_USING_VAR_EXPORT is not set
CONFIG_RT_USING_ADT=y
# CONFIG_RT_USING_RT_LINK is not set
@ -427,8 +451,6 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_AGILE_FTP is not set
# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
# CONFIG_PKG_USING_RT_LINK_HW is not set
# CONFIG_PKG_USING_RYANMQTT is not set
# CONFIG_PKG_USING_RYANW5500 is not set
# CONFIG_PKG_USING_LORA_PKT_FWD is not set
# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
@ -436,7 +458,6 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_SMALL_MODBUS is not set
# CONFIG_PKG_USING_NET_SERVER is not set
# CONFIG_PKG_USING_ZFTP is not set
# CONFIG_PKG_USING_WOL is not set
#
# security packages
@ -527,6 +548,7 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_SEGGER_RTT is not set
# CONFIG_PKG_USING_RDB is not set
# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
# CONFIG_PKG_USING_ULOG_FILE is not set
# CONFIG_PKG_USING_LOGMGR is not set
# CONFIG_PKG_USING_ADBD is not set
# CONFIG_PKG_USING_COREMARK is not set
@ -560,6 +582,7 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_CBOX is not set
# CONFIG_PKG_USING_SNOWFLAKE is not set
# CONFIG_PKG_USING_HASH_MATCH is not set
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
# CONFIG_PKG_USING_VOFA_PLUS is not set
@ -632,93 +655,19 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_TFDB is not set
# CONFIG_PKG_USING_QPC is not set
# CONFIG_PKG_USING_AGILE_UPGRADE is not set
# CONFIG_PKG_USING_FLASH_BLOB is not set
#
# peripheral libraries and drivers
#
#
# sensors drivers
#
# CONFIG_PKG_USING_LSM6DSM is not set
# CONFIG_PKG_USING_LSM6DSL is not set
# CONFIG_PKG_USING_LPS22HB is not set
# CONFIG_PKG_USING_HTS221 is not set
# CONFIG_PKG_USING_LSM303AGR is not set
# CONFIG_PKG_USING_BME280 is not set
# CONFIG_PKG_USING_BME680 is not set
# CONFIG_PKG_USING_BMA400 is not set
# CONFIG_PKG_USING_BMI160_BMX160 is not set
# CONFIG_PKG_USING_SPL0601 is not set
# CONFIG_PKG_USING_MS5805 is not set
# CONFIG_PKG_USING_DA270 is not set
# CONFIG_PKG_USING_DF220 is not set
# CONFIG_PKG_USING_HSHCAL001 is not set
# CONFIG_PKG_USING_BH1750 is not set
# CONFIG_PKG_USING_MPU6XXX is not set
# CONFIG_PKG_USING_AHT10 is not set
# CONFIG_PKG_USING_AP3216C is not set
# CONFIG_PKG_USING_TSL4531 is not set
# CONFIG_PKG_USING_DS18B20 is not set
# CONFIG_PKG_USING_DHT11 is not set
# CONFIG_PKG_USING_DHTXX is not set
# CONFIG_PKG_USING_GY271 is not set
# CONFIG_PKG_USING_GP2Y10 is not set
# CONFIG_PKG_USING_SGP30 is not set
# CONFIG_PKG_USING_HDC1000 is not set
# CONFIG_PKG_USING_BMP180 is not set
# CONFIG_PKG_USING_BMP280 is not set
# CONFIG_PKG_USING_SHTC1 is not set
# CONFIG_PKG_USING_BMI088 is not set
# CONFIG_PKG_USING_HMC5883 is not set
# CONFIG_PKG_USING_MAX6675 is not set
# CONFIG_PKG_USING_TMP1075 is not set
# CONFIG_PKG_USING_SR04 is not set
# CONFIG_PKG_USING_CCS811 is not set
# CONFIG_PKG_USING_PMSXX is not set
# CONFIG_PKG_USING_RT3020 is not set
# CONFIG_PKG_USING_MLX90632 is not set
# CONFIG_PKG_USING_MLX90393 is not set
# CONFIG_PKG_USING_MLX90392 is not set
# CONFIG_PKG_USING_MLX90397 is not set
# CONFIG_PKG_USING_MS5611 is not set
# CONFIG_PKG_USING_MAX31865 is not set
# CONFIG_PKG_USING_VL53L0X is not set
# CONFIG_PKG_USING_INA260 is not set
# CONFIG_PKG_USING_MAX30102 is not set
# CONFIG_PKG_USING_INA226 is not set
# CONFIG_PKG_USING_LIS2DH12 is not set
# CONFIG_PKG_USING_HS300X is not set
# CONFIG_PKG_USING_ZMOD4410 is not set
# CONFIG_PKG_USING_ISL29035 is not set
# CONFIG_PKG_USING_MMC3680KJ is not set
# CONFIG_PKG_USING_QMP6989 is not set
# CONFIG_PKG_USING_BALANCE is not set
# CONFIG_PKG_USING_SENSORS_DRIVERS is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_SHT2X is not set
# CONFIG_PKG_USING_SHT3X is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_ADT74XX is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_AS7341 is not set
# CONFIG_PKG_USING_CW2015 is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_PAJ7620 is not set
#
# touch drivers
#
# CONFIG_PKG_USING_GT9147 is not set
# CONFIG_PKG_USING_GT1151 is not set
# CONFIG_PKG_USING_GT917S is not set
# CONFIG_PKG_USING_GT911 is not set
# CONFIG_PKG_USING_FT6206 is not set
# CONFIG_PKG_USING_FT5426 is not set
# CONFIG_PKG_USING_FT6236 is not set
# CONFIG_PKG_USING_XPT2046_TOUCH is not set
# CONFIG_PKG_USING_REALTEK_AMEBA is not set
# CONFIG_PKG_USING_STM32_SDIO is not set
# CONFIG_PKG_USING_ESP_IDF is not set
# CONFIG_PKG_USING_ICM20608 is not set
# CONFIG_PKG_USING_BUTTON is not set
# CONFIG_PKG_USING_PCF8574 is not set
# CONFIG_PKG_USING_SX12XX is not set
@ -741,9 +690,12 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_AGILE_LED is not set
# CONFIG_PKG_USING_AT24CXX is not set
# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
# CONFIG_PKG_USING_AD7746 is not set
# CONFIG_PKG_USING_PCA9685 is not set
# CONFIG_PKG_USING_I2C_TOOLS is not set
# CONFIG_PKG_USING_NRF24L01 is not set
# CONFIG_PKG_USING_TOUCH_DRIVERS is not set
# CONFIG_PKG_USING_MAX17048 is not set
# CONFIG_PKG_USING_RPLIDAR is not set
# CONFIG_PKG_USING_AS608 is not set
# CONFIG_PKG_USING_RC522 is not set
@ -758,6 +710,7 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_CAN_YMODEM is not set
# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
# CONFIG_PKG_USING_QLED is not set
# CONFIG_PKG_USING_PAJ7620 is not set
# CONFIG_PKG_USING_AGILE_CONSOLE is not set
# CONFIG_PKG_USING_LD3320 is not set
# CONFIG_PKG_USING_WK2124 is not set
@ -788,11 +741,10 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_BL_MCU_SDK is not set
# CONFIG_PKG_USING_SOFT_SERIAL is not set
# CONFIG_PKG_USING_MB85RS16 is not set
# CONFIG_PKG_USING_CW2015 is not set
# CONFIG_PKG_USING_RFM300 is not set
# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
# CONFIG_PKG_USING_FINGERPRINT is not set
#
# AI packages
@ -807,12 +759,6 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_QUEST is not set
# CONFIG_PKG_USING_NAXOS is not set
#
# Signal Processing and Control Algorithm Packages
#
# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
# CONFIG_PKG_USING_UKAL is not set
#
# miscellaneous packages
#
@ -864,6 +810,7 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_VI is not set
# CONFIG_PKG_USING_KI is not set
# CONFIG_PKG_USING_ARMv7M_DWT is not set
# CONFIG_PKG_USING_UKAL is not set
# CONFIG_PKG_USING_CRCLIB is not set
# CONFIG_PKG_USING_LWGPS is not set
# CONFIG_PKG_USING_STATE_MACHINE is not set
@ -874,7 +821,6 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_SLCAN2RTT is not set
# CONFIG_PKG_USING_SOEM is not set
# CONFIG_PKG_USING_QPARAM is not set
# CONFIG_PKG_USING_CorevMCU_CLI is not set
#
# Arduino libraries
@ -891,17 +837,16 @@ CONFIG_RT_USING_ADT=y
#
# Sensors
#
# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set
# CONFIG_PKG_USING_ADAFRUIT_MAX31855 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
@ -982,7 +927,6 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
@ -994,44 +938,11 @@ CONFIG_RT_USING_ADT=y
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
# CONFIG_PKG_USING_SEEED_ITG3200 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
# CONFIG_PKG_USING_SEEED_MP503 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
#
# Display
#
# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
# CONFIG_PKG_USING_SEEED_TM1637 is not set
#
# Timing
@ -1059,7 +970,6 @@ CONFIG_RT_USING_ADT=y
#
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
#
# Other
@ -1080,68 +990,9 @@ CONFIG_RT_USING_ADT=y
#
# Uncategorized
#
#
# Privated Packages of RealThread
#
# CONFIG_PKG_USING_CODEC is not set
# CONFIG_PKG_USING_PLAYER is not set
# CONFIG_PKG_USING_MPLAYER is not set
# CONFIG_PKG_USING_PERSIMMON_SRC is not set
# CONFIG_PKG_USING_JS_PERSIMMON is not set
# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
#
# Network Utilities
#
# CONFIG_PKG_USING_MDNS is not set
# CONFIG_PKG_USING_UPNP is not set
# CONFIG_PKG_USING_WICED is not set
# CONFIG_PKG_USING_CLOUDSDK is not set
# CONFIG_PKG_USING_POWER_MANAGER is not set
# CONFIG_PKG_USING_RT_OTA is not set
# CONFIG_PKG_USING_RTINSIGHT is not set
# CONFIG_PKG_USING_SMARTCONFIG is not set
# CONFIG_PKG_USING_RTX is not set
# CONFIG_RT_USING_TESTCASE is not set
# CONFIG_PKG_USING_NGHTTP2 is not set
# CONFIG_PKG_USING_AVS is not set
# CONFIG_PKG_USING_ALI_LINKKIT is not set
# CONFIG_PKG_USING_STS is not set
# CONFIG_PKG_USING_DLMS is not set
# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
# CONFIG_PKG_USING_ZBAR is not set
# CONFIG_PKG_USING_MCF is not set
# CONFIG_PKG_USING_URPC is not set
# CONFIG_PKG_USING_DCM is not set
# CONFIG_PKG_USING_EMQ is not set
# CONFIG_PKG_USING_CFGM is not set
# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
# CONFIG_PKG_USING_SMODULE is not set
# CONFIG_PKG_USING_SNFD is not set
# CONFIG_PKG_USING_UDBD is not set
# CONFIG_PKG_USING_BENCHMARK is not set
# CONFIG_PKG_USING_UBJSON is not set
# CONFIG_PKG_USING_DATATYPE is not set
# CONFIG_PKG_USING_FASTFS is not set
# CONFIG_PKG_USING_RIL is not set
# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
# CONFIG_PKG_USING_WATCH_APP_FWK is not set
# CONFIG_PKG_USING_GUI_TEST is not set
# CONFIG_PKG_USING_PMEM is not set
# CONFIG_PKG_USING_LWRDP is not set
# CONFIG_PKG_USING_MASAN is not set
# CONFIG_PKG_USING_BSDIFF_LIB is not set
# CONFIG_PKG_USING_PRC_DIFF is not set
#
# RT-Thread Smart
#
# CONFIG_PKG_USING_UKERNEL is not set
# CONFIG_PKG_USING_TRACE_AGENT is not set
# CONFIG_PKG_USING_DLOG is not set
# CONFIG_PKG_USING_EXT4 is not set
CONFIG_BCM2711_SOC=y
CONFIG_BSP_SUPPORT_FPU=y
# CONFIG_BSP_USING_VM_MODE is not set
#
# Hardware Drivers Config
@ -1153,22 +1004,24 @@ CONFIG_BCM2711_SOC=y
CONFIG_BSP_USING_UART=y
CONFIG_RT_USING_UART0=y
# CONFIG_RT_USING_UART1 is not set
# CONFIG_RT_USING_UART3 is not set
# CONFIG_RT_USING_UART4 is not set
CONFIG_RT_USING_UART3=y
CONFIG_RT_USING_UART4=y
# CONFIG_RT_USING_UART5 is not set
CONFIG_BSP_USING_GIC=y
CONFIG_BSP_USING_GICV2=y
# CONFIG_BSP_USING_GICV3 is not set
CONFIG_BSP_USING_PIN=y
# CONFIG_BSP_USING_SPI is not set
CONFIG_BSP_USING_CORETIMER=y
# CONFIG_BSP_USING_SYSTIMER is not set
# CONFIG_BSP_USING_ETH is not set
CONFIG_BSP_USING_WDT=y
CONFIG_BSP_USING_RTC=y
CONFIG_BSP_USING_ALARM=y
# CONFIG_BSP_USING_RTC is not set
CONFIG_BSP_USING_SDIO=y
CONFIG_BSP_USING_SDIO0=y
#
# Board Peripheral Drivers
#
# CONFIG_BSP_USING_HDMI is not set
CONFIG_BSP_USING_HDMI=y
# CONFIG_BSP_USING_HDMI_DISPLAY is not set
# CONFIG_BSP_USING_TOUCH is not set

View File

@ -21,10 +21,11 @@ source "$PKGS_DIR/Kconfig"
config BCM2711_SOC
bool
select ARCH_ARMV8
select ARCH_ARM_MMU
select RT_USING_CACHE
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select ARCH_CPU_64BIT
default y
source "driver/Kconfig"
source "drivers/Kconfig"

View File

@ -11,61 +11,16 @@
## 2. 编译说明
### 2.1 Window上的环境搭建
Windows环境下推荐使用[env工具](https://www.rt-thread.org/page/download.html)进行编译。
首先下载windows上的aarch64的gcc交叉编译工具版本为gcc-arm-8.3选择aarch64-elf就可以。
将推荐将gcc解压到`\env\tools\gnu_gcc\arm_gcc`目录下。
接着修改`bsp\raspberry-pi\raspi4-64\rtconfig.py`
修改路径:
推荐使用[env工具](https://www.rt-thread.org/page/download.html)可以在console下进入到`bsp\raspberry-pi\raspi4-64`目录中,运行以下命令:
```
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'
scons
```
然后在`bsp\raspberry-pi\raspi4-64\`下输入scons编译即可
来编译这个板级支持包。如果编译正确无误,会产生 `rtthread.elf`, `rtthread.bin` 文件。
**window环境搭建注意**
下载完成`gcc-arm-8.3-2019.03-i686-mingw32-aarch64-elf.tar.xz`交叉编译工具链后最好采用7-zip解压工具进行两次解压。
确保解压目录下的`/bin/aarch64-elf-ld.exe`文件的size不为0。
否则编译会出现如下错误:
```
collect2.exe:fatal error:CreateProcess:No such file or directory
```
### 2.2 Linux上的环境搭建
Linux下推荐使用[gcc工具][2]。Linux版本下gcc版本可采用`gcc-arm-8.3-2019.03-x86_64-aarch64-elf`。
将工具链解压到指定目录,并修改当前bsp下的`EXEC_PATH`为自定义gcc目录。
```
PLATFORM = 'gcc'
EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'
```
直接进入`bsp\raspberry-pi\raspi4-64`输入scons编译即可。
## 3. 执行
### 3.1 下载**Raspberry Pi Imager**生成可以运行的raspbian SD卡
首先下载镜像
* [Raspberry Pi Imager for Ubuntu](https://downloads.raspberrypi.org/imager/imager_amd64.deb)
* [Raspberry Pi Imager for Windows](https://downloads.raspberrypi.org/imager/imager.exe)
* [Raspberry Pi Imager for macOS](https://downloads.raspberrypi.org/imager/imager.dmg)
### 3.2 准备好串口线
## 3. 环境搭建
### 3.1 准备好串口线
目前版本是使用raspi4的 GPIO 14, GPIO 15来作路口输出连线情况如下图所示
@ -73,27 +28,61 @@ EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'
串口参数: 115200 8N1 ,硬件和软件流控为关。
### 3.3 程序下载
### 3.2 RTT固件放在SD卡运行
当编译生成了rtthread.bin文件后我们可以将该文件放到sd卡上并修改sd卡中的`config.txt`文件如下:
暂时不支持,需要使用 u-boot 加载。
### 3.3 RTT程序用uboot加载
此 bsp 的 `tools` 下可以找到 [u-boot64.bin](./tools/u-boot64.bin) 和 [config.txt](./tools/config.txt) 两个文件。将其与准备好的 sd 卡中文件替换即可。sd 卡推荐通过树莓派 [imager](https://www.raspberrypi.com/software/) 制作。
需要注意的以下步骤:
**1.电脑上启动tftp服务器**
windows系统电脑上可以安装tftpd搭建tftp服务器。将目录指定到`bsp\raspberry-pi\raspi4-64`。
**2.修改设置uboot**
在控制台输入下列命令:
```
enable_uart=1
arm_64bit=1
kernel=rtthread.bin
core_freq=250
setenv bootcmd "dhcp 0x00208000 x.x.x.x:rtthread.bin;dcache flush;go 0x00208000"
saveenv
reset
```
按上面的方法做好SD卡后插入树莓派4通电可以在串口上看到如下所示的输出信息
其中`x.x.x.x`为tftp服务器的pc的ip地址。
```text
heap: 0x000c9350 - 0x040c9350
**3.修改链接脚本**
链接脚本会在 python 脚本中自行替换,不用处理
**3.插入网线**
上述准备完成后将网线插入保证开发板和tftp服务器在同一个网段的路由器上。上电后uboot可以自动从tftp服务器上获取固件然后开始执行了。
完成后可以看到串口的输出信息
```
\ | /
- RT - Thread Operating System
/ | \ 4.0.3 build Apr 16 2020
2006 - 2020 Copyright by rt-thread team
Hi, this is RT-Thread!!
/ | \ 5.0.0 build Mar 29 2023 10:56:23
2006 - 2022 Copyright by RT-Thread team
lwIP-2.1.2 initialized!
EMMC: assuming clock rate to be 100MHz
[I/sal.skt] Socket Abstraction Layer initialize success.
[I/utest] utest is initialize success.
[I/utest] total utest testcase num: (0)
[I/DBG] version is B1
[I/SDIO] SD card capacity 31166976 KB.
found part[0], begin: 4194304, size: 256.0MB
found part[1], begin: 272629760, size: 3.856GB
file system initialization done!
cpu 2 boot success
cpu 1 boot success
cpu 3 boot success
msh />
```
@ -103,11 +92,18 @@ msh />
| ------ | ---- | :------: |
| UART | 支持 | UART0,UART2,UART3,UART4,UART5 |
| GPIO | 支持 | - |
| SPI | 支持 | SPI0 |
| MAILBOX | 支持 | - |
| WATCHDOG | 支持 | - |
| HDMI | 支持 | - |
| SDIO | 支持 | - |
| ETH | 支持 | - |
## 5. 联系人信息
## 5. 注意事项
目前rt-thread程序可以使用的内存在100MB以内可以通过调整`board.c`中`platform_mem_desc`表的数据进行相关内存的映射以及修改`board.h`来确定程序使用的堆栈大小。
## 6. 联系人信息
维护人:[bernard][5]

View File

@ -18,13 +18,17 @@ env = Environment(tools = ['mingw'],
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
env['ASCOM'] = env['ASPPCOM']
env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
objs = PrepareBuilding(env, RTT_ROOT)
if GetDepend('RT_USING_SMART'):
# use smart link.lds
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
# make a building
DoBuilding(TARGET, objs)

View File

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

View File

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

View File

@ -1,172 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2021-12-28 GuEe-GUI add smp support
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "drv_uart.h"
#include "mmu.h"
#include "gic.h"
#include "gtimer.h"
#include "cpuport.h"
#include "interrupt.h"
#include "mbox.h"
struct mem_desc platform_mem_desc[] =
{
{0, 0x6400000, 0, NORMAL_MEM},
{0xFE200000, 0xFE400000, 0xFE200000, DEVICE_MEM}, /* uart gpio */
{0xFF800000, 0xFFA00000, 0xFF800000, DEVICE_MEM}, /* gic timer */
{WDT_BASE, WDT_BASE + 0x1000, WDT_BASE, DEVICE_MEM}, /* wdt */
{MBOX_ADDR, MBOX_ADDR + 0x200000, MBOX_ADDR, DEVICE_MEM}, /* mbox msg */
{STIMER_BASE, STIMER_BASE + 0x200000, STIMER_BASE, DEVICE_MEM}, /* stimer */
{MAC_BASE_ADDR, MAC_BASE_ADDR + 0x80000, MAC_BASE_ADDR, DEVICE_MEM}, /* mac */
{MMC2_BASE_ADDR, MMC2_BASE_ADDR + 0x200000, MMC2_BASE_ADDR, DEVICE_MEM}, /* mmc */
{ARM_TIMER_BASE, ARM_TIMER_BASE + 0x200000, ARM_TIMER_BASE, DEVICE_MEM}, /* arm timer */
{SEND_DATA_NO_CACHE, SEND_DATA_NO_CACHE + 0x200000, SEND_DATA_NO_CACHE, NORMAL_MEM}, /* eth send */
{RECV_DATA_NO_CACHE, RECV_DATA_NO_CACHE + 0x200000, RECV_DATA_NO_CACHE, NORMAL_MEM}, /* eth recv */
};
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
#if !defined(BSP_USING_CORETIMER) && !defined(RT_USING_SMP)
void rt_hw_timer_isr(int vector, void *parameter)
{
ARM_TIMER_IRQCLR = 0;
rt_tick_increase();
}
#endif
void rt_hw_timer_init(void)
{
#if defined(BSP_USING_CORETIMER) || defined(RT_USING_SMP)
rt_hw_gtimer_init();
core_timer_enable(0);
#else
rt_uint32_t apb_clock = 0;
rt_uint32_t timer_clock = 1000000;
apb_clock = bcm271x_mbox_clock_get_rate(CORE_CLK_ID);
ARM_TIMER_PREDIV = (apb_clock/timer_clock - 1);
ARM_TIMER_RELOAD = 0;
ARM_TIMER_LOAD = 0;
ARM_TIMER_IRQCLR = 1;
ARM_TIMER_CTRL = 0;
ARM_TIMER_RELOAD = 1000000 / RT_TICK_PER_SECOND;
ARM_TIMER_LOAD = 1000000 / RT_TICK_PER_SECOND;
/* 23-bit counter, enable interrupt, enable timer */
ARM_TIMER_CTRL = (1 << 1) | (1 << 5) | (1 << 7);
rt_hw_interrupt_install(ARM_TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(ARM_TIMER_IRQ);
#endif
}
void idle_wfi(void)
{
asm volatile ("wfi");
}
/**
* Initialize the Hardware related stuffs. Called from rtthread_startup()
* after interrupt disabled.
*/
void rt_hw_board_init(void)
{
extern void *MMUTable;
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x80000000, 0x10000000, MMUTable, 0);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* initialize hardware interrupt */
rt_hw_interrupt_init(); // in libcpu/interrupt.c. Set some data structures, no operation on device
/* initialize uart */
rt_hw_uart_init(); // driver/drv_uart.c
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
#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
/* initialize timer for os tick */
rt_hw_timer_init();
rt_thread_idle_sethook(idle_wfi);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_SMP
/* install IPI handle */
rt_hw_ipi_handler_install(IRQ_ARM_IPI_KICK, rt_scheduler_ipi_handler);
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
#endif
}
#ifdef RT_USING_SMP
static unsigned long cpu_release_paddr[] =
{
[0] = 0xd8,
[1] = 0xe0,
[2] = 0xe8,
[3] = 0xf0,
[4] = 0
};
void rt_hw_secondary_cpu_up(void)
{
int i;
extern void secondary_cpu_start(void);
for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
{
__asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)secondary_cpu_start), "r"(cpu_release_paddr[i]));
rt_hw_dcache_flush_range(cpu_release_paddr[i], sizeof(cpu_release_paddr[i]));
__DSB();
__SEV();
}
}
void secondary_cpu_c_start(void)
{
int id;
rt_hw_mmu_init();
id = rt_hw_cpu_id();
rt_hw_spin_lock(&_cpus_lock);
arm_gic_cpu_init(0, platform_get_gic_cpu_base());
rt_hw_vector_init();
rt_hw_gtimer_local_enable();
core_timer_enable(id);
arm_gic_umask(0, IRQ_ARM_IPI_KICK);
rt_kprintf("\rcall cpu %d on success\n", id);
rt_system_scheduler_start();
}
void rt_hw_secondary_cpu_idle_exec(void)
{
__WFE();
}
#endif

View File

@ -1,30 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
*/
#ifndef BOARD_H__
#define BOARD_H__
#include <stdint.h>
#include "raspi4.h"
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 + 64 * 1024 * 1024)
#ifndef RT_USING_SMART
#define PV_OFFSET 0
#define KERNEL_VADDR_START 0
#endif
void rt_hw_board_init(void);
#endif

View File

@ -1,216 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-30 bigmagic first version
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
#define MAC_REG (void *)(0xfd580000)
#define SYS_REV_CTRL (0x00)
#define SYS_PORT_CTRL (0x04)
#define PORT_MODE_EXT_GPHY (3)
#define GENET_SYS_OFF (0x0000)
#define SYS_RBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x08)
#define SYS_TBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x0c)
#define GENET_EXT_OFF (0x0080)
#define EXT_RGMII_OOB_CTRL (GENET_EXT_OFF + 0x0c)
#define RGMII_LINK BIT(4)
#define OOB_DISABLE BIT(5)
#define RGMII_MODE_EN BIT(6)
#define ID_MODE_DIS BIT(16)
#define GENET_RBUF_OFF (0x0300)
#define RBUF_TBUF_SIZE_CTRL (GENET_RBUF_OFF + 0xb4)
#define RBUF_CTRL (GENET_RBUF_OFF + 0x00)
#define RBUF_ALIGN_2B BIT(1)
#define GENET_UMAC_OFF (0x0800)
#define UMAC_MIB_CTRL (GENET_UMAC_OFF + 0x580)
#define UMAC_MAX_FRAME_LEN (GENET_UMAC_OFF + 0x014)
#define UMAC_MAC0 (GENET_UMAC_OFF + 0x00c)
#define UMAC_MAC1 (GENET_UMAC_OFF + 0x010)
#define UMAC_CMD (GENET_UMAC_OFF + 0x008)
#define MDIO_CMD (GENET_UMAC_OFF + 0x614)
#define UMAC_TX_FLUSH (GENET_UMAC_OFF + 0x334)
#define MDIO_START_BUSY BIT(29)
#define MDIO_READ_FAIL BIT(28)
#define MDIO_RD (2 << 26)
#define MDIO_WR BIT(26)
#define MDIO_PMD_SHIFT (21)
#define MDIO_PMD_MASK (0x1f)
#define MDIO_REG_SHIFT (16)
#define MDIO_REG_MASK (0x1f)
#define GENET_INTRL2_OFF (0x0200)
#define GENET_INTRL2_CPU_STAT (GENET_INTRL2_OFF + 0x00)
#define GENET_INTRL2_CPU_CLEAR (GENET_INTRL2_OFF + 0x08)
#define GENET_INTRL2_CPU_STAT_MASK (GENET_INTRL2_OFF + 0x0c)
#define GENET_INTRL2_CPU_SET_MASK (GENET_INTRL2_OFF + 0x10)
#define GENET_INTRL2_CPU_CLEAR_MASK (GENET_INTRL2_OFF + 0x14)
#define GENET_IRQ_MDIO_ERROR BIT(24)
#define GENET_IRQ_MDIO_DONE BIT(23)
#define GENET_IRQ_TXDMA_DONE BIT(16)
#define GENET_IRQ_RXDMA_DONE BIT(13)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define UMAC_SPEED_10 (0)
#define UMAC_SPEED_100 (1)
#define UMAC_SPEED_1000 (2)
#define UMAC_SPEED_2500 (3)
#define CMD_SPEED_SHIFT (2)
#define CMD_SPEED_MASK (3)
#define CMD_SW_RESET BIT(13)
#define CMD_LCL_LOOP_EN BIT(15)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define MIB_RESET_RX BIT(0)
#define MIB_RESET_RUNT BIT(1)
#define MIB_RESET_TX BIT(2)
/* total number of Buffer Descriptors, same for Rx/Tx */
#define TOTAL_DESCS (256)
#define RX_DESCS TOTAL_DESCS
#define TX_DESCS TOTAL_DESCS
#define DEFAULT_Q (0x10)
#define ETH_DATA_LEN (1500)
#define ETH_HLEN (14)
#define VLAN_HLEN (4)
#define ETH_FCS_LEN (4)
/*
* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
* 1536 is multiple of 256 bytes
*/
#define ENET_BRCM_TAG_LEN (6)
#define ENET_PAD (8)
#define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
/* Tx/Rx Dma Descriptor common bits */
#define DMA_EN BIT(0)
#define DMA_RING_BUF_EN_SHIFT (0x01)
#define DMA_RING_BUF_EN_MASK (0xffff)
#define DMA_BUFLENGTH_MASK (0x0fff)
#define DMA_BUFLENGTH_SHIFT (16)
#define DMA_RING_SIZE_SHIFT (16)
#define DMA_OWN (0x8000)
#define DMA_EOP (0x4000)
#define DMA_SOP (0x2000)
#define DMA_WRAP (0x1000)
#define DMA_MAX_BURST_LENGTH (0x8)
/* Tx specific DMA descriptor bits */
#define DMA_TX_UNDERRUN (0x0200)
#define DMA_TX_APPEND_CRC (0x0040)
#define DMA_TX_OW_CRC (0x0020)
#define DMA_TX_DO_CSUM (0x0010)
#define DMA_TX_QTAG_SHIFT (7)
/* DMA rings size */
#define DMA_RING_SIZE (0x40)
#define DMA_RINGS_SIZE (DMA_RING_SIZE * (DEFAULT_Q + 1))
/* DMA descriptor */
#define DMA_DESC_LENGTH_STATUS (0x00)
#define DMA_DESC_ADDRESS_LO (0x04)
#define DMA_DESC_ADDRESS_HI (0x08)
#define DMA_DESC_SIZE (12)
#define GENET_RX_OFF (0x2000)
#define GENET_RDMA_REG_OFF (GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define GENET_TX_OFF (0x4000)
#define GENET_TDMA_REG_OFF (GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define DMA_FC_THRESH_HI (RX_DESCS >> 4)
#define DMA_FC_THRESH_LO (5)
#define DMA_FC_THRESH_VALUE ((DMA_FC_THRESH_LO << 16) | DMA_FC_THRESH_HI)
#define DMA_XOFF_THRESHOLD_SHIFT (16)
#define TDMA_RING_REG_BASE (GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define TDMA_READ_PTR (TDMA_RING_REG_BASE + 0x00)
#define TDMA_CONS_INDEX (TDMA_RING_REG_BASE + 0x08)
#define TDMA_PROD_INDEX (TDMA_RING_REG_BASE + 0x0c)
#define DMA_RING_BUF_SIZE (0x10)
#define DMA_START_ADDR (0x14)
#define DMA_END_ADDR (0x1c)
#define DMA_MBUF_DONE_THRESH (0x24)
#define TDMA_FLOW_PERIOD (TDMA_RING_REG_BASE + 0x28)
#define TDMA_WRITE_PTR (TDMA_RING_REG_BASE + 0x2c)
#define RDMA_RING_REG_BASE (GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define RDMA_WRITE_PTR (RDMA_RING_REG_BASE + 0x00)
#define RDMA_PROD_INDEX (RDMA_RING_REG_BASE + 0x08)
#define RDMA_CONS_INDEX (RDMA_RING_REG_BASE + 0x0c)
#define RDMA_XON_XOFF_THRESH (RDMA_RING_REG_BASE + 0x28)
#define RDMA_READ_PTR (RDMA_RING_REG_BASE + 0x2c)
#define TDMA_REG_BASE (GENET_TDMA_REG_OFF + DMA_RINGS_SIZE)
#define RDMA_REG_BASE (GENET_RDMA_REG_OFF + DMA_RINGS_SIZE)
#define DMA_RING_CFG (0x00)
#define DMA_CTRL (0x04)
#define DMA_SCB_BURST_SIZE (0x0c)
#define RX_BUF_LENGTH (2048)
#define RX_TOTAL_BUFSIZE (RX_BUF_LENGTH * RX_DESCS)
#define RX_BUF_OFFSET (2)
#define PHY_INTERFACE_MODE_RGMII (7)
#define PHY_INTERFACE_MODE_RGMII_RXID (9)
#define BCM54213PE_MII_CONTROL (0x00)
#define BCM54213PE_MII_STATUS (0x01)
#define BCM54213PE_PHY_IDENTIFIER_HIGH (0x02)
#define BCM54213PE_PHY_IDENTIFIER_LOW (0x03)
#define BCM54213PE_AUTO_NEGOTIATION_ADV (0x04)
#define BCM54213PE_AUTO_NEGOTIATION_LINK (0x05)
#define BCM54213PE_AUTO_NEGOTIATION_EXPANSION (0x06)
#define BCM54213PE_NEXT_PAGE_TX (0x07)
#define BCM54213PE_PARTNER_RX (0x08)
#define BCM54213PE_CONTROL (0x09)
#define BCM54213PE_STATUS (0x0A)
#define BCM54213PE_IEEE_EXTENDED_STATUS (0x0F)
#define BCM54213PE_PHY_EXTENDED_CONTROL (0x10)
#define BCM54213PE_PHY_EXTENDED_STATUS (0x11)
#define BCM54213PE_RECEIVE_ERROR_COUNTER (0x12)
#define BCM54213PE_FALSE_C_S_COUNTER (0x13)
#define BCM54213PE_RECEIVE_NOT_OK_COUNTER (0x14)
#define BCM54213PE_VERSION_B1 (0x600d84a2)
#define BCM54213PE_VERSION_X (0x600d84a0)
//BCM54213PE_MII_CONTROL
#define MII_CONTROL_PHY_RESET (1 << 15)
#define MII_CONTROL_AUTO_NEGOTIATION_ENABLED (1 << 12)
#define MII_CONTROL_AUTO_NEGOTIATION_RESTART (1 << 9)
#define MII_CONTROL_PHY_FULL_DUPLEX (1 << 8)
#define MII_CONTROL_SPEED_SELECTION (1 << 6)
//BCM54213PE_MII_STATUS
#define MII_STATUS_LINK_UP (1 << 2)
//BCM54213PE_CONTROL
#define CONTROL_FULL_DUPLEX_CAPABILITY (1 << 9)
#define CONTROL_HALF_DUPLEX_CAPABILITY (1 << 8)
#define SPEED_1000 (1000)
#define SPEED_100 (100)
#define SPEED_10 (10)
#endif/* __DRV_ETH_H__ */

View File

@ -1,187 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
*/
#include "drv_gpio.h"
#ifdef BSP_USING_PIN
uint32_t raspi_get_pin_state(uint32_t fselnum)
{
uint32_t gpfsel = 0;
switch (fselnum)
{
case 0:
gpfsel = GPIO_REG_GPFSEL0(GPIO_BASE);
break;
case 1:
gpfsel = GPIO_REG_GPFSEL1(GPIO_BASE);
break;
case 2:
gpfsel = GPIO_REG_GPFSEL2(GPIO_BASE);
break;
case 3:
gpfsel = GPIO_REG_GPFSEL3(GPIO_BASE);
break;
case 4:
gpfsel = GPIO_REG_GPFSEL4(GPIO_BASE);
break;
case 5:
gpfsel = GPIO_REG_GPFSEL5(GPIO_BASE);
break;
default:
break;
}
return gpfsel;
}
void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel)
{
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(GPIO_BASE) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(GPIO_BASE) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(GPIO_BASE) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(GPIO_BASE) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(GPIO_BASE) = gpfsel;
break;
default:
break;
}
}
static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(GPIO_BASE) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(GPIO_BASE) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(GPIO_BASE) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(GPIO_BASE) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(GPIO_BASE) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(GPIO_BASE) = gpfsel;
break;
default:
break;
}
}
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel = raspi_get_pin_state(fselnum);
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
raspi_set_pin_state(fselnum, gpfsel);
}
static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
uint32_t num = pin / 32;
if(num == 0)
{
if(value == 0)
{
GPIO_REG_GPSET0(GPIO_BASE) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR0(GPIO_BASE) = 1 << (pin % 32);
}
}
else
{
if(value == 0)
{
GPIO_REG_GPSET1(GPIO_BASE) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR1(GPIO_BASE) = 1 << (pin % 32);
}
}
}
static int raspi_pin_read(struct rt_device *device, rt_base_t pin)
{
return 0;
}
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)
{
return RT_EOK;
}
static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
return RT_EOK;
}
rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
return RT_EOK;
}
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,
RT_NULL,
};
#endif
int rt_hw_gpio_init(void)
{
#ifdef BSP_USING_PIN
rt_device_pin_register("gpio", &ops, RT_NULL);
#endif
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_gpio_init);

View File

@ -1,268 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-27 bigmagic first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#include "board.h"
#include "raspi4.h"
/* 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
{
size_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_CAPABILITIES_0 (0x40)
#define EMMC_CAPABILITIES_1 (0x44)
#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)
#define SD_RESP_R1b (SD_CMD_RSPNS_TYPE_48B)
#define SD_RESP_R2 (SD_CMD_RSPNS_TYPE_136)
#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

View File

@ -1,188 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-09-10 bigmagic first version
*/
#ifndef __MBOX_H__
#define __MBOX_H__
#include <rtthread.h>
#include <stdint.h>
// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
// https://github.com/hermanhermitage/videocoreiv
/* 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_TAG_LAST 0
#define MMIO_BASE 0xFE000000
#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)
/*
* raspi hardware info
*/
enum
{
MBOX_TAG_HARDWARE_GET_MODEL = 0x00010001,
MBOX_TAG_HARDWARE_GET_REV = 0x00010002,
MBOX_TAG_HARDWARE_GET_MAC_ADDRESS = 0x00010003,
MBOX_TAG_HARDWARE_GET_SERIAL = 0x00010004,
MBOX_TAG_HARDWARE_GET_ARM_MEMORY = 0x00010005,
MBOX_TAG_HARDWARE_GET_VC_MEMORY = 0x00010006,
MBOX_TAG_HARDWARE_GET_CLOCKS = 0x00010007,
};
/*
* raspi clock
*/
enum
{
MBOX_TAG_CLOCK_GET_TURBO = 0x00030009,
MBOX_TAG_CLOCK_SET_TURBO = 0x00038009,
MBOX_TAG_CLOCK_GET_STATE = 0x00030001,
MBOX_TAG_CLOCK_SET_STATE = 0x00038001,
MBOX_TAG_CLOCK_GET_RATE = 0x00030002,
MBOX_TAG_CLOCK_SET_RATE = 0x00038002,
MBOX_TAG_CLOCK_GET_MAX_RATE = 0x00030004,
MBOX_TAG_CLOCK_GET_MIN_RATE = 0x00030007,
};
/*
* raspi power
*/
enum
{
MBOX_TAG_POWER_GET_STATE = 0x00020001,
MBOX_TAG_POWER_SET_STATE = 0x00028001,
};
/*
* raspi temperature
*/
enum
{
MBOX_TAG_TEMP_GET = 0x00030006,
MBOX_TAG_TEMP_GET_MAX = 0x0003000A,
};
/*
* raspi Memory
*/
enum
{
MBOX_TAG_ALLOCATE_MEMORY = 0x0003000C, // Memory: Allocates Contiguous Memory On The GPU (Response: Handle)
MBOX_TAG_LOCK_MEMORY = 0x0003000D, // Memory: Unlock Buffer (Response: Status)
MBOX_TAG_UNLOCK_MEMORY = 0x0003000E, // Memory: Unlock Buffer (Response: Status)
MBOX_TAG_RELEASE_MEMORY = 0x0003000F, // Memory: Free The Memory Buffer (Response: Status)
MBOX_TAG_EXECUTE_CODE = 0x00030010, // Memory: Calls The Function At Given (Bus) Address And With Arguments Given
};
/*
* raspi GPU
*/
enum
{
MBOX_TAG_EXECUTE_QPU = 0x00030011, // QPU: Calls The QPU Function At Given (Bus) Address And With Arguments Given
// (Response: Number Of QPUs, Control, No Flush, Timeout In ms)
MBOX_TAG_ENABLE_QPU = 0x00030012, // QPU: Enables The QPU (Response: Enable State)
};
/*
* raspi HDMI
*/
#define MBOX_TAG_GET_EDID_BLOCK 0x00030020 // HDMI: Read Specificed EDID Block From Attached HDMI/DVI Device
// (Response: Block Number, Status, EDID Block (128 Bytes))
/*
* raspi NOTIFY
*/
#define MBOX_TAG_NOTIFY_REBOOT 0x00030048
#define MBOX_TAG_NOTIFY_XHCI_RESET 0x00030058
/*
* touch
*/
#define MBOX_TAG_GET_TOUCHBUF (0x0004000F)
#define MBOX_ADDR 0x08000000
#define RES_CLK_ID (0x000000000)
#define EMMC_CLK_ID (0x000000001)
#define UART_CLK_ID (0x000000002)
#define ARM_CLK_ID (0x000000003)
#define CORE_CLK_ID (0x000000004)
#define V3D_CLK_ID (0x000000005)
#define H264_CLK_ID (0x000000006)
#define ISP_CLK_ID (0x000000007)
#define SDRAM_CLK_ID (0x000000008)
#define PIXEL_CLK_ID (0x000000009)
#define PWM_CLK_ID (0x00000000a)
int mbox_call(unsigned char ch, int mmu_enable);
int bcm271x_mbox_poweroff_devices(int id);
int bcm271x_mbox_get_touch(void);
int bcm271x_notify_reboot(void);
int bcm271x_notify_xhci_reset(void);
int bcm271x_gpu_enable(void);
int bcm271x_mbox_hardware_get_model(void);
int bcm271x_mbox_hardware_get_revison(void);
int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac);
int bcm271x_mbox_hardware_get_serial(rt_uint64_t *sn);
int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t *base, rt_uint32_t *size);
int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t *base, rt_uint32_t *size);
int bcm271x_mbox_clock_get_turbo(void);
int bcm271x_mbox_clock_set_turbo(int level);
int bcm271x_mbox_clock_get_state(int id);
int bcm271x_mbox_clock_set_state(int id, int state);
int bcm271x_mbox_clock_get_rate(int id);
int bcm271x_mbox_clock_set_rate(int id, int rate);
int bcm271x_mbox_clock_get_max_rate(int id);
int bcm271x_mbox_clock_get_min_rate(int id);
int bcm271x_mbox_power_get_state(int id);
int bcm271x_mbox_power_set_state(int id, int state);
int bcm271x_mbox_temp_get(void);
int bcm271x_mbox_temp_get_max(void);
#endif

View File

@ -1,167 +0,0 @@
#ifndef __RASPI4_H__
#define __RASPI4_H__
#include <rthw.h>
#define __REG32(x) (*((volatile unsigned int *)(x)))
//base address
#define PER_BASE (0xFE000000)
//gpio offset
#define GPIO_BASE_OFFSET (0x00200000)
//pl011 offset
#define PL011_UART_BASE_OFFSET (0x00201000)
//pactl cs offset
#define PACTL_CS_OFFSET (0x00204E00)
//aux offset
#define AUX_BASE_OFFSET (0x00215000)
//gpio
#define GPIO_BASE (PER_BASE + GPIO_BASE_OFFSET)
#define GPIO_IRQ_NUM (3) //40 pin mode
#define IRQ_GPIO0 (96 + 49) //bank0 (0 to 27)
#define IRQ_GPIO1 (96 + 50) //bank1 (28 to 45)
#define IRQ_GPIO2 (96 + 51) //bank2 (46 to 57)
#define IRQ_GPIO3 (96 + 52) //bank3
//system timer
#define ARM_TIMER_IRQ (64)
#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)
//uart
#define UART_BASE (PER_BASE + PL011_UART_BASE_OFFSET)
#define UART0_BASE (UART_BASE + 0x0)
#define UART2_BASE (UART_BASE + 0x400)
#define UART3_BASE (UART_BASE + 0x600)
#define UART4_BASE (UART_BASE + 0x800)
#define UART5_BASE (UART_BASE + 0xA00)
#define IRQ_AUX_UART (96 + 29)
#define UART_REFERENCE_CLOCK (48000000)
//aux
#define AUX_BASE (PER_BASE + AUX_BASE_OFFSET)
#define IRQ_PL011 (96 + 57)
//pactl cs
#define PACTL_CS_ADDR (PER_BASE + PACTL_CS_OFFSET)
#define PACTL_CS HWREG32(PACTL_CS_ADDR)
typedef enum
{
IRQ_SPI0 = 0x00000000,
IRQ_SPI1 = 0x00000002,
IRQ_SPI2 = 0x00000004,
IRQ_SPI3 = 0x00000008,
IRQ_SPI4 = 0x00000010,
IRQ_SPI5 = 0x00000020,
IRQ_SPI6 = 0x00000040,
IRQ_I2C0 = 0x00000100,
IRQ_I2C1 = 0x00000200,
IRQ_I2C2 = 0x00000400,
IRQ_I2C3 = 0x00000800,
IRQ_I2C4 = 0x00001000,
IRQ_I2C5 = 0x00002000,
IRQ_I2C6 = 0x00004000,
IRQ_I2C7 = 0x00008000,
IRQ_UART5 = 0x00010000,
IRQ_UART4 = 0x00020000,
IRQ_UART3 = 0x00040000,
IRQ_UART2 = 0x00080000,
IRQ_UART0 = 0x00100000
} PACTL_CS_VAL;
// 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
#define CORE_TIMER_IRQ_CTRL(n) HWREG32((unsigned long)(0xFF800040 + (n) * 4))
#define TIMER_IRQ 30
#define NON_SECURE_TIMER_IRQ (1 << 1)
rt_inline void core_timer_enable(int cpu_id)
{
CORE_TIMER_IRQ_CTRL(cpu_id) |= NON_SECURE_TIMER_IRQ;
}
//core timer
#define ST_BASE_OFFSET (0x003000)
#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) \
//mmc
#define MMC0_BASE_ADDR (PER_BASE + 0x300000)
#define MMC2_BASE_ADDR (PER_BASE + 0x340000)
//eth
#define MAC_BASE_ADDR (0xfd580000)
#define MAC_REG_BASE_ADDR (void *)(MAC_BASE_ADDR)
#define ETH_IRQ (160 + 29)
#define SEND_DATA_NO_CACHE (0x08200000)
#define RECV_DATA_NO_CACHE (0x08400000)
//watchdog
#define WDT_BASE (PER_BASE + 0x00100000)
#define PM_RSTC HWREG32(WDT_BASE + 0x0000001c)
#define PM_RSTS HWREG32(WDT_BASE + 0x00000020)
#define PM_WDOG HWREG32(WDT_BASE + 0x00000024)
#define PM_PASSWORD (0x5A000000)
#define PM_WDOG_TIME_SET (0x000fffff)
#define PM_RSTS_HADWRH_SET (0x00000040)
#define PM_RSTC_WRCFG_FULL_RESET (0x00000020)
#define PM_RSTC_WRCFG_CLR (0xffffffcf)
#define PM_RSTC_RESET (0x00000102)
//gic max
#define MAX_HANDLERS (256)
#define ARM_GIC_NR_IRQS (512)
#define INTC_BASE (0xff800000)
#define ARM_GIC_MAX_NR (512)
#define GIC_V2_BASE (INTC_BASE + 0x00040000)
#define GIC_V2_DISTRIBUTOR_BASE (INTC_BASE + 0x00041000)
#define GIC_V2_CPU_INTERFACE_BASE (INTC_BASE + 0x00042000)
#define GIC_V2_HYPERVISOR_BASE (INTC_BASE + 0x00044000)
#define GIC_V2_VIRTUAL_CPU_BASE (INTC_BASE + 0x00046000)
/* ipi interrupt number */
#define IRQ_ARM_IPI_KICK 0
#define IRQ_ARM_IPI_CALL 1
#define GIC_IRQ_START 0
#define GIC_ACK_INTID_MASK 0x000003ff
#define GIC_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE
#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE
/* the basic constants and interfaces needed by gic */
rt_inline rt_uint32_t platform_get_gic_dist_base(void)
{
return GIC_PL400_DISTRIBUTOR_PPTR;
}
rt_inline rt_uint32_t platform_get_gic_cpu_base(void)
{
return GIC_PL400_CONTROLLER_PPTR;
}
#endif

View File

@ -1,3 +1,12 @@
config BSP_SUPPORT_FPU
bool "Using Float"
default n
menuconfig BSP_USING_VM_MODE
bool "Enable VM mode"
default n
menu "Hardware Drivers Config"
menu "BCM Peripheral Drivers"
menuconfig BSP_USING_UART
@ -27,19 +36,43 @@ menu "Hardware Drivers Config"
default n
endif
config BSP_USING_GIC
bool
menuconfig BSP_USING_GIC
bool "Enable GIC"
select RT_USING_GIC
default y
if BSP_USING_GIC
config BSP_USING_GICV2
bool
bool "Enable GIC400(GICV2)"
default y
config BSP_USING_GICV3
bool "Enable GIC500(GICV3)"
default n
endif
config BSP_USING_PIN
bool "Using PIN"
select RT_USING_PIN
default y
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_CORETIMER
bool "Using core timer"
select RT_USING_CORETIMER
@ -59,10 +92,6 @@ menu "Hardware Drivers Config"
default n
endif
config BSP_USING_ETH
bool "Enable ETH"
default n
config BSP_USING_WDT
bool "Enable WDT"
select RT_USING_WDT
@ -103,5 +132,9 @@ menu "Hardware Drivers Config"
bool "HDMI DISPLAY"
default n
endif
menuconfig BSP_USING_TOUCH
bool "Enable Touch"
default n
endmenu
endmenu

View File

@ -0,0 +1,19 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*.S')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('driver', src, depend = [''], CPPPATH = CPPPATH)
# build for sub-directory
list = os.listdir(cwd)
objs = []
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'))
group = group + objs
Return('group')

View File

@ -0,0 +1,245 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2021-12-28 GuEe-GUI add smp support
* 2023-03-28 WangXiaoyao sync works & memory layout fixups
* code formats
*/
#include <rthw.h>
#include <rtthread.h>
#include <mm_aspace.h>
#include "board.h"
#include "drv_uart.h"
#include "cp15.h"
#include "mmu.h"
#include "mbox.h"
#include <mm_page.h>
#ifdef RT_USING_SMART
#include <lwp_arch.h>
#endif
extern size_t MMUTable[];
size_t gpio_base_addr = GPIO_BASE_ADDR;
size_t uart_base_addr = UART_BASE;
size_t gic_base_addr = GIC_V2_BASE;
size_t arm_timer_base = ARM_TIMER_BASE;
size_t pactl_cs_base = PACTL_CS_ADDR;
size_t stimer_base_addr = STIMER_BASE;
size_t mmc2_base_addr = MMC2_BASE_ADDR;
size_t videocore_mbox = VIDEOCORE_MBOX;
size_t mbox_addr = MBOX_ADDR;
size_t wdt_base_addr = WDT_BASE;
uint8_t *mac_reg_base_addr = (uint8_t *)MAC_REG;
uint8_t *eth_send_no_cache = (uint8_t *)SEND_DATA_NO_CACHE;
uint8_t *eth_recv_no_cache = (uint8_t *)RECV_DATA_NO_CACHE;
#ifdef RT_USING_SMART
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x0fffffff, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM}
};
#else
struct mem_desc platform_mem_desc[] = {
{0x00200000, (128ul << 20) - 1, 0x00200000, NORMAL_MEM},
{0xFC000000, 0x000100000000 - 1, 0xFC000000, DEVICE_MEM},
};
#endif
const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc)/sizeof(platform_mem_desc[0]);
void idle_wfi(void)
{
asm volatile ("wfi");
}
/**
* This function will initialize board
*/
extern size_t MMUTable[];
int rt_hw_gtimer_init(void);
rt_region_t init_page_region = {
PAGE_START,
PAGE_END,
};
/**
* Initialize the Hardware related stuffs. Called from rtthread_startup()
* after interrupt disabled.
*/
void rt_hw_board_init(void)
{
extern void (*system_off)(void);
extern void reboot(void);
system_off = reboot;
/* io device remap */
#ifdef RT_USING_SMART
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xfffffffff0000000, 0x10000000, MMUTable, PV_OFFSET);
#else
rt_hw_mmu_map_init(&rt_kernel_space, (void*)0x000400000000, 0x10000000, MMUTable, 0);
#endif
rt_page_init(init_page_region);
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size);
/* map peripheral address to virtual address */
#ifdef RT_USING_HEAP
/* initialize system heap */
rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
#endif
/* initialize hardware interrupt */
rt_hw_interrupt_init();
//gpio
gpio_base_addr = (size_t)rt_ioremap((void*)GPIO_BASE_ADDR, 0x1000);
//pactl
pactl_cs_base = (size_t)rt_ioremap((void*)PACTL_CS_ADDR, 0x1000);
//stimer
stimer_base_addr = (size_t)rt_ioremap((void*)STIMER_BASE, 0x1000);
//mmc2_base_addr
mmc2_base_addr = (size_t)rt_ioremap((void*)MMC2_BASE_ADDR, 0x1000);
//mbox
videocore_mbox = (size_t)rt_ioremap((void*)VIDEOCORE_MBOX, 0x1000);
// mbox msg
mbox = (volatile unsigned int *)rt_pages_alloc(0);
//wdt
wdt_base_addr = (size_t)rt_ioremap((void*)WDT_BASE, 0x1000);
//mac
mac_reg_base_addr = (void *)rt_ioremap((void*)MAC_REG, 0x80000);
// eth data
eth_send_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
eth_recv_no_cache = (void *)rt_pages_alloc(rt_page_bits(0x200000));
/* initialize uart */
rt_hw_uart_init();
/* initialize timer for os tick */
rt_hw_gtimer_init();
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
rt_kprintf("heap: 0x%08x - 0x%08x\n", HEAP_BEGIN, HEAP_END);
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
rt_thread_idle_sethook(idle_wfi);
}
#ifdef RT_USING_SMP
#include <gic.h>
void rt_hw_mmu_ktbl_set(unsigned long tbl);
void _secondary_cpu_entry(void);
static unsigned long cpu_release_paddr[] =
{
[0] = 0xd8,
[1] = 0xe0,
[2] = 0xe8,
[3] = 0xf0,
[4] = 0x00
};
#ifndef RT_USING_SMART
static void *_remap(void *paddr, size_t size)
{
int ret;
static void *va = 0;
size_t low_off = (size_t)paddr & ARCH_PAGE_MASK;
if (va)
return va + low_off;
va = rt_kernel_space.start;
while (1)
{
int rt_kmem_map_phy(void *va, void *pa, rt_size_t length, rt_size_t attr);
ret = rt_kmem_map_phy(va, 0x0, ARCH_PAGE_SIZE, MMU_MAP_K_DEVICE);
if (ret == RT_EOK)
{
break;
}
else
{
va += ARCH_PAGE_SIZE;
}
}
return va + low_off;
}
#endif /* RT_USING_SMART */
void rt_hw_secondary_cpu_up(void)
{
int i;
void *release_addr;
for (i = 1; i < RT_CPUS_NR && cpu_release_paddr[i]; ++i)
{
#ifdef RT_USING_SMART
release_addr = rt_ioremap((void *)cpu_release_paddr[i], sizeof(cpu_release_paddr[0]));
#else
release_addr = _remap((void *)cpu_release_paddr[i], sizeof(cpu_release_paddr[0]));
#endif
__asm__ volatile ("str %0, [%1]"::"rZ"((unsigned long)_secondary_cpu_entry + PV_OFFSET), "r"(release_addr));
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, release_addr, sizeof(release_addr));
asm volatile ("dsb sy");
asm volatile ("sev");
}
}
void rt_hw_secondary_cpu_bsp_start(void)
{
rt_hw_spin_lock(&_cpus_lock);
rt_hw_mmu_ktbl_set((unsigned long)MMUTable);
rt_hw_vector_init();
arm_gic_cpu_init(0, 0);
rt_hw_gtimer_init();
rt_kprintf("\rcpu %d boot success\n", rt_hw_cpu_id());
rt_system_scheduler_start();
}
void rt_hw_secondary_cpu_idle_exec(void)
{
asm volatile ("wfe":::"memory", "cc");
}
#endif

View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
*/
#ifndef BOARD_H__
#define BOARD_H__
#include <stdint.h>
#include "raspi4.h"
#include "mmu.h"
#include "ioremap.h"
extern int __bss_end;
#define HEAP_BEGIN ((void*)&__bss_end)
#ifdef RT_USING_SMART
#define HEAP_END ((size_t)KERNEL_VADDR_START + 32 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)KERNEL_VADDR_START + 128 * 1024 * 1024)
#else
#define KERNEL_VADDR_START 0x0
#define HEAP_END (KERNEL_VADDR_START + 64 * 1024 * 1024)
#define PAGE_START HEAP_END
#define PAGE_END ((size_t)PAGE_START + 64 * 1024 * 1024)
#endif
void rt_hw_board_init(void);
#endif

View File

@ -0,0 +1,243 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-11-26 bigmagic first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/touch.h>
#include <ioremap.h>
#include <mmu.h>
#ifdef RT_USING_SMART
#include <lwp.h>
#include <lwp_user_mm.h>
#endif
#include <hypercall.h>
#ifdef BSP_USING_TOUCH
#include "mbox.h"
#include "drv_dsi_touch.h"
#define DBG_TAG "dsi_touch"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
static rt_touch_t touch_device = RT_NULL;
static struct rt_semaphore dsi_touch_ack;
static rt_uint32_t touch_x;
static rt_uint32_t touch_y;
static rt_uint32_t touch_state = 0;
static rt_thread_t dsi_touch_tid = RT_NULL;
#define DSI_TOUCH_THREAD_STACK_SIZE (4096)
#define DSI_TOUCH_THREAD_PRIORITY (25)
#define DSI_TOUCH_THREAD_TIMESLICE (10)
#define MAXIMUM_SUPPORTED_POINTS (10)
struct touch_regs
{
uint8_t device_mode;
uint8_t gesture_id;
uint8_t num_points;
struct touch
{
uint8_t xh;
uint8_t xl;
uint8_t yh;
uint8_t yl;
uint8_t res1;
uint8_t res2;
} point[MAXIMUM_SUPPORTED_POINTS];
};
struct drv_mouse_device
{
struct rt_device parent;
struct rt_touch_data touchdata;
int channel;
};
struct drv_mouse_device _mouse;
static void post_event(rt_uint16_t x, rt_uint16_t y, rt_uint8_t event)
{
struct rt_touch_data *minfo = &_mouse.touchdata;
struct rt_channel_msg ch_msg;
LOG_D("event:%d, x:%d, y:%d\n", event, x, y);
minfo->x_coordinate = x;
minfo->y_coordinate = y;
minfo->event = event;
ch_msg.type = RT_CHANNEL_RAW;
ch_msg.u.d = (void *)(size_t)event;
rt_channel_send(_mouse.channel, &ch_msg);
}
static void dsi_touch_thread_entry(void *param)
{
static volatile unsigned long touchbuf;
touchbuf = bcm271x_mbox_get_touch();
if (touchbuf == RT_NULL)
{
rt_kprintf("init dsi touch err!\n");
return;
}
#ifdef BSP_USING_VM_MODE
if (rt_hv_stage2_map((unsigned long)touchbuf, 0x1000))
{
rt_kprintf("alloc mmio from hyper fail!\n");
return;
}
#endif
touchbuf = (unsigned long)rt_ioremap((void *)touchbuf, 0x1000);
while (1)
{
struct touch_regs *regs = (struct touch_regs *)touchbuf;
if ((regs->num_points > 0) && (regs->num_points < MAXIMUM_SUPPORTED_POINTS))
{
/* only one touch point */
touch_x = (((int)regs->point[0].xh & 0xf) << 8) + regs->point[0].xl;
touch_y = (((int)regs->point[0].yh & 0xf) << 8) + regs->point[0].yl;
if (!touch_state)
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_DOWN);
}
else
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_MOVE);
}
touch_state = 1;
}
else
{
if (touch_state)
{
post_event(touch_x, touch_y, RT_TOUCH_EVENT_UP);
}
touch_state = 0;
}
rt_thread_mdelay(1);
}
}
static rt_size_t dsi_read_point(struct rt_touch_device *touch, void *buf, rt_size_t read_num)
{
rt_uint16_t* touchxy = (rt_uint16_t *)buf;
if ((read_num != 0) && (touch_state == 1))
{
touchxy[0] = touch_x;
touchxy[1] = touch_y;
touch_state = 0;
return read_num;
}
else
{
return 0;
}
}
static rt_err_t dsi_control(struct rt_touch_device *device, int cmd, void *data)
{
return RT_EOK;
}
static struct rt_touch_ops dsi_touch_ops =
{
.touch_readpoint = dsi_read_point,
.touch_control = dsi_control,
};
static rt_err_t drv_mouse_init(struct rt_device *device)
{
struct drv_mouse_device *mouse = (struct drv_mouse_device*)device;
return RT_EOK;
}
static rt_err_t drv_mouse_control(struct rt_device *device, int cmd, void *args)
{
switch (cmd)
{
#define CMD_MOUSE_SET_NOTIFY 0 /* arg is shmid, in the shm, a sem point is given */
case CMD_MOUSE_SET_NOTIFY:
*(unsigned long *)args = (rt_uint32_t)(unsigned long)lwp_map_user_phy(lwp_self(), RT_NULL, (uint32_t*)((size_t)&_mouse.touchdata + PV_OFFSET), sizeof(struct rt_touch_data), 1);
break;
default:
break;
}
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops _mouse_ops =
{
drv_mouse_init,
RT_NULL,
RT_NULL,
RT_NULL,
RT_NULL,
drv_mouse_control
};
#endif
static int hw_dsi_touch_init(void)
{
struct rt_device *device = &_mouse.parent;
#ifdef RT_USING_DEVICE_OPS
device->ops = &_mouse_ops;
#else
device->init = drv_mouse_init;
device->open = RT_NULL;
device->close = RT_NULL;
device->read = RT_NULL;
device->write = RT_NULL;
device->control = drv_mouse_control;
#endif
rt_device_register(device, "mouse", RT_DEVICE_FLAG_RDWR);
_mouse.channel = rt_channel_open("mouse", O_CREAT);
/* touch sem */
rt_sem_init(&dsi_touch_ack, "dsi_touch_ack", 0, RT_IPC_FLAG_FIFO);
dsi_touch_tid = rt_thread_create("dsi_touch",
dsi_touch_thread_entry, RT_NULL,
DSI_TOUCH_THREAD_STACK_SIZE,
DSI_TOUCH_THREAD_PRIORITY, DSI_TOUCH_THREAD_TIMESLICE);
if (dsi_touch_tid != RT_NULL)
{
rt_thread_startup(dsi_touch_tid);
}
touch_device = (rt_touch_t)rt_malloc(sizeof(struct rt_touch_device));
if (touch_device == RT_NULL)
{
return -RT_ERROR;
}
/* register touch device */
touch_device->info.type = RT_TOUCH_TYPE_RESISTANCE;
touch_device->info.vendor = RT_TOUCH_VENDOR_UNKNOWN;
touch_device->ops = &dsi_touch_ops;
rt_hw_touch_register(touch_device, "dsi_touch", RT_DEVICE_FLAG_INT_RX, RT_NULL);
return 0;
}
INIT_APP_EXPORT(hw_dsi_touch_init);
#endif /* BSP_USING_TOUCH */

View File

@ -7,18 +7,14 @@
* Change Logs:
* Date Author Notes
* 2020-10-30 bigmagic first version
* 2023-03-28 WangXiaoyao Modify pbuf_alloc
*/
#include <rtdef.h>
#include <rthw.h>
#include <stdint.h>
#include <rtthread.h>
#ifdef BSP_USING_ETH
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#include <mmu.h>
#include "mbox.h"
#include "raspi4.h"
@ -28,12 +24,13 @@
#include <rtdbg.h>
#define LOG_TAG "drv.eth"
#define RECV_CACHE_BUF (2048)
#define SEND_CACHE_BUF (2048)
#define DMA_DISC_ADDR_SIZE (2 * 1024 *1024)
static int link_speed = 0;
static int link_flag = 0;
#define RX_DESC_BASE (MAC_REG_BASE_ADDR + GENET_RX_OFF)
#define TX_DESC_BASE (MAC_REG_BASE_ADDR + GENET_TX_OFF)
#define DMA_DISC_ADDR_SIZE (4 * 1024 *1024)
#define RX_DESC_BASE (mac_reg_base_addr + GENET_RX_OFF)
#define TX_DESC_BASE (mac_reg_base_addr + GENET_TX_OFF)
#define MAX_ADDR_LEN (6)
@ -42,20 +39,15 @@
#define BIT(nr) (1UL << (nr))
#define LINK_THREAD_STACK_SIZE (2048)
static rt_thread_t link_thread_tid = RT_NULL;
#define LINK_THREAD_STACK_SIZE (8192)
#define LINK_THREAD_PRIORITY (20)
#define LINK_THREAD_TIMESLICE (10)
static int link_speed = 0;
static int link_flag = 0;
static rt_thread_t link_thread_tid = RT_NULL;
static rt_uint32_t tx_index = 0;
static rt_uint32_t rx_index = 0;
static rt_uint32_t index_flag = 0;
struct rt_eth_dev
{
struct eth_device parent;
@ -68,29 +60,25 @@ struct rt_eth_dev
void *priv;
};
static struct rt_eth_dev eth_dev;
static struct rt_semaphore send_finsh_sem_lock;
static struct rt_semaphore link_ack;
rt_inline rt_uint32_t read32(void *addr)
static inline rt_uint32_t read32(void *addr)
{
return (*((volatile unsigned int *)(addr)));
return (*((volatile unsigned int*)(addr)));
}
rt_inline void write32(void *addr, rt_uint32_t value)
static inline void write32(void *addr, rt_uint32_t value)
{
(*((volatile unsigned int *)(addr))) = value;
(*((volatile unsigned int*)(addr))) = value;
}
static void eth_rx_irq(int irq, void *param)
{
rt_uint32_t val = 0;
val = read32(mac_reg_base_addr + GENET_INTRL2_CPU_STAT);
val &= ~read32(mac_reg_base_addr + GENET_INTRL2_CPU_STAT_MASK);
val = read32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_STAT);
val &= ~read32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_STAT_MASK);
write32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_CLEAR, val);
write32(mac_reg_base_addr + GENET_INTRL2_CPU_CLEAR, val);
if (val & GENET_IRQ_RXDMA_DONE)
{
@ -99,75 +87,73 @@ static void eth_rx_irq(int irq, void *param)
if (val & GENET_IRQ_TXDMA_DONE)
{
rt_sem_release(&send_finsh_sem_lock);
//todo
}
}
/* we only support RGMII (as used on the RPi4) */
/* We only support RGMII (as used on the RPi4). */
static int bcmgenet_interface_set(void)
{
int phy_mode = PHY_INTERFACE_MODE_RGMII;
switch (phy_mode)
{
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_RXID:
write32(MAC_REG_BASE_ADDR + SYS_PORT_CTRL, PORT_MODE_EXT_GPHY);
write32(mac_reg_base_addr + SYS_PORT_CTRL, PORT_MODE_EXT_GPHY);
break;
default:
rt_kprintf("unknown phy mode: %d\n", MAC_REG_BASE_ADDR);
rt_kprintf("unknown phy mode: %d\n", mac_reg_base_addr);
return -1;
}
return 0;
}
static void bcmgenet_umac_reset(void)
{
rt_uint32_t reg;
reg = read32(MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL);
reg = read32(mac_reg_base_addr + SYS_RBUF_FLUSH_CTRL);
reg |= BIT(1);
write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), reg);
write32((mac_reg_base_addr + SYS_RBUF_FLUSH_CTRL), reg);
reg &= ~BIT(1);
write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), reg);
write32((mac_reg_base_addr + SYS_RBUF_FLUSH_CTRL), reg);
DELAY_MICROS(10);
write32((MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL), 0);
write32((mac_reg_base_addr + SYS_RBUF_FLUSH_CTRL), 0);
DELAY_MICROS(10);
write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
write32(MAC_REG_BASE_ADDR + UMAC_CMD, (CMD_SW_RESET | CMD_LCL_LOOP_EN));
write32(mac_reg_base_addr + UMAC_CMD, 0);
write32(mac_reg_base_addr + UMAC_CMD, (CMD_SW_RESET | CMD_LCL_LOOP_EN));
DELAY_MICROS(2);
write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
write32(mac_reg_base_addr + UMAC_CMD, 0);
/* clear tx/rx counter */
write32(MAC_REG_BASE_ADDR + UMAC_MIB_CTRL, MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT);
write32(MAC_REG_BASE_ADDR + UMAC_MIB_CTRL, 0);
write32(MAC_REG_BASE_ADDR + UMAC_MAX_FRAME_LEN, ENET_MAX_MTU_SIZE);
write32(mac_reg_base_addr + UMAC_MIB_CTRL, MIB_RESET_RX | MIB_RESET_TX | MIB_RESET_RUNT);
write32(mac_reg_base_addr + UMAC_MIB_CTRL, 0);
write32(mac_reg_base_addr + UMAC_MAX_FRAME_LEN, ENET_MAX_MTU_SIZE);
/* init rx registers, enable ip header optimization */
reg = read32(MAC_REG_BASE_ADDR + RBUF_CTRL);
reg = read32(mac_reg_base_addr + RBUF_CTRL);
reg |= RBUF_ALIGN_2B;
write32(MAC_REG_BASE_ADDR + RBUF_CTRL, reg);
write32(MAC_REG_BASE_ADDR + RBUF_TBUF_SIZE_CTRL, 1);
write32(mac_reg_base_addr + RBUF_CTRL, reg);
write32(mac_reg_base_addr + RBUF_TBUF_SIZE_CTRL, 1);
}
static void bcmgenet_disable_dma(void)
{
rt_uint32_t tdma_reg = 0, rdma_reg = 0;
tdma_reg = read32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL);
tdma_reg = read32(mac_reg_base_addr + TDMA_REG_BASE + DMA_CTRL);
tdma_reg &= ~(1UL << DMA_EN);
write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL, tdma_reg);
rdma_reg = read32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL);
write32(mac_reg_base_addr + TDMA_REG_BASE + DMA_CTRL, tdma_reg);
rdma_reg = read32(mac_reg_base_addr + RDMA_REG_BASE + DMA_CTRL);
rdma_reg &= ~(1UL << DMA_EN);
write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL, rdma_reg);
write32(MAC_REG_BASE_ADDR + UMAC_TX_FLUSH, 1);
write32(mac_reg_base_addr + RDMA_REG_BASE + DMA_CTRL, rdma_reg);
write32(mac_reg_base_addr + UMAC_TX_FLUSH, 1);
DELAY_MICROS(100);
write32(MAC_REG_BASE_ADDR + UMAC_TX_FLUSH, 0);
write32(mac_reg_base_addr + UMAC_TX_FLUSH, 0);
}
static void bcmgenet_enable_dma(void)
@ -176,31 +162,27 @@ static void bcmgenet_enable_dma(void)
rt_uint32_t dma_ctrl = 0;
dma_ctrl = (1 << (DEFAULT_Q + DMA_RING_BUF_EN_SHIFT)) | DMA_EN;
write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_CTRL, dma_ctrl);
write32(mac_reg_base_addr + TDMA_REG_BASE + DMA_CTRL, dma_ctrl);
reg = read32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL);
write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_CTRL, dma_ctrl | reg);
reg = read32(mac_reg_base_addr + RDMA_REG_BASE + DMA_CTRL);
write32(mac_reg_base_addr + RDMA_REG_BASE + DMA_CTRL, dma_ctrl | reg);
}
static int bcmgenet_mdio_write(rt_uint32_t addr, rt_uint32_t reg, rt_uint32_t value)
{
int count = 10000;
rt_uint32_t val;
rt_uint32_t reg_val;
val = MDIO_WR | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT) | (0xffff & value);
write32(MAC_REG_BASE_ADDR + MDIO_CMD, val);
write32(mac_reg_base_addr + MDIO_CMD, val);
reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
rt_uint32_t reg_val = read32(mac_reg_base_addr + MDIO_CMD);
reg_val = reg_val | MDIO_START_BUSY;
write32(MAC_REG_BASE_ADDR + MDIO_CMD, reg_val);
write32(mac_reg_base_addr + MDIO_CMD, reg_val);
while ((read32(MAC_REG_BASE_ADDR + MDIO_CMD) & MDIO_START_BUSY) && (--count))
{
while ((read32(mac_reg_base_addr + MDIO_CMD) & MDIO_START_BUSY) && (--count))
DELAY_MICROS(1);
}
reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
reg_val = read32(mac_reg_base_addr + MDIO_CMD);
return reg_val & 0xffff;
}
@ -212,18 +194,16 @@ static int bcmgenet_mdio_read(rt_uint32_t addr, rt_uint32_t reg)
rt_uint32_t reg_val = 0;
val = MDIO_RD | (addr << MDIO_PMD_SHIFT) | (reg << MDIO_REG_SHIFT);
write32(MAC_REG_BASE_ADDR + MDIO_CMD, val);
write32(mac_reg_base_addr + MDIO_CMD, val);
reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
reg_val = read32(mac_reg_base_addr + MDIO_CMD);
reg_val = reg_val | MDIO_START_BUSY;
write32(MAC_REG_BASE_ADDR + MDIO_CMD, reg_val);
write32(mac_reg_base_addr + MDIO_CMD, reg_val);
while ((read32(MAC_REG_BASE_ADDR + MDIO_CMD) & MDIO_START_BUSY) && (--count))
{
while ((read32(mac_reg_base_addr + MDIO_CMD) & MDIO_START_BUSY) && (--count))
DELAY_MICROS(1);
}
reg_val = read32(MAC_REG_BASE_ADDR + MDIO_CMD);
reg_val = read32(mac_reg_base_addr + MDIO_CMD);
return reg_val & 0xffff;
}
@ -232,15 +212,13 @@ static int bcmgenet_gmac_write_hwaddr(void)
{
rt_uint8_t addr[6];
rt_uint32_t reg;
bcm271x_mbox_hardware_get_mac_address(&addr[0]);
reg = addr[0] << 24 | addr[1] << 16 | addr[2] << 8 | addr[3];
write32(MAC_REG_BASE_ADDR + UMAC_MAC0, reg);
write32(mac_reg_base_addr + UMAC_MAC0, reg);
reg = addr[4] << 8 | addr[5];
write32(MAC_REG_BASE_ADDR + UMAC_MAC1, reg);
write32(mac_reg_base_addr + UMAC_MAC1, reg);
return 0;
}
@ -258,17 +236,15 @@ static int get_ethernet_uid(void)
{
LOG_I("version is B1\n");
}
return uid;
}
static void bcmgenet_mdio_init(void)
{
/* get ethernet uid */
if (get_ethernet_uid() == 0)
{
return;
}
rt_uint32_t ret = 0;
/*get ethernet uid*/
ret = get_ethernet_uid();
if (ret == 0) return;
/* reset phy */
bcmgenet_mdio_write(1, BCM54213PE_MII_CONTROL, MII_CONTROL_PHY_RESET);
@ -296,34 +272,34 @@ static void bcmgenet_mdio_init(void)
static void rx_ring_init(void)
{
write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
write32(MAC_REG_BASE_ADDR + RDMA_READ_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + RDMA_WRITE_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_END_ADDR, RX_DESCS * DMA_DESC_SIZE / 4 - 1);
write32(mac_reg_base_addr + RDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
write32(mac_reg_base_addr + RDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
write32(mac_reg_base_addr + RDMA_READ_PTR, 0x0);
write32(mac_reg_base_addr + RDMA_WRITE_PTR, 0x0);
write32(mac_reg_base_addr + RDMA_RING_REG_BASE + DMA_END_ADDR, RX_DESCS * DMA_DESC_SIZE / 4 - 1);
write32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX, 0x0);
write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, 0x0);
write32(MAC_REG_BASE_ADDR + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
write32(MAC_REG_BASE_ADDR + RDMA_XON_XOFF_THRESH, DMA_FC_THRESH_VALUE);
write32(MAC_REG_BASE_ADDR + RDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
write32(mac_reg_base_addr + RDMA_PROD_INDEX, 0x0);
write32(mac_reg_base_addr + RDMA_CONS_INDEX, 0x0);
write32(mac_reg_base_addr + RDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (RX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
write32(mac_reg_base_addr + RDMA_XON_XOFF_THRESH, DMA_FC_THRESH_VALUE);
write32(mac_reg_base_addr + RDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
}
static void tx_ring_init(void)
{
write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_READ_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_WRITE_PTR, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_END_ADDR, TX_DESCS * DMA_DESC_SIZE / 4 - 1);
write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH, 0x1);
write32(MAC_REG_BASE_ADDR + TDMA_FLOW_PERIOD, 0x0);
write32(MAC_REG_BASE_ADDR + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
write32(MAC_REG_BASE_ADDR + TDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
write32(mac_reg_base_addr + TDMA_REG_BASE + DMA_SCB_BURST_SIZE, DMA_MAX_BURST_LENGTH);
write32(mac_reg_base_addr + TDMA_RING_REG_BASE + DMA_START_ADDR, 0x0);
write32(mac_reg_base_addr + TDMA_READ_PTR, 0x0);
write32(mac_reg_base_addr + TDMA_READ_PTR, 0x0);
write32(mac_reg_base_addr + TDMA_READ_PTR, 0x0);
write32(mac_reg_base_addr + TDMA_WRITE_PTR, 0x0);
write32(mac_reg_base_addr + TDMA_RING_REG_BASE + DMA_END_ADDR, TX_DESCS * DMA_DESC_SIZE / 4 - 1);
write32(mac_reg_base_addr + TDMA_PROD_INDEX, 0x0);
write32(mac_reg_base_addr + TDMA_CONS_INDEX, 0x0);
write32(mac_reg_base_addr + TDMA_RING_REG_BASE + DMA_MBUF_DONE_THRESH, 0x1);
write32(mac_reg_base_addr + TDMA_FLOW_PERIOD, 0x0);
write32(mac_reg_base_addr + TDMA_RING_REG_BASE + DMA_RING_BUF_SIZE, (TX_DESCS << DMA_RING_SIZE_SHIFT) | RX_BUF_LENGTH);
write32(mac_reg_base_addr + TDMA_REG_BASE + DMA_RING_CFG, 1 << DEFAULT_Q);
}
static void rx_descs_init(void)
@ -345,7 +321,6 @@ static int bcmgenet_adjust_link(void)
{
rt_uint32_t speed;
rt_uint32_t phy_dev_speed = link_speed;
rt_uint32_t reg1;
switch (phy_dev_speed)
{
@ -363,12 +338,14 @@ static int bcmgenet_adjust_link(void)
return -1;
}
reg1 = read32(MAC_REG_BASE_ADDR + EXT_RGMII_OOB_CTRL);
reg1 |= (RGMII_LINK | RGMII_MODE_EN | ID_MODE_DIS);
write32(MAC_REG_BASE_ADDR + EXT_RGMII_OOB_CTRL, reg1);
DELAY_MICROS(1000);
write32(MAC_REG_BASE_ADDR + UMAC_CMD, speed << CMD_SPEED_SHIFT);
rt_uint32_t reg1 = read32(mac_reg_base_addr + EXT_RGMII_OOB_CTRL);
//reg1 &= ~(1UL << OOB_DISABLE);
//rt_kprintf("OOB_DISABLE is %d\n", OOB_DISABLE);
reg1 |= (RGMII_LINK | RGMII_MODE_EN | ID_MODE_DIS);
write32(mac_reg_base_addr + EXT_RGMII_OOB_CTRL, reg1);
DELAY_MICROS(1000);
write32(mac_reg_base_addr + UMAC_CMD, speed << CMD_SPEED_SHIFT);
return 0;
}
@ -388,49 +365,46 @@ static int bcmgenet_gmac_eth_start(void)
bcmgenet_umac_reset();
bcmgenet_gmac_write_hwaddr();
/* disable RX/TX DMA and flush TX queues */
/* Disable RX/TX DMA and flush TX queues */
bcmgenet_disable_dma();
rx_ring_init();
rx_descs_init();
tx_ring_init();
/* enable RX/TX DMA */
/* Enable RX/TX DMA */
bcmgenet_enable_dma();
/* ppdate MAC registers based on PHY property */
/* Update MAC registers based on PHY property */
ret = bcmgenet_adjust_link();
if (ret)
if(ret)
{
rt_kprintf("bcmgenet: adjust PHY link failed: %d\n", ret);
return ret;
}
/* wait tx index clear */
while ((read32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX) != 0) && (--count))
{
while ((read32(mac_reg_base_addr + TDMA_CONS_INDEX) != 0) && (--count))
DELAY_MICROS(1);
}
tx_index = read32(MAC_REG_BASE_ADDR + TDMA_CONS_INDEX);
write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, tx_index);
tx_index = read32(mac_reg_base_addr + TDMA_CONS_INDEX);
write32(mac_reg_base_addr + TDMA_PROD_INDEX, tx_index);
index_flag = read32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX);
index_flag = read32(mac_reg_base_addr + RDMA_PROD_INDEX);
rx_index = index_flag % RX_DESCS;
rx_index = index_flag % 256;
write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, index_flag);
write32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX, index_flag);
write32(mac_reg_base_addr + RDMA_CONS_INDEX, index_flag);
write32(mac_reg_base_addr + RDMA_PROD_INDEX, index_flag);
/* enable Rx/Tx */
/* Enable Rx/Tx */
rt_uint32_t rx_tx_en;
rx_tx_en = read32(MAC_REG_BASE_ADDR + UMAC_CMD);
rx_tx_en = read32(mac_reg_base_addr + UMAC_CMD);
rx_tx_en |= (CMD_TX_EN | CMD_RX_EN);
write32(MAC_REG_BASE_ADDR + UMAC_CMD, rx_tx_en);
/* eanble IRQ for TxDMA done and RxDMA done */
write32(MAC_REG_BASE_ADDR + GENET_INTRL2_CPU_CLEAR_MASK, GENET_IRQ_TXDMA_DONE | GENET_IRQ_RXDMA_DONE);
write32(mac_reg_base_addr + UMAC_CMD, rx_tx_en);
// eanble IRQ for TxDMA done and RxDMA done
write32(mac_reg_base_addr + GENET_INTRL2_CPU_CLEAR_MASK, GENET_IRQ_TXDMA_DONE | GENET_IRQ_RXDMA_DONE);
return 0;
}
@ -438,22 +412,21 @@ static rt_uint32_t prev_recv_cnt = 0;
static rt_uint32_t cur_recv_cnt = 0;
static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
{
void *desc_base;
rt_uint32_t length = 0, addr = 0;
rt_uint32_t prod_index = read32(MAC_REG_BASE_ADDR + RDMA_PROD_INDEX);
/* no buff */
if (prod_index == index_flag)
void* desc_base;
rt_uint32_t length = 0;
size_t addr = 0;
rt_uint32_t prod_index = read32(mac_reg_base_addr + RDMA_PROD_INDEX);
//get next
if(prod_index == index_flag)
{
cur_recv_cnt = index_flag;
index_flag = 0x7fffffff;
//no buff
return 0;
}
else
{
/* no new buff */
if (prev_recv_cnt == (prod_index & 0xffff))
if(prev_recv_cnt == (prod_index & 0xffffUL))
{
return 0;
}
@ -462,70 +435,74 @@ static rt_uint32_t bcmgenet_gmac_eth_recv(rt_uint8_t **packetp)
length = read32(desc_base + DMA_DESC_LENGTH_STATUS);
length = (length >> DMA_BUFLENGTH_SHIFT) & DMA_BUFLENGTH_MASK;
addr = read32(desc_base + DMA_DESC_ADDRESS_LO);
/*
* to cater for the IP headepr alignment the hardware does.
/* To cater for the IP headepr alignment the hardware does.
* This would actually not be needed if we don't program
* RBUF_ALIGN_2B
*/
/* convert to memory address */
addr = addr + RECV_DATA_NO_CACHE - RECV_DATA_NO_CACHE;
rt_hw_dcache_invalidate_range(addr, length);
*packetp = (rt_uint8_t *)(unsigned long)(addr + RX_BUF_OFFSET);
*packetp = (rt_uint8_t *)(addr + RX_BUF_OFFSET);
rx_index = rx_index + 1;
if (rx_index >= RX_DESCS)
if(rx_index >= 256)
{
rx_index = 0;
}
write32(MAC_REG_BASE_ADDR + RDMA_CONS_INDEX, cur_recv_cnt);
write32(mac_reg_base_addr + RDMA_CONS_INDEX, cur_recv_cnt);
cur_recv_cnt = cur_recv_cnt + 1;
if (cur_recv_cnt > 0xffff)
if(cur_recv_cnt > 0xffff)
{
cur_recv_cnt = 0;
}
prev_recv_cnt = cur_recv_cnt;
return length - RX_BUF_OFFSET;
return length;
}
}
static int bcmgenet_gmac_eth_send(rt_uint32_t packet, int length, struct pbuf *p)
static int bcmgenet_gmac_eth_send(void *packet, int length)
{
rt_ubase_t level;
void *desc_base = (TX_DESC_BASE + tx_index * DMA_DESC_SIZE);
pbuf_copy_partial(p, (void *)(unsigned long)(packet + tx_index * SEND_CACHE_BUF), p->tot_len, 0);
rt_uint32_t len_stat = length << DMA_BUFLENGTH_SHIFT;
rt_uint32_t prod_index, cons;
rt_uint32_t tries = 100;
prod_index = read32(mac_reg_base_addr + TDMA_PROD_INDEX);
len_stat |= 0x3F << DMA_TX_QTAG_SHIFT;
len_stat |= DMA_TX_APPEND_CRC | DMA_SOP | DMA_EOP;
rt_hw_dcache_flush_range(packet + tx_index * SEND_CACHE_BUF, length);
rt_uint32_t prod_index;
prod_index = read32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX);
write32((desc_base + DMA_DESC_ADDRESS_LO), SEND_DATA_NO_CACHE + tx_index * SEND_CACHE_BUF);
write32((desc_base + DMA_DESC_ADDRESS_LO), SEND_DATA_NO_CACHE);
write32((desc_base + DMA_DESC_ADDRESS_HI), 0);
write32((desc_base + DMA_DESC_LENGTH_STATUS), len_stat);
tx_index++;
if (tx_index >= TX_DESCS)
{
tx_index = 0;
}
tx_index = tx_index == 255? 0 : tx_index + 1;
prod_index = prod_index + 1;
if (prod_index > 0xffff)
if (prod_index == 0xe000)
{
write32(mac_reg_base_addr + TDMA_PROD_INDEX, 0);
prod_index = 0;
}
/* start Transmisson */
write32(MAC_REG_BASE_ADDR + TDMA_PROD_INDEX, prod_index);
/* Start Transmisson */
write32(mac_reg_base_addr + TDMA_PROD_INDEX, prod_index);
level = rt_hw_interrupt_disable();
do
{
cons = read32(mac_reg_base_addr + TDMA_CONS_INDEX);
} while ((cons & 0xffff) < prod_index && --tries);
rt_hw_interrupt_enable(level);
if (!tries)
{
rt_kprintf("send err! tries is %d\n", tries);
return -1;
}
return 0;
}
@ -535,10 +512,10 @@ static void link_task_entry(void *param)
RT_ASSERT(eth_device != RT_NULL);
struct rt_eth_dev *dev = &eth_dev;
/* start mdio */
//start mdio
bcmgenet_mdio_init();
/* start timer link */
//start timer link
rt_timer_init(&dev->link_timer, "link_timer",
link_irq,
NULL,
@ -546,16 +523,16 @@ static void link_task_entry(void *param)
RT_TIMER_FLAG_PERIODIC);
rt_timer_start(&dev->link_timer);
/* link wait forever */
//link wait forever
rt_sem_take(&link_ack, RT_WAITING_FOREVER);
/* link up */
eth_device_linkchange(&eth_dev.parent, RT_TRUE);
eth_device_linkchange(&eth_dev.parent, RT_TRUE); //link up
rt_timer_stop(&dev->link_timer);
/* set mac */
//set mac
// bcmgenet_gmac_write_hwaddr();
bcmgenet_gmac_write_hwaddr();
/* check link speed */
//check link speed
if ((bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 10)) || (bcmgenet_mdio_read(1, BCM54213PE_STATUS) & (1 << 11)))
{
link_speed = 1000;
@ -572,7 +549,6 @@ static void link_task_entry(void *param)
rt_kprintf("Support link mode Speed 10M\n");
}
/* convert to memory address */
bcmgenet_gmac_eth_start();
rt_hw_interrupt_install(ETH_IRQ, eth_rx_irq, NULL, "eth_irq");
@ -586,27 +562,20 @@ static rt_err_t bcmgenet_eth_init(rt_device_t device)
rt_uint32_t ret = 0;
rt_uint32_t hw_reg = 0;
/* read GENET HW version */
/* Read GENET HW version */
rt_uint8_t major = 0;
hw_reg = read32(MAC_REG_BASE_ADDR + SYS_REV_CTRL);
hw_reg = read32(mac_reg_base_addr + SYS_REV_CTRL);
major = (hw_reg >> 24) & 0x0f;
if (major != 6)
{
if (major == 5)
{
major = 4;
}
else if (major == 0)
{
major = 1;
}
rt_kprintf("Uns upported GENETv%d.%d\n", major, (hw_reg >> 16) & 0x0f);
return -RT_ERROR;
return RT_ERROR;
}
/* set interface */
ret = bcmgenet_interface_set();
if (ret)
@ -615,20 +584,18 @@ static rt_err_t bcmgenet_eth_init(rt_device_t device)
}
/* rbuf clear */
write32(MAC_REG_BASE_ADDR + SYS_RBUF_FLUSH_CTRL, 0);
write32(mac_reg_base_addr + SYS_RBUF_FLUSH_CTRL, 0);
/* disable MAC while updating its registers */
write32(MAC_REG_BASE_ADDR + UMAC_CMD, 0);
write32(mac_reg_base_addr + UMAC_CMD, 0);
/* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
write32(MAC_REG_BASE_ADDR + UMAC_CMD, CMD_SW_RESET | CMD_LCL_LOOP_EN);
write32(mac_reg_base_addr + UMAC_CMD, CMD_SW_RESET | CMD_LCL_LOOP_EN);
link_thread_tid = rt_thread_create("link", link_task_entry, (void *)device,
LINK_THREAD_STACK_SIZE,
LINK_THREAD_PRIORITY, LINK_THREAD_TIMESLICE);
if (link_thread_tid != RT_NULL)
{
rt_thread_startup(link_thread_tid);
}
return RT_EOK;
}
@ -639,13 +606,9 @@ static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
{
case NIOCTL_GADDR:
if (args)
{
rt_memcpy(args, eth_dev.dev_addr, 6);
}
else
{
return -RT_ERROR;
}
break;
default:
break;
@ -655,31 +618,46 @@ static rt_err_t bcmgenet_eth_control(rt_device_t dev, int cmd, void *args)
rt_err_t rt_eth_tx(rt_device_t device, struct pbuf *p)
{
if (link_flag == 1)
int copy_len = 0;
/* lock eth device */
if (link_flag != 1)
{
bcmgenet_gmac_eth_send((rt_uint32_t)SEND_DATA_NO_CACHE, p->tot_len, p);
rt_sem_take(&send_finsh_sem_lock, RT_WAITING_FOREVER);
rt_kprintf("link disconnected\n");
return -RT_ERROR;
}
copy_len = pbuf_copy_partial(p, eth_send_no_cache, p->tot_len, 0);
if (copy_len == 0)
{
rt_kprintf("copy len is zero\n");
return -RT_ERROR;
}
bcmgenet_gmac_eth_send((void *)eth_send_no_cache, p->tot_len);
return RT_EOK;
}
struct pbuf *rt_eth_rx(rt_device_t device)
{
int recv_len = 0;
rt_uint8_t *addr_point = RT_NULL;
size_t addr_point;
struct pbuf *pbuf = RT_NULL;
if (link_flag == 1)
if (link_flag != 1)
{
recv_len = bcmgenet_gmac_eth_recv(&addr_point);
return RT_NULL;
}
recv_len = bcmgenet_gmac_eth_recv((rt_uint8_t **)&addr_point);
if (recv_len > 0)
{
pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
if (pbuf)
pbuf = pbuf_alloc(PBUF_LINK, ENET_FRAME_MAX_FRAMELEN, PBUF_POOL);
if (pbuf != RT_NULL)
{
rt_memcpy(pbuf->payload, addr_point, recv_len);
}
//calc offset
addr_point= (size_t)(addr_point+ (eth_recv_no_cache - RECV_DATA_NO_CACHE));
rt_memcpy(pbuf->payload, (char *)addr_point, recv_len);
}
}
@ -689,14 +667,15 @@ struct pbuf *rt_eth_rx(rt_device_t device)
int rt_hw_eth_init(void)
{
rt_uint8_t mac_addr[6];
rt_sem_init(&send_finsh_sem_lock, "send_finsh_sem_lock", TX_DESCS, RT_IPC_FLAG_FIFO);
rt_sem_init(&link_ack, "link_ack", 0, RT_IPC_FLAG_FIFO);
memset(&eth_dev, 0, sizeof(eth_dev));
memset((void *)SEND_DATA_NO_CACHE, 0, DMA_DISC_ADDR_SIZE);
memset((void *)RECV_DATA_NO_CACHE, 0, DMA_DISC_ADDR_SIZE);
memset((void *)eth_send_no_cache, 0, sizeof(DMA_DISC_ADDR_SIZE));
memset((void *)eth_recv_no_cache, 0, sizeof(DMA_DISC_ADDR_SIZE));
bcm271x_mbox_hardware_get_mac_address(&mac_addr[0]);
eth_dev.iobase = MAC_REG_BASE_ADDR;
eth_dev.iobase = mac_reg_base_addr;
eth_dev.name = "e0";
eth_dev.dev_addr[0] = mac_addr[0];
eth_dev.dev_addr[1] = mac_addr[1];
@ -718,11 +697,7 @@ int rt_hw_eth_init(void)
eth_dev.parent.eth_rx = rt_eth_rx;
eth_device_init(&(eth_dev.parent), "e0");
/* link down */
eth_device_linkchange(&eth_dev.parent, RT_FALSE);
eth_device_linkchange(&eth_dev.parent, RT_FALSE); //link down
return 0;
}
INIT_COMPONENT_EXPORT(rt_hw_eth_init);
#endif /* BSP_USING_ETH */

View File

@ -0,0 +1,225 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-30 bigmagic first version
*/
#ifndef __DRV_ETH_H__
#define __DRV_ETH_H__
//#define BIT(nr) (1UL << (nr))
#define ENET_FRAME_MAX_FRAMELEN 1518U
#define SYS_REV_CTRL (0x00)
#define SYS_PORT_CTRL (0x04)
#define PORT_MODE_EXT_GPHY (3)
#define GENET_SYS_OFF (0x0000)
#define SYS_RBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x08)
#define SYS_TBUF_FLUSH_CTRL (GENET_SYS_OFF + 0x0c)
#define GENET_EXT_OFF (0x0080)
#define EXT_RGMII_OOB_CTRL (GENET_EXT_OFF + 0x0c)
#define RGMII_LINK BIT(4)
#define OOB_DISABLE BIT(5)
#define RGMII_MODE_EN BIT(6)
#define ID_MODE_DIS BIT(16)
#define GENET_RBUF_OFF (0x0300)
#define RBUF_TBUF_SIZE_CTRL (GENET_RBUF_OFF + 0xb4)
#define RBUF_CTRL (GENET_RBUF_OFF + 0x00)
#define RBUF_ALIGN_2B BIT(1)
#define GENET_UMAC_OFF (0x0800)
#define UMAC_MIB_CTRL (GENET_UMAC_OFF + 0x580)
#define UMAC_MAX_FRAME_LEN (GENET_UMAC_OFF + 0x014)
#define UMAC_MAC0 (GENET_UMAC_OFF + 0x00c)
#define UMAC_MAC1 (GENET_UMAC_OFF + 0x010)
#define UMAC_CMD (GENET_UMAC_OFF + 0x008)
#define MDIO_CMD (GENET_UMAC_OFF + 0x614)
#define UMAC_TX_FLUSH (GENET_UMAC_OFF + 0x334)
#define MDIO_START_BUSY BIT(29)
#define MDIO_READ_FAIL BIT(28)
#define MDIO_RD (2 << 26)
#define MDIO_WR BIT(26)
#define MDIO_PMD_SHIFT (21)
#define MDIO_PMD_MASK (0x1f)
#define MDIO_REG_SHIFT (16)
#define MDIO_REG_MASK (0x1f)
#define GENET_INTRL2_OFF (0x0200)
#define GENET_INTRL2_CPU_STAT (GENET_INTRL2_OFF + 0x00)
#define GENET_INTRL2_CPU_CLEAR (GENET_INTRL2_OFF + 0x08)
#define GENET_INTRL2_CPU_STAT_MASK (GENET_INTRL2_OFF + 0x0c)
#define GENET_INTRL2_CPU_SET_MASK (GENET_INTRL2_OFF + 0x10)
#define GENET_INTRL2_CPU_CLEAR_MASK (GENET_INTRL2_OFF + 0x14)
#define GENET_IRQ_MDIO_ERROR BIT(24)
#define GENET_IRQ_MDIO_DONE BIT(23)
#define GENET_IRQ_TXDMA_DONE BIT(16)
#define GENET_IRQ_RXDMA_DONE BIT(13)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define UMAC_SPEED_10 (0)
#define UMAC_SPEED_100 (1)
#define UMAC_SPEED_1000 (2)
#define UMAC_SPEED_2500 (3)
#define CMD_SPEED_SHIFT (2)
#define CMD_SPEED_MASK (3)
#define CMD_SW_RESET BIT(13)
#define CMD_LCL_LOOP_EN BIT(15)
#define CMD_TX_EN BIT(0)
#define CMD_RX_EN BIT(1)
#define MIB_RESET_RX BIT(0)
#define MIB_RESET_RUNT BIT(1)
#define MIB_RESET_TX BIT(2)
/* total number of Buffer Descriptors, same for Rx/Tx */
#define TOTAL_DESCS (256)
#define RX_DESCS TOTAL_DESCS
#define TX_DESCS TOTAL_DESCS
#define DEFAULT_Q (0x10)
#define ETH_DATA_LEN (1500)
#define ETH_HLEN (14)
#define VLAN_HLEN (4)
#define ETH_FCS_LEN (4)
/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
* 1536 is multiple of 256 bytes
*/
#define ENET_BRCM_TAG_LEN (6)
#define ENET_PAD (8)
#define ENET_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + \
VLAN_HLEN + ENET_BRCM_TAG_LEN + \
ETH_FCS_LEN + ENET_PAD)
/* Tx/Rx Dma Descriptor common bits */
#define DMA_EN BIT(0)
#define DMA_RING_BUF_EN_SHIFT (0x01)
#define DMA_RING_BUF_EN_MASK (0xffff)
#define DMA_BUFLENGTH_MASK (0x0fff)
#define DMA_BUFLENGTH_SHIFT (16)
#define DMA_RING_SIZE_SHIFT (16)
#define DMA_OWN (0x8000)
#define DMA_EOP (0x4000)
#define DMA_SOP (0x2000)
#define DMA_WRAP (0x1000)
#define DMA_MAX_BURST_LENGTH (0x8)
/* Tx specific DMA descriptor bits */
#define DMA_TX_UNDERRUN (0x0200)
#define DMA_TX_APPEND_CRC (0x0040)
#define DMA_TX_OW_CRC (0x0020)
#define DMA_TX_DO_CSUM (0x0010)
#define DMA_TX_QTAG_SHIFT (7)
/* DMA rings size */
#define DMA_RING_SIZE (0x40)
#define DMA_RINGS_SIZE (DMA_RING_SIZE * (DEFAULT_Q + 1))
/* DMA descriptor */
#define DMA_DESC_LENGTH_STATUS (0x00)
#define DMA_DESC_ADDRESS_LO (0x04)
#define DMA_DESC_ADDRESS_HI (0x08)
#define DMA_DESC_SIZE (12)
#define GENET_RX_OFF (0x2000)
#define GENET_RDMA_REG_OFF \
(GENET_RX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define GENET_TX_OFF (0x4000)
#define GENET_TDMA_REG_OFF \
(GENET_TX_OFF + TOTAL_DESCS * DMA_DESC_SIZE)
#define DMA_FC_THRESH_HI (RX_DESCS >> 4)
#define DMA_FC_THRESH_LO (5)
#define DMA_FC_THRESH_VALUE ((DMA_FC_THRESH_LO << 16) | \
DMA_FC_THRESH_HI)
#define DMA_XOFF_THRESHOLD_SHIFT (16)
#define TDMA_RING_REG_BASE \
(GENET_TDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define TDMA_READ_PTR (TDMA_RING_REG_BASE + 0x00)
#define TDMA_CONS_INDEX (TDMA_RING_REG_BASE + 0x08)
#define TDMA_PROD_INDEX (TDMA_RING_REG_BASE + 0x0c)
#define DMA_RING_BUF_SIZE (0x10)
#define DMA_START_ADDR (0x14)
#define DMA_END_ADDR (0x1c)
#define DMA_MBUF_DONE_THRESH (0x24)
#define TDMA_FLOW_PERIOD (TDMA_RING_REG_BASE + 0x28)
#define TDMA_WRITE_PTR (TDMA_RING_REG_BASE + 0x2c)
#define RDMA_RING_REG_BASE \
(GENET_RDMA_REG_OFF + DEFAULT_Q * DMA_RING_SIZE)
#define RDMA_WRITE_PTR (RDMA_RING_REG_BASE + 0x00)
#define RDMA_PROD_INDEX (RDMA_RING_REG_BASE + 0x08)
#define RDMA_CONS_INDEX (RDMA_RING_REG_BASE + 0x0c)
#define RDMA_XON_XOFF_THRESH (RDMA_RING_REG_BASE + 0x28)
#define RDMA_READ_PTR (RDMA_RING_REG_BASE + 0x2c)
#define TDMA_REG_BASE (GENET_TDMA_REG_OFF + DMA_RINGS_SIZE)
#define RDMA_REG_BASE (GENET_RDMA_REG_OFF + DMA_RINGS_SIZE)
#define DMA_RING_CFG (0x00)
#define DMA_CTRL (0x04)
#define DMA_SCB_BURST_SIZE (0x0c)
#define RX_BUF_LENGTH (2048)
#define RX_TOTAL_BUFSIZE (RX_BUF_LENGTH * RX_DESCS)
#define RX_BUF_OFFSET (2)
#define PHY_INTERFACE_MODE_RGMII (7)
#define PHY_INTERFACE_MODE_RGMII_RXID (9)
#define BCM54213PE_MII_CONTROL (0x00)
#define BCM54213PE_MII_STATUS (0x01)
#define BCM54213PE_PHY_IDENTIFIER_HIGH (0x02)
#define BCM54213PE_PHY_IDENTIFIER_LOW (0x03)
#define BCM54213PE_AUTO_NEGOTIATION_ADV (0x04)
#define BCM54213PE_AUTO_NEGOTIATION_LINK (0x05)
#define BCM54213PE_AUTO_NEGOTIATION_EXPANSION (0x06)
#define BCM54213PE_NEXT_PAGE_TX (0x07)
#define BCM54213PE_PARTNER_RX (0x08)
#define BCM54213PE_CONTROL (0x09)
#define BCM54213PE_STATUS (0x0A)
#define BCM54213PE_IEEE_EXTENDED_STATUS (0x0F)
#define BCM54213PE_PHY_EXTENDED_CONTROL (0x10)
#define BCM54213PE_PHY_EXTENDED_STATUS (0x11)
#define BCM54213PE_RECEIVE_ERROR_COUNTER (0x12)
#define BCM54213PE_FALSE_C_S_COUNTER (0x13)
#define BCM54213PE_RECEIVE_NOT_OK_COUNTER (0x14)
#define BCM54213PE_VERSION_B1 (0x600d84a2)
#define BCM54213PE_VERSION_X (0x600d84a0)
//BCM54213PE_MII_CONTROL
#define MII_CONTROL_PHY_RESET (1 << 15)
#define MII_CONTROL_AUTO_NEGOTIATION_ENABLED (1 << 12)
#define MII_CONTROL_AUTO_NEGOTIATION_RESTART (1 << 9)
#define MII_CONTROL_PHY_FULL_DUPLEX (1 << 8)
#define MII_CONTROL_SPEED_SELECTION (1 << 6)
//BCM54213PE_MII_STATUS
#define MII_STATUS_LINK_UP (1 << 2)
//BCM54213PE_CONTROL
#define CONTROL_FULL_DUPLEX_CAPABILITY (1 << 9)
#define CONTROL_HALF_DUPLEX_CAPABILITY (1 << 8)
#define SPEED_1000 (1000)
#define SPEED_100 (100)
#define SPEED_10 (10)
#endif/* __DRV_ETH_H__ */

View File

@ -0,0 +1,439 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2020-06-16 bigmagic add gpio irq
*/
#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];
uint32_t raspi_get_pin_state(uint32_t fselnum)
{
uint32_t gpfsel = 0;
switch (fselnum)
{
case 0:
gpfsel = GPIO_REG_GPFSEL0(gpio_base_addr);
break;
case 1:
gpfsel = GPIO_REG_GPFSEL1(gpio_base_addr);
break;
case 2:
gpfsel = GPIO_REG_GPFSEL2(gpio_base_addr);
break;
case 3:
gpfsel = GPIO_REG_GPFSEL3(gpio_base_addr);
break;
case 4:
gpfsel = GPIO_REG_GPFSEL4(gpio_base_addr);
break;
case 5:
gpfsel = GPIO_REG_GPFSEL5(gpio_base_addr);
break;
default:
break;
}
return gpfsel;
}
void raspi_set_pin_state(uint32_t fselnum, uint32_t gpfsel)
{
switch (fselnum)
{
case 0:
GPIO_REG_GPFSEL0(gpio_base_addr) = gpfsel;
break;
case 1:
GPIO_REG_GPFSEL1(gpio_base_addr) = gpfsel;
break;
case 2:
GPIO_REG_GPFSEL2(gpio_base_addr) = gpfsel;
break;
case 3:
GPIO_REG_GPFSEL3(gpio_base_addr) = gpfsel;
break;
case 4:
GPIO_REG_GPFSEL4(gpio_base_addr) = gpfsel;
break;
case 5:
GPIO_REG_GPFSEL5(gpio_base_addr) = gpfsel;
break;
default:
break;
}
}
static void gpio_set_pud(GPIO_PIN pin, GPIO_PUPD_FUNC mode)
{
uint32_t fselnum = pin / 16;
uint32_t fselrest = pin % 16;
uint32_t reg_value = 0;
switch (fselnum)
{
case 0:
reg_value = GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG0(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 1:
reg_value = GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG1(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 2:
reg_value = GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG2(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
case 3:
reg_value = GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr);
GPIO_PUP_PDN_CNTRL_REG3(gpio_base_addr) = (reg_value | (mode << (fselrest*2)));
break;
default:
break;
}
}
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode)
{
uint32_t fselnum = pin / 10;
uint32_t fselrest = pin % 10;
uint32_t gpfsel = 0;
gpfsel = raspi_get_pin_state(fselnum);
gpfsel &= ~((uint32_t)(0x07 << (fselrest * 3)));
gpfsel |= (uint32_t)(mode << (fselrest * 3));
raspi_set_pin_state(fselnum, gpfsel);
}
void prev_raspi_pin_write(GPIO_PIN pin, int pin_value)
{
uint32_t num = pin / 32;
if(num == 0)
{
if(pin_value == 1)
{
GPIO_REG_GPSET0(gpio_base_addr) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR0(gpio_base_addr) = 1 << (pin % 32);
}
}
else
{
if(pin_value == 1)
{
GPIO_REG_GPSET1(gpio_base_addr) = 1 << (pin % 32);
}
else
{
GPIO_REG_GPCLR1(gpio_base_addr) = 1 << (pin % 32);
}
}
}
static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_uint8_t mode)
{
GPIO_FUNC raspi_mode = OUTPUT;
switch (mode)
{
case PIN_MODE_OUTPUT:
raspi_mode = OUTPUT;
break;
case PIN_MODE_INPUT:
raspi_mode = INPUT;
break;
case PIN_MODE_INPUT_PULLUP:
gpio_set_pud(pin, RASPI_PULL_UP);
raspi_mode = INPUT;
break;
case PIN_MODE_INPUT_PULLDOWN:
gpio_set_pud(pin, RASPI_PULL_DOWN);
raspi_mode = INPUT;
break;
case PIN_MODE_OUTPUT_OD:
raspi_mode = OUTPUT;
break;
}
prev_raspi_pin_mode((GPIO_PIN)pin, raspi_mode);
}
static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_uint8_t value)
{
prev_raspi_pin_write(pin, value);
}
static rt_int8_t raspi_pin_read(struct rt_device *device, rt_base_t pin)
{
uint32_t num = pin / 32;
uint32_t pin_level = 0;
if(num == 0)
{
if(GPIO_REG_GPLEV0(gpio_base_addr) & (1 << pin))
{
pin_level = 1;
}
else
{
pin_level = 0;
}
}
else
{
if(GPIO_REG_GPLEV1(gpio_base_addr) & (1 << pin))
{
pin_level = 1;
}
else
{
pin_level = 0;
}
}
return pin_level;
}
static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
{
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_uint8_t pin_num = pin / 32;
rt_uint32_t mask = 1 << shift;
switch (mode)
{
case PIN_IRQ_MODE_RISING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPREN0(gpio_base_addr);
GPIO_REG_GPREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPREN1(gpio_base_addr);
GPIO_REG_GPREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_FALLING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPFEN0(gpio_base_addr);
GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPFEN1(gpio_base_addr);
GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_RISING_FALLING:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPAREN0(gpio_base_addr);
GPIO_REG_GPAREN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
reg_value = GPIO_REG_GPFEN0(gpio_base_addr);
GPIO_REG_GPFEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPAREN1(gpio_base_addr);
GPIO_REG_GPAREN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
reg_value = GPIO_REG_GPFEN1(gpio_base_addr);
GPIO_REG_GPFEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPHEN0(gpio_base_addr);
GPIO_REG_GPHEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPHEN1(gpio_base_addr);
GPIO_REG_GPHEN1(gpio_base_addr) = (reg_value & ~ mask) | ( mask);
}
break;
case PIN_IRQ_MODE_LOW_LEVEL:
if(pin_num == 0)
{
reg_value = GPIO_REG_GPLEN0(gpio_base_addr);
GPIO_REG_GPLEN0(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
else
{
reg_value = GPIO_REG_GPLEN1(gpio_base_addr);
GPIO_REG_GPLEN1(gpio_base_addr) = (reg_value & ~ mask) | (mask);
}
break;
}
return RT_EOK;
}
static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_base_t pin)
{
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] = RT_NULL;
_g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL;
_g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL;
_g_gpio_irq_tbl[index].state[pin] = RT_NULL;
return RT_EOK;
}
rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
{
rt_uint8_t index;
if (pin <= 27)
index = 0;
else if (pin <= 45)
index = 1;
else
index = 2;
if (enabled)
_g_gpio_irq_tbl[index].state[pin] = 1;
else
_g_gpio_irq_tbl[index].state[pin] = 0;
return RT_EOK;
}
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,
RT_NULL,
};
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 = GPIO_REG_GPEDS0(gpio_base_addr);
value &= 0x0fffffff;
pin = 0;
GPIO_REG_GPEDS0(gpio_base_addr) = value;
}
else if(irq == IRQ_GPIO1)
{
/* 28-45 */
tmpvalue = GPIO_REG_GPEDS0(gpio_base_addr);
tmpvalue &= (~0x0fffffff);
GPIO_REG_GPEDS0(gpio_base_addr) = tmpvalue;
value = GPIO_REG_GPEDS1(gpio_base_addr);
value &= 0x3fff;
GPIO_REG_GPEDS1(gpio_base_addr) = value;
value = (value) | tmpvalue;
pin = 28;
}
else if (irq == IRQ_GPIO2)
{
/* 46-53 */
value = GPIO_REG_GPEDS1(gpio_base_addr);
value &= (~0x3fff);
GPIO_REG_GPEDS1(gpio_base_addr) = value;
pin = 46;
}
while (value)
{
if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
{
if(irq_def->state[pin])
{
irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
}
}
pin++;
value = value >> 1;
}
}
#endif
int rt_hw_gpio_init(void)
{
#ifdef BSP_USING_PIN
rt_device_pin_register("gpio", &ops, RT_NULL);
//disable all intr
GPIO_REG_GPEDS0(gpio_base_addr) = 0xffffffff;
GPIO_REG_GPEDS1(gpio_base_addr) = 0xffffffff;
GPIO_REG_GPREN0(gpio_base_addr) = 0x0;
GPIO_REG_GPREN1(gpio_base_addr) = 0x0;
GPIO_REG_GPFEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPFEN1(gpio_base_addr) = 0x0;
GPIO_REG_GPHEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPHEN1(gpio_base_addr) = 0x0;
GPIO_REG_GPAREN0(gpio_base_addr) = 0x0;
GPIO_REG_GPAREN1(gpio_base_addr) = 0x0;
GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0;
GPIO_REG_GPAFEN0(gpio_base_addr) = 0x0;
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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -17,6 +17,14 @@
#include "board.h"
#include "interrupt.h"
struct gpio_irq_def
{
void *irq_arg[32];
void (*irq_cb[32])(void *param);
rt_uint8_t irq_type[32];
rt_uint8_t state[32];
};
#define GPIO_REG_GPFSEL0(BASE) HWREG32(BASE + 0x00)
#define GPIO_REG_GPFSEL1(BASE) HWREG32(BASE + 0x04)
#define GPIO_REG_GPFSEL2(BASE) HWREG32(BASE + 0x08)
@ -59,6 +67,10 @@
#define GPIO_REG_GPPUDCLK1(BASE) HWREG32(BASE + 0x9C)
#define GPIO_REG_REV9(BASE) HWREG32(BASE + 0xA0)
#define GPIO_REG_TEST(BASE) HWREG32(BASE + 0xA4)
#define GPIO_PUP_PDN_CNTRL_REG0(BASE) HWREG32(BASE + 0xE4)
#define GPIO_PUP_PDN_CNTRL_REG1(BASE) HWREG32(BASE + 0xE8)
#define GPIO_PUP_PDN_CNTRL_REG2(BASE) HWREG32(BASE + 0xEC)
#define GPIO_PUP_PDN_CNTRL_REG3(BASE) HWREG32(BASE + 0xF0)
typedef enum {
GPIO_PIN_0,
@ -115,6 +127,12 @@ typedef enum {
ALT5 = 0b010
} GPIO_FUNC;
typedef enum {
RASPI_NO_RESISTOR = 0x00,
RASPI_PULL_UP = 0x01,
RASPI_PULL_DOWN = 0x10
} GPIO_PUPD_FUNC;
void prev_raspi_pin_mode(GPIO_PIN pin, GPIO_FUNC mode);
void prev_raspi_pin_write(GPIO_PIN pin, int pin_value);
int rt_hw_gpio_init(void);

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <rtthread.h>
#include "interrupt.h"
#ifndef RT_CPUS_NR
#define RT_CPUS_NR 1
#endif
#define GTIMER_IRQ (27)
static uint64_t _tickval[RT_CPUS_NR];
static uint64_t _increaseval[RT_CPUS_NR];
#define tickval _tickval[cpu_id]
#define increaseval _increaseval[cpu_id]
/**
* This function is the gtimer isr handler.
*
* @param vector interrupt ID
* @param parameter the parameter specified by rt_hw_interrupt_install
*
* @return none
*/
static void _hw_timer_isr(int vector, void *parameter)
{
#ifdef RT_USING_SMP
int cpu_id = rt_hw_cpu_id();
#else
int cpu_id = 0;
#endif
uint64_t cntvct_el0;
do
{
tickval += increaseval;
__asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
__asm__ volatile("mrs %0, CNTVCT_EL0":"=r"(cntvct_el0));
} while (cntvct_el0 >= tickval);
rt_tick_increase();
}
/**
* The function will initialize the general timer used for the system tick.
*
* @param none
*
* @return none
*/
rt_weak int rt_hw_gtimer_init(void)
{
#ifdef RT_USING_SMP
int cpu_id = rt_hw_cpu_id();
#else
int cpu_id = 0;
#endif
uint64_t val;
rt_hw_interrupt_install(GTIMER_IRQ, _hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(GTIMER_IRQ);
__asm__ volatile("mrs %0, CNTFRQ_EL0":"=r"(val));
increaseval = val / RT_TICK_PER_SECOND;
__asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
tickval = increaseval;
__asm__ volatile("msr CNTV_CVAL_EL0, %0"::"r"(tickval));
val = 1;
__asm__ volatile("msr CNTV_CTL_EL0, %0"::"r"(val));
return 0;
}
INIT_BOARD_EXPORT(rt_hw_gtimer_init);

View File

@ -0,0 +1,353 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#include <stdint.h>
#include <rtthread.h>
#include <ioremap.h>
#if defined(BSP_USING_HDMI) && defined(RT_USING_SMART)
#include <lwp.h>
#include <lwp_user_mm.h>
#include <hypercall.h>
#include "mbox.h"
#include "drv_hdmi.h"
#define LCD_WIDTH (800)
#define LCD_HEIGHT (480)
#define LCD_DEPTH (32)
#define LCD_BPP (32)
#define TAG_ALLOCATE_BUFFER 0x00040001
#define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
#define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
#define TAG_SET_DEPTH 0x00048005
#define TAG_SET_PIXEL_ORDER 0x00048006
#define TAG_GET_PITCH 0x00040008
#define TAG_SET_VIRT_OFFSET 0x00048009
#define TAG_END 0x00000000
enum {
MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
MBOX_TAG_FB_GET_DEPTH = 0x00040005,
MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
MBOX_TAG_FB_SET_DEPTH = 0x00048005,
MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
MBOX_TAG_FB_GET_PITCH = 0x00040008,
MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
};
#define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
static struct rt_hdmi_fb_device _hdmi;
typedef rt_uint16_t color_t;
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_ssize_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
{
return 0;
}
rt_ssize_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
return size;
}
rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
{
static unsigned long smem_start = 0;
static unsigned long smem_len = 0;
struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
switch (cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
{
if (smem_start != 0)
{
rt_hw_cpu_dcache_clean_and_invalidate((void *)smem_start, smem_len);
}
}
break;
case RTGRAPHIC_CTRL_GET_INFO:
{
struct rt_device_graphic_info *lcd_info = (struct rt_device_graphic_info *)args;
lcd_info->bits_per_pixel = 32;
lcd_info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_ARGB888; /* should be coherent to adding layers */
lcd_info->width = lcd->width;
lcd_info->height = lcd->height;
lcd_info->framebuffer = (void *)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, lcd->width * lcd->height * sizeof(rt_uint32_t), 1);
}
break;
#define FBIOGET_FSCREENINFO 0x4602
case FBIOGET_FSCREENINFO:
{
struct fb_fix_screeninfo
{
char id[16];
unsigned long smem_start;
uint32_t smem_len;
uint32_t line_length;
} *info = (struct fb_fix_screeninfo *)args;
rt_strncpy(info->id, "lcd", sizeof(info->id));
info->smem_len = lcd->width * lcd->height * sizeof(rt_uint32_t);
info->smem_start = (size_t)lwp_map_user_phy(lwp_self(), RT_NULL, lcd->fb, info->smem_len, 1);
info->line_length = lcd->width * sizeof(rt_uint32_t);
rt_memset((void *)info->smem_start, 0, info->smem_len);
smem_start = info->smem_start;
smem_len = info->smem_len;
}
break;
}
return RT_EOK;
}
#ifdef RT_USING_DEVICE_OPS
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,
};
#endif
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;
/* 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;
}
rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
mbox[3] = 4; // buffer size
mbox[4] = 0; // len
mbox[5] = 0; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
return (mbox[5] & 0x3fffffff);
}
rt_uint32_t bcm271x_mbox_fb_get_pitch(void)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_GET_PITCH;
mbox[3] = 4; // buffer size
mbox[4] = 0; // len
mbox[5] = 0; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
return mbox[5];
}
void bcm271x_mbox_fb_set_porder(int rgb)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
mbox[3] = 4; // buffer size
mbox[4] = 4; // len
mbox[5] = rgb; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
mbox[3] = 8; // buffer size
mbox[4] = 8; // len
mbox[5] = xoffset; // id
mbox[6] = yoffset;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void bcm271x_mbox_fb_setalpha(int alpha)
{
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE;
mbox[3] = 4; // buffer size
mbox[4] = 4; // len
mbox[5] = alpha; // id
mbox[6] = 0;
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
}
void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
{
mbox[0] = 4 * 35;
mbox[1] = MBOX_REQUEST;
mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
mbox[3] = 8; //size
mbox[4] = 4; //len
mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
mbox[6] = 0; //FrameBufferInfo.size
mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
mbox[8] = 8;
mbox[9] = 8;
mbox[10] = width;
mbox[11] = height;
mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
mbox[13] = 8;
mbox[14] = 8;
mbox[15] = width;
mbox[16] = height * nrender;
mbox[17] = TAG_SET_DEPTH;
mbox[18] = 4;
mbox[19] = 4;
mbox[20] = bpp;
mbox[21] = TAG_SET_PIXEL_ORDER;
mbox[22] = 4;
mbox[23] = 0;
mbox[24] = 0; //RGB, not BGR preferably
mbox[25] = TAG_GET_PITCH;
mbox[26] = 4;
mbox[27] = 0;
mbox[28] = 0;
mbox[29] = TAG_SET_VIRT_OFFSET;
mbox[30] = 8;
mbox[31] = 8;
mbox[32] = 0;
mbox[33] = 0;
mbox[34] = TAG_END;
mbox_call(8, MMU_DISABLE);
return (void *)((size_t)(mbox[5] & 0x3fffffff));
}
int hdmi_fb_init(void)
{
_hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
if (_hdmi.fb == RT_NULL)
{
rt_kprintf("init hdmi fb err!\n");
return -RT_ERROR;
}
#ifdef BSP_USING_VM_MODE
if (rt_hv_stage2_map((unsigned long)_hdmi.fb, 0x1400000))
{
rt_kprintf("alloc mmio from hyper fail!\n");
return -RT_ERROR;
}
#endif
bcm271x_mbox_fb_setoffset(0, 0);
bcm271x_mbox_fb_set_porder(0);
_hdmi.width = LCD_WIDTH;
_hdmi.height = LCD_HEIGHT;
_hdmi.depth = LCD_DEPTH;
_hdmi.pitch = 0;
_hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
//rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
rt_hdmi_fb_device_init(&_hdmi, "lcd");
return 0;
}
INIT_DEVICE_EXPORT(hdmi_fb_init);
#endif /*BSP_USING_HDMI */

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#ifndef __DRV_HDMI_H__
#define __DRV_HDMI_H__
#define RGB(r, g, b) ((((r))<<16) | (((g))<<8) | ((b)))
struct rt_hdmi_fb_device
{
struct rt_device parent;
rt_uint32_t width;
rt_uint32_t height;
rt_uint32_t depth;
rt_uint32_t pitch;
rt_uint32_t pixel_format;
rt_uint8_t *fb;
};
#endif/* __DRV_HDMI_H__ */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -8,19 +8,13 @@
* 2020-10-27 bigmagic first version
*/
#include <rtdef.h>
#include "mbox.h"
#include "raspi4.h"
#include "drv_sdio.h"
#include "mmu.h"
#ifdef BSP_USING_SDIO
static rt_uint32_t mmc_base_clock = 0;
static rt_uint32_t sdCommandTable[] =
{
static rt_uint32_t sdCommandTable[] = {
SD_CMD_INDEX(0),
SD_CMD_RESERVED(1),
SD_CMD_INDEX(2) | SD_RESP_R2,
@ -47,7 +41,7 @@ static rt_uint32_t sdCommandTable[] =
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(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,
@ -56,13 +50,13 @@ static rt_uint32_t sdCommandTable[] =
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_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_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),
@ -87,52 +81,46 @@ static rt_uint32_t sdCommandTable[] =
SD_CMD_RESERVED(63)
};
rt_inline rt_uint32_t read32(rt_ubase_t addr)
static inline rt_uint32_t read32(size_t addr)
{
return (*((volatile unsigned int *)(addr)));
return (*((volatile unsigned int*)(addr)));
}
rt_inline void write32(rt_ubase_t addr, rt_uint32_t value)
static inline void write32(size_t addr, rt_uint32_t value)
{
(*((volatile unsigned int *)(addr))) = value;
(*((volatile unsigned int*)(addr))) = value;
}
rt_err_t sd_int(struct sdhci_pdata_t *pdat, rt_uint32_t mask)
rt_err_t sd_int(struct sdhci_pdata_t * pdat, rt_uint32_t mask)
{
rt_uint32_t r;
rt_uint32_t 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);
/* qemu maybe can not use sdcard */
rt_kprintf("send cmd/data timeout wait for %x int: %x, status: %x\n", mask, r, read32(pdat->virt + EMMC_STATUS));
//qemu maybe can not use sdcard
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));
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)
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;
@ -145,7 +133,7 @@ rt_err_t sd_status(struct sdhci_pdata_t *pdat, unsigned int mask)
return RT_EOK;
}
static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_cmd_t *cmd)
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;
@ -158,30 +146,19 @@ static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_
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_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)
@ -200,10 +177,10 @@ static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_
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 ;
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
{
@ -214,43 +191,34 @@ static rt_err_t raspi_transfer_command(struct sdhci_pdata_t *pdat, struct sdhci_
}
}
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));
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)
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);
rt_kprintf("timeout happens when reading block %d\n",c);
return ret;
}
for (d = 0; d < blksize / 4; d++)
{
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)
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;
@ -261,10 +229,8 @@ static rt_err_t write_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uin
{
return ret;
}
for (d = 0; d < blksize / 4; d++)
{
for (d=0; d < blksize / 4; d++)
write32(pdat->virt + EMMC_DATA, buf[d]);
}
c++;
buf += blksize / 4;
}
@ -273,15 +239,13 @@ static rt_err_t write_bytes(struct sdhci_pdata_t *pdat, rt_uint32_t *buf, rt_uin
{
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)
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");
@ -294,13 +258,10 @@ static rt_err_t raspi_transfer_data(struct sdhci_pdata_t *pdat, struct sdhci_cmd
newcmd.cmdarg = dat->blkcnt;
newcmd.resptype = RESP_R1;
ret = raspi_transfer_command(pdat, &newcmd);
if (ret)
{
return ret;
}
if (ret) return ret;
}
if (dlen < 512)
if(dlen < 512)
{
write32(pdat->virt + EMMC_BLKSIZECNT, dlen | 1 << 16);
}
@ -312,34 +273,26 @@ static rt_err_t raspi_transfer_data(struct sdhci_pdata_t *pdat, struct sdhci_cmd
{
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);
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);
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)
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;
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);
}
@ -356,7 +309,7 @@ static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *re
cmd.cmdidx = req->cmd->cmd_code;
cmd.cmdarg = req->cmd->arg;
cmd.resptype = resp_type(req->cmd);
cmd.resptype =resp_type(req->cmd);
if (req->data)
{
dat.buf = (rt_uint8_t *)req->data->buf;
@ -380,7 +333,7 @@ static void mmc_request_send(struct rt_mmcsd_host *host, struct rt_mmcsd_req *re
{
stop.cmdidx = req->stop->cmd_code;
stop.cmdarg = req->stop->arg;
cmd.resptype = resp_type(req->stop);
cmd.resptype =resp_type(req->stop);
req->stop->err = sdhci_transfer(sdhci, &stop, RT_NULL);
}
@ -392,15 +345,15 @@ rt_int32_t mmc_card_status(struct rt_mmcsd_host *host)
return 0;
}
static rt_err_t sdhci_detect(struct sdhci_t *sdhci)
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)
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;
struct sdhci_pdata_t * pdat = (struct sdhci_pdata_t *)sdhci->priv;
if (width == MMCSD_BUS_WIDTH_4)
{
temp = read32((pdat->virt + EMMC_CONTROL0));
@ -412,27 +365,22 @@ static rt_err_t sdhci_setwidth(struct sdhci_t *sdhci, rt_uint32_t width)
}
static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer, rt_uint32_t base_clock, rt_uint32_t target_rate)
static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer ,rt_uint32_t base_clock, rt_uint32_t target_rate)
{
rt_uint32_t targetted_divisor = 0;
rt_uint32_t freq_select = 0;
rt_uint32_t upper_bits = 0;
rt_uint32_t ret = 0;
int divisor = -1;
if (target_rate > base_clock)
{
if(target_rate > base_clock)
targetted_divisor = 1;
}
else
{
targetted_divisor = base_clock / target_rate;
rt_uint32_t mod = base_clock % target_rate;
if (mod)
{
if(mod)
targetted_divisor--;
}
}
// Decide on the clock mode to use
@ -442,14 +390,15 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer, rt_uint32_t base_clo
// This requires a power-of-two divider
// Find the first bit set
for (int first_bit = 31; first_bit >= 0; first_bit--)
int divisor = -1;
for(int first_bit = 31; first_bit >= 0; first_bit--)
{
rt_uint32_t bit_test = (1 << first_bit);
if (targetted_divisor & bit_test)
if(targetted_divisor & bit_test)
{
divisor = first_bit;
targetted_divisor &= ~bit_test;
if (targetted_divisor)
if(targetted_divisor)
{
// The divisor is not a power-of-two, increase it
divisor++;
@ -458,24 +407,16 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer, rt_uint32_t base_clo
}
}
if (divisor == -1)
{
if(divisor == -1)
divisor = 31;
}
if (divisor >= 32)
{
if(divisor >= 32)
divisor = 31;
}
if (divisor != 0)
{
if(divisor != 0)
divisor = (1 << (divisor - 1));
}
if (divisor >= 0x400)
{
if(divisor >= 0x400)
divisor = 0x3ff;
}
freq_select = divisor & 0xff;
upper_bits = (divisor >> 8) & 0x3;
@ -484,27 +425,25 @@ static uint32_t sd_get_clock_divider(rt_uint32_t sdHostVer, rt_uint32_t base_clo
return ret;
}
static rt_err_t sdhci_setclock(struct sdhci_t *sdhci, rt_uint32_t clock)
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);
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;
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);
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);
@ -516,26 +455,23 @@ static rt_err_t sdhci_setclock(struct sdhci_t *sdhci, rt_uint32_t clock)
temp |= (7 << 16);
temp = (temp & 0xffff003f) | cdiv;
write32((pdat->virt + EMMC_CONTROL1), temp);
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);
write32((pdat->virt + EMMC_CONTROL1),temp);
DELAY_MICROS(10);
// wait for clock to be stable.
// 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;
return RT_ERROR;
}
mmcsd_dbg("set stable clock %d.\n", clock);
@ -544,7 +480,7 @@ static rt_err_t sdhci_setclock(struct sdhci_t *sdhci, rt_uint32_t clock)
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;
struct sdhci_t * sdhci = (struct sdhci_t *)host->private_data;
sdhci_setclock(sdhci, io_cfg->clock);
sdhci_setwidth(sdhci, io_cfg->bus_width);
}
@ -557,30 +493,28 @@ static const struct rt_mmcsd_host_ops ops =
RT_NULL,
};
static rt_err_t reset_emmc(struct sdhci_pdata_t *pdat)
static rt_err_t reset_emmc(struct sdhci_pdata_t * pdat)
{
rt_uint32_t control1;
int cnt = 10000;
/* reset the controller */
//Reset the controller
control1 = read32((pdat->virt + EMMC_CONTROL1));
control1 |= (1 << 24);
/* disable clock */
// Disable clock
control1 &= ~(1 << 2);
control1 &= ~(1 << 0);
/* temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX; */
write32((pdat->virt + EMMC_CONTROL1), control1);
//temp |= C1_CLK_INTLEN | C1_TOUNIT_MAX;
write32((pdat->virt + EMMC_CONTROL1),control1);
int cnt = 10000;
do
{
DELAY_MICROS(10);
--cnt;
if (cnt == 0)
cnt = cnt - 1;
if(cnt == 0)
{
break;
}
}
while ((read32(pdat->virt + EMMC_CONTROL1) & (0x7 << 24)) != 0);
} while ((read32(pdat->virt + EMMC_CONTROL1) & (0x7 << 24)) != 0);
// Enable SD Bus Power VDD1 at 3.3V
rt_uint32_t control0 = read32(pdat->virt + EMMC_CONTROL0);
@ -588,25 +522,25 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t *pdat)
write32(pdat->virt + EMMC_CONTROL0, control0);
rt_thread_delay(100);
//usleep(2000);
/* check for a valid card */
// Check for a valid card
mmcsd_dbg("EMMC: checking for an inserted card\n");
cnt = 10000;
do
{
DELAY_MICROS(10);
--cnt;
if (cnt == 0)
cnt = cnt - 1;
if(cnt == 0)
{
break;
}
}
while ((read32(pdat->virt + EMMC_STATUS) & (0x1 << 16)) == 0);
} while ((read32(pdat->virt + EMMC_STATUS) & (0x1 << 16)) == 0);
rt_uint32_t status_reg = read32(pdat->virt + EMMC_STATUS);
if ((status_reg & (1 << 16)) == 0)
if((status_reg & (1 << 16)) == 0)
{
rt_kprintf("EMMC: no card inserted\n");
return -1;
@ -616,30 +550,26 @@ static rt_err_t reset_emmc(struct sdhci_pdata_t *pdat)
mmcsd_dbg("EMMC: status: %08x\n", status_reg);
}
/* clear control2 */
// Clear control2
write32(pdat->virt + EMMC_CONTROL2, 0);
/* get the base clock rate */
// Get the base clock rate //12
mmc_base_clock = bcm271x_mbox_clock_get_rate(EMMC_CLK_ID);
if (mmc_base_clock == 0)
if(mmc_base_clock == 0)
{
rt_kprintf("EMMC: assuming clock rate to be 100MHz\n");
mmc_base_clock = 100000000;
}
mmcsd_dbg("EMMC: setting clock rate is %d\n", mmc_base_clock);
return RT_EOK;
}
#ifdef RT_MMCSD_DBG
void dump_registers(struct sdhci_pdata_t *pdat)
void dump_registers(struct sdhci_pdata_t * pdat)
{
int i = EMMC_ARG2;
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));
@ -656,9 +586,9 @@ void dump_registers(struct sdhci_pdata_t *pdat)
int raspi_sdmmc_init(void)
{
size_t virt;
struct rt_mmcsd_host *host = RT_NULL;
struct sdhci_pdata_t *pdat = RT_NULL;
struct sdhci_t *sdhci = RT_NULL;
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();
@ -675,7 +605,7 @@ int raspi_sdmmc_init(void)
}
rt_memset(sdhci, 0, sizeof(struct sdhci_t));
virt = MMC2_BASE_ADDR;
virt = mmc2_base_addr;
pdat = (struct sdhci_pdata_t *)rt_malloc(sizeof(struct sdhci_pdata_t));
RT_ASSERT(pdat != RT_NULL);
@ -703,9 +633,8 @@ int raspi_sdmmc_init(void)
host->max_blk_count = 1;
host->private_data = sdhci;
write32((pdat->virt + EMMC_IRPT_EN), 0xffffffff);
write32((pdat->virt + EMMC_IRPT_MASK), 0xffffffff);
write32((pdat->virt + EMMC_IRPT_EN),0xffffffff);
write32((pdat->virt + EMMC_IRPT_MASK),0xffffffff);
#ifdef RT_MMCSD_DBG
dump_registers(pdat);
#endif
@ -720,5 +649,3 @@ err:
}
INIT_DEVICE_EXPORT(raspi_sdmmc_init);
#endif /* BSP_USING_SDIO */

View File

@ -0,0 +1,253 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-27 bigmagic first version
*/
#ifndef __DRV_SDIO_H__
#define __DRV_SDIO_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/mmcsd_core.h>
#include "board.h"
#include "raspi4.h"
/* 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
{
size_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_CAPABILITIES_0 (0x40)
#define EMMC_CAPABILITIES_1 (0x44)
#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

View File

@ -0,0 +1,296 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-22 bigmagic first version
*/
#include <rtthread.h>
#include <rthw.h>
#include <rtdevice.h>
#include "raspi4.h"
#include "drv_spi.h"
#ifdef BSP_USING_SPI
#define RPI_CORE_CLK_HZ (250000000)
#define BSP_SPI_MAX_HZ (30* 1000 *1000)
#define SPITIMEOUT 0x0FFF
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
};
#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)
static struct rt_spi_device spi0_device0;
#endif
#if defined (BSP_USING_SPI0_DEVICE1)
static struct rt_spi_device spi0_device1;
#endif
#endif
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;
struct raspi_spi_device* hw_config = (struct raspi_spi_device *)(device->parent.user_data);
struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config;
// spi clear fifo
SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
if(cfg->mode & RT_SPI_CPOL)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPOL;
}
if(cfg->mode & RT_SPI_CPHA)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CPHA;
}
if(cfg->mode & RT_SPI_CS_HIGH)
{
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CSPOL_HIGH;
}
//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;
SPI_REG_CLK(hwcfg->hw_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];//reverse
else
return b;
}
static rt_err_t spi_transfernb(struct raspi_spi_hw_config *hwcfg, 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 */
SPI_REG_CS(hwcfg->hw_base) |= (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
/* Set TA = 1 */
SPI_REG_CS(hwcfg->hw_base) |= SPI_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 (((SPI_REG_CS(hwcfg->hw_base) & SPI_CS_TX_DATA)) && (TXCnt < len))
{
SPI_REG_FIFO(hwcfg->hw_base) = correct_order(tbuf[TXCnt],flag);
TXCnt++;
}
/* Rx fifo not empty, so get the next received bytes */
while (((SPI_REG_CS(hwcfg->hw_base) & SPI_CS_RX_DATA)) && (RXCnt < len))
{
rbuf[RXCnt] = correct_order(SPI_REG_FIFO(hwcfg->hw_base), flag);
RXCnt++;
}
}
/* Wait for DONE to be set */
while (!(SPI_REG_CS(hwcfg->hw_base) & SPI_CS_DONE));
/* Set TA = 0, and also set the barrier */
SPI_REG_CS(hwcfg->hw_base) |= (0 & SPI_CS_TA);
return RT_EOK;
}
static rt_uint32_t raspi_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
rt_err_t res;
rt_uint8_t flag;
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);
struct rt_spi_configuration config = device->config;
struct raspi_spi_device * hw_config = (struct raspi_spi_device *)device->parent.user_data;
GPIO_PIN cs_pin = (GPIO_PIN)hw_config->cs_pin;
struct raspi_spi_hw_config *hwcfg = (struct raspi_spi_hw_config *)hw_config->spi_hw_config;
if (config.mode & RT_SPI_MSB)
{
flag = 0;
}
else
{
flag = 1;
}
if (message->cs_take)
{
(config.mode & RT_SPI_CS_HIGH)?prev_raspi_pin_write(cs_pin, 1):prev_raspi_pin_write(cs_pin, 0);
}
res = spi_transfernb(hwcfg, (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)?prev_raspi_pin_write(cs_pin, 0):prev_raspi_pin_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));
return ret;
}
rt_err_t raspi_spi_hw_init(struct raspi_spi_hw_config *hwcfg)
{
prev_raspi_pin_mode(hwcfg->sclk_pin, hwcfg->sclk_mode);
prev_raspi_pin_mode(hwcfg->miso_pin, hwcfg->miso_mode);
prev_raspi_pin_mode(hwcfg->mosi_pin, hwcfg->mosi_mode);
#if defined (BSP_USING_SPI0_DEVICE0)
prev_raspi_pin_mode(hwcfg->ce0_pin, hwcfg->ce0_mode);
#endif
#if defined (BSP_USING_SPI0_DEVICE1)
prev_raspi_pin_mode(hwcfg->ce1_pin, hwcfg->ce1_mode);
#endif
//clear rx and tx
SPI_REG_CS(hwcfg->hw_base) = (SPI_CS_CLEAR_TX | SPI_CS_CLEAR_RX);
//enable chip select
#if defined (BSP_USING_SPI0_DEVICE0)
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_0;
#endif
#if defined (BSP_USING_SPI0_DEVICE1)
SPI_REG_CS(hwcfg->hw_base) |= SPI_CS_CHIP_SELECT_1;
#endif
#if defined (BSP_USING_SPI0_DEVICE0) && defined (BSP_USING_SPI0_DEVICE1)
HWREG32(SPI_REG_CS(hwcfg->hw_base)) |= (SPI_CS_CHIP_SELECT_0 | SPI_CS_CHIP_SELECT_1);
#endif
return RT_EOK;
}
static struct rt_spi_ops raspi_spi_ops =
{
.configure = raspi_spi_configure,
.xfer = raspi_spi_xfer
};
struct raspi_spi_hw_config raspi_spi0_hw =
{
.spi_num = 0,
.sclk_pin = GPIO_PIN_11,
.sclk_mode = ALT0,
.mosi_pin = GPIO_PIN_10,
.mosi_mode = ALT0,
.miso_pin = GPIO_PIN_9,
.miso_mode = ALT0,
#if defined (BSP_USING_SPI0_DEVICE0)
.ce0_pin = GPIO_PIN_8,
.ce0_mode = ALT0,
#endif
#if defined (BSP_USING_SPI0_DEVICE1)
.ce1_pin = GPIO_PIN_7,
.ce1_mode = ALT0,
#endif
.hw_base = SPI_0_BASE,
};
#endif
#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,
.spi_hw_config = &raspi_spi0_hw,
.cs_pin = GPIO_PIN_8,
};
#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 = GPIO_PIN_7,
};
#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)
raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device0);
#endif
#if defined (BSP_USING_SPI0_DEVICE1)
raspi_spi_bus_attach_device(SPI0_BUS_NAME, &raspi_spi0_device1);
#endif
#endif
return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_spi_init);

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-16 bigmagic first version
*/
#ifndef __DRV_SPI_H__
#define __DRV_SPI_H__
#include "drv_gpio.h"
#define SPI_REG_CS(BASE) HWREG32(BASE + 0x00)
#define SPI_REG_FIFO(BASE) HWREG32(BASE + 0x04)
#define SPI_REG_CLK(BASE) HWREG32(BASE + 0x08)
#define SPI_REG_DLEN(BASE) HWREG32(BASE + 0x0C)
#define SPI_REG_LTOH(BASE) HWREG32(BASE + 0x10)
#define SPI_REG_DC(BASE) HWREG32(BASE + 0x14)
/* CS Register */
#define SPI_CS_LOSSI_LONG_32BIT (1 << 25)
#define SPI_CS_LOSSI_DMA_MODE (1 << 24)
#define SPI_CS_CSPOL2 (1 << 23)
#define SPI_CS_CSPOL1 (1 << 22)
#define SPI_CS_CSPOL0 (1 << 21)
#define SPI_CS_RX_FIFO_FULL (1 << 20)
#define SPI_CS_RX_FIFO_3_QUARTER (1 << 19)
#define SPI_CS_TX_DATA (1 << 18)
#define SPI_CS_RX_DATA (1 << 17)
#define SPI_CS_DONE (1 << 16)
#define SPI_CS_LOSSI_EN (1 << 13)
#define SPI_CS_READ_EN (1 << 12)
#define SPI_CS_AUTO_CS (1 << 11)
#define SPI_CS_INTR_RXR (1 << 10)
#define SPI_CS_INTR_DONE (1 << 9)
#define SPI_CS_DMA_EN (1 << 8)
#define SPI_CS_TA (1 << 7)
#define SPI_CS_CSPOL_HIGH (1 << 6)
#define SPI_CS_CLEAR_RX (2 << 4)
#define SPI_CS_CLEAR_TX (1 << 4)
#define SPI_CS_CPOL (1 << 3)
#define SPI_CS_CPHA (1 << 2)
#define SPI_CS_CHIP_SELECT_2 (2 << 0)
#define SPI_CS_CHIP_SELECT_1 (1 << 0)
#define SPI_CS_CHIP_SELECT_0 (0 << 0)
struct raspi_spi_hw_config
{
rt_uint8_t spi_num;
GPIO_PIN sclk_pin;
GPIO_FUNC sclk_mode;
GPIO_PIN mosi_pin;
GPIO_FUNC mosi_mode;
GPIO_PIN miso_pin;
GPIO_FUNC miso_mode;
#if defined (BSP_USING_SPI0_DEVICE0) || defined (BSP_USING_SPI1_DEVICE0)
GPIO_PIN ce0_pin;
GPIO_FUNC ce0_mode;
#endif
#if defined (BSP_USING_SPI0_DEVICE1) || defined (BSP_USING_SPI1_DEVICE1)
GPIO_PIN ce1_pin;
GPIO_FUNC ce1_mode;
#endif
#if defined (BSP_USING_SPI1_DEVICE2)
GPIO_PIN ce2_pin;
GPIO_FUNC ce2_mode;
#endif
rt_ubase_t hw_base;
};
struct raspi_spi_device
{
char *device_name;
struct rt_spi_bus *spi_bus;
struct rt_spi_device *spi_device;
struct raspi_spi_hw_config *spi_hw_config;
GPIO_PIN cs_pin;
};
int rt_hw_spi_init(void);
#endif

View File

@ -1,11 +1,12 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-04-16 bigmagic first version
* 2020-05-26 bigmagic add other uart
*/
#include <rthw.h>
@ -15,12 +16,12 @@
#include "board.h"
#include "drv_uart.h"
#include "drv_gpio.h"
#include <mmu.h>
struct hw_uart_device
{
rt_ubase_t hw_base;
rt_uint32_t irqno;
};
size_t uart0_addr = 0;
size_t uart3_addr = 0;
size_t uart4_addr = 0;
size_t uart5_addr = 0;
#ifdef RT_USING_UART0
static struct rt_serial_device _serial0;
@ -42,6 +43,12 @@ static struct rt_serial_device _serial4;
static struct rt_serial_device _serial5;
#endif
struct hw_uart_device
{
rt_ubase_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;
@ -67,25 +74,25 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
return RT_EOK;
}
if(uart->hw_base == UART0_BASE)
if(uart->hw_base == uart0_addr)
{
prev_raspi_pin_mode(GPIO_PIN_14, ALT0);
prev_raspi_pin_mode(GPIO_PIN_15, ALT0);
}
if(uart->hw_base == UART3_BASE)
if(uart->hw_base == uart3_addr)
{
prev_raspi_pin_mode(GPIO_PIN_4, ALT4);
prev_raspi_pin_mode(GPIO_PIN_5, ALT4);
}
if(uart->hw_base == UART4_BASE)
if(uart->hw_base == uart4_addr)
{
prev_raspi_pin_mode(GPIO_PIN_8, ALT4);
prev_raspi_pin_mode(GPIO_PIN_9, ALT4);
}
if(uart->hw_base == UART5_BASE)
if(uart->hw_base == uart5_addr)
{
prev_raspi_pin_mode(GPIO_PIN_12, ALT4);
prev_raspi_pin_mode(GPIO_PIN_13, ALT4);
@ -107,13 +114,9 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
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 */
PL011_REG_IMSC(uart->hw_base) &= ~((uint32_t)PL011_IMSC_RXIM);
rt_hw_interrupt_mask(uart->irqno);
break;
case RT_DEVICE_CTRL_SET_INT:
@ -129,17 +132,14 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg
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;
if(uart->hw_base == AUX_BASE)
{
while (!(AUX_MU_LSR_REG(uart->hw_base) & 0x20));
@ -150,7 +150,6 @@ static int uart_putc(struct rt_serial_device *serial, char c)
while ((PL011_REG_FR(uart->hw_base) & PL011_FR_TXFF));
PL011_REG_DR(uart->hw_base) = (uint8_t)c;
}
return 1;
}
@ -188,6 +187,46 @@ static const struct rt_uart_ops _uart_ops =
uart_getc,
};
void *earlycon_base = (void *)AUX_BASE;
size_t earlycon_size = 0x1000;
extern void early_putc(int c)
{
if (c == '\n')
{
early_putc('\r');
}
while (!(AUX_MU_LSR_REG(earlycon_base) & 0x20));
AUX_MU_IO_REG(earlycon_base) = c;
}
void rt_hw_console_output(const char *str)
{
if (earlycon_base)
{
while (*str)
{
early_putc(*str++);
}
}
}
void early_printhex(rt_ubase_t number)
{
char str[sizeof("0123456789abcdef")];
str[16] = 0;
for (int i = 15; i >= 0; --i)
{
str[i] = "0123456789abcdef"[(number & 0xf)];
number >>= 4;
}
rt_kputs(str);
}
#ifdef RT_USING_UART1
static void rt_hw_aux_uart_isr(int irqno, void *param)
{
@ -203,7 +242,7 @@ static void rt_hw_uart_isr(int irqno, void *param)
{
PACTL_CS &= ~(IRQ_UART0);
rt_hw_serial_isr(&_serial0, RT_SERIAL_EVENT_RX_IND);
PL011_REG_ICR(UART0_BASE) = PL011_INTERRUPT_RECEIVE;
PL011_REG_ICR(uart0_addr) = PL011_INTERRUPT_RECEIVE;
}
#endif
@ -277,8 +316,6 @@ static struct hw_uart_device _uart5_device =
};
#endif
static struct rt_serial_device _serial0;
int rt_hw_uart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
@ -289,7 +326,12 @@ int rt_hw_uart_init(void)
_serial0.ops = &_uart_ops;
_serial0.config = config;
uart0->hw_base = UART0_BASE;
uart0_addr = UART0_BASE;
#ifdef RT_USING_SMART
uart0_addr = (size_t)rt_ioremap((void*)UART0_BASE, 0x1000);
#endif
earlycon_base = (void *)uart0_addr;
uart0->hw_base = uart0_addr;
/* register UART0 device */
@ -307,7 +349,7 @@ int rt_hw_uart_init(void)
_serial1.ops = &_uart_ops;
_serial1.config = config;
uart1->hw_base = AUX_BASE;
uart1->hw_base = (size_t)rt_ioremap((void*)AUX_BASE, 0x1000);
/* register UART1 device */
rt_hw_serial_register(&_serial1, "uart1",
@ -323,7 +365,8 @@ int rt_hw_uart_init(void)
_serial3.ops = &_uart_ops;
_serial3.config = config;
uart3_addr = UART3_BASE;
uart3_addr = (size_t)rt_ioremap((void*)UART3_BASE, 0x1000);
uart3->hw_base = uart3_addr;
/* register UART3 device */
rt_hw_serial_register(&_serial3, "uart3",
@ -339,7 +382,8 @@ int rt_hw_uart_init(void)
_serial4.ops = &_uart_ops;
_serial4.config = config;
uart4_addr = UART4_BASE;
uart4_addr = (size_t)rt_ioremap((void*)UART4_BASE, 0x1000);
uart4->hw_base = uart4_addr;
/* register UART4 device */
rt_hw_serial_register(&_serial4, "uart4",
@ -355,7 +399,8 @@ int rt_hw_uart_init(void)
_serial5.ops = &_uart_ops;
_serial5.config = config;
uart5_addr = UART5_BASE;
uart5_addr = (size_t)rt_ioremap((void*)UART5_BASE, 0x1000);
uart5->hw_base = uart5_addr;
/* register UART5 device */
rt_hw_serial_register(&_serial5, "uart5",
@ -365,3 +410,4 @@ int rt_hw_uart_init(void)
#endif
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -7,11 +7,8 @@
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#include <rthw.h>
#include "drv_wdt.h"
#include "drv_gpio.h"
#include "mbox.h"
#include "raspi4.h"
#ifdef BSP_USING_WDT
@ -62,26 +59,22 @@ rt_uint64_t raspi_watchdog_get_timeleft()
static rt_err_t raspi_wdg_init(rt_watchdog_t *wdt)
{
/* init for 10S */
/*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:
@ -102,9 +95,8 @@ static rt_err_t raspi_wdg_control(rt_watchdog_t *wdt, int cmd, void *arg)
raspi_watchdog_stop();
break;
default:
return -RT_EIO;
return RT_EIO;
}
return RT_EOK;
}
@ -124,48 +116,6 @@ int rt_hw_wdt_init(void)
}
INIT_DEVICE_EXPORT(rt_hw_wdt_init);
void poweroff(void)
{
unsigned long r;
rt_kprintf("poweroff...\n");
/* power off devices one by one */
for (r = 0; r < 16; ++r)
{
bcm271x_mbox_poweroff_devices(r);
}
/* power off gpio pins (but not VCC pins) */
GPIO_REG_GPFSEL0(GPIO_BASE) = 0;
GPIO_REG_GPFSEL1(GPIO_BASE) = 0;
GPIO_REG_GPFSEL2(GPIO_BASE) = 0;
GPIO_REG_GPFSEL3(GPIO_BASE) = 0;
GPIO_REG_GPFSEL4(GPIO_BASE) = 0;
GPIO_REG_GPFSEL5(GPIO_BASE) = 0;
GPIO_REG_GPPUD(GPIO_BASE) = 0;
rt_thread_mdelay(150);
GPIO_REG_GPPUDCLK0(GPIO_BASE) = 0xffffffff;
GPIO_REG_GPPUDCLK1(GPIO_BASE) = 0xffffffff;
rt_thread_mdelay(150);
/* flush GPIO setup */
GPIO_REG_GPPUDCLK0(GPIO_BASE) = 0;
GPIO_REG_GPPUDCLK1(GPIO_BASE) = 0;
/* power off the SoC (GPU + CPU), partition 63 used to indicate halt */
r = PM_RSTS;
r &= ~0xfffffaaa;
r |= 0x555;
PM_RSTS |= PM_PASSWORD | r;
PM_WDOG |= PM_PASSWORD | 0x0A;
PM_RSTC |= PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET;
while (1) {};
}
MSH_CMD_EXPORT(poweroff, poweroff...);
void reboot(void)
{
unsigned int r;
@ -173,13 +123,13 @@ void reboot(void)
rt_kprintf("reboot system...\n");
rt_thread_mdelay(100);
r = PM_RSTS;
/* trigger a restart by instructing the GPU to boot from partition 0 */
// trigger a restart by instructing the GPU to boot from partition 0
r &= ~0xfffffaaa;
PM_RSTS |= (PM_PASSWORD | r); /* boot from partition 0 */
PM_RSTS |= (PM_PASSWORD | r); // boot from partition 0
PM_WDOG |= (PM_PASSWORD | 0x0A);
PM_RSTC |= (PM_PASSWORD | PM_RSTC_WRCFG_FULL_RESET);
while (1) {};
while (1);
}
MSH_CMD_EXPORT(reboot, reboot system...);
MSH_CMD_EXPORT(reboot,reboot system...);
#endif /*BSP_USING_WDT */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -7,7 +7,6 @@
* Date Author Notes
* 2020-10-26 bigmagic first version
*/
#ifndef __DRV_WDT_H__
#define __DRV_WDT_H__

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
@ -10,42 +10,39 @@
*/
/* mailbox message buffer */
#include <rthw.h>
#include "mbox.h"
#include "mmu.h"
//volatile unsigned int __attribute__((aligned(16))) mbox[36];
volatile unsigned int *mbox = (volatile unsigned int *) MBOX_ADDR;
#define BUS_ADDRESS(phys) (((phys) & ~0xC0000000) | 0xC0000000)
volatile unsigned int *mbox;
/**
* Make a mailbox call. Returns 0 on failure, non-zero on success
*/
int mbox_call(unsigned char ch, int mmu_enable)
{
unsigned int r = (((MBOX_ADDR) & ~0xF) | (ch & 0xF));
if (mmu_enable)
{
unsigned int r = ((((rt_uint32_t)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);
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)
while(1)
{
/* is there a response? */
do
{
__asm__ volatile ("nop");
}
while (*MBOX_STATUS & MBOX_EMPTY);
asm volatile("nop");
} while (*MBOX_STATUS & MBOX_EMPTY);
/* is it a response to our message? */
if (r == *MBOX_READ)
{
if (r == *MBOX_READ){
/* is it a valid successful response? */
return mbox[1] == MBOX_RESPONSE;
}
@ -53,24 +50,6 @@ int mbox_call(unsigned char ch, int mmu_enable)
return 0;
}
int bcm271x_mbox_poweroff_devices(int id)
{
mbox[0] = 8 * 4; /* length of the message */
mbox[1] = MBOX_REQUEST; /* this is a request message */
mbox[2] = MBOX_TAG_SETPOWER; /* set power state */
mbox[3] = 8; /* buffer size */
mbox[4] = 8; /* len */
mbox[5] = (unsigned int)id; /* device id */
mbox[6] = 0; /* bit 0: off, bit 1: no wait */
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MBOX_CH_PROP);
return 0;
}
int bcm271x_mbox_get_touch(void)
{
mbox[0] = 8 * 4; // length of the message
@ -91,7 +70,7 @@ int bcm271x_mbox_get_touch(void)
int bcm271x_notify_reboot(void)
{
mbox[0] = 7 * 4; // length of the message
mbox[0] = 7*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_NOTIFY_REBOOT; // (the tag id)
mbox[3] = 0x00000004; // length + 4
@ -105,7 +84,7 @@ int bcm271x_notify_reboot(void)
int bcm271x_notify_xhci_reset(void)
{
mbox[0] = 7 * 4; // length of the message
mbox[0] = 7*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_NOTIFY_XHCI_RESET; // (the tag id)
mbox[3] = 0x00000004; // length + 4
@ -118,7 +97,7 @@ int bcm271x_notify_xhci_reset(void)
int bcm271x_gpu_enable(void)
{
mbox[0] = 12 * 4; // length of the message
mbox[0] = 12*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
@ -137,7 +116,7 @@ int bcm271x_gpu_enable(void)
int bcm271x_mbox_hardware_get_model(void)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_MODEL;
@ -155,7 +134,7 @@ int bcm271x_mbox_hardware_get_model(void)
int bcm271x_mbox_hardware_get_revison(void)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_REV;
@ -171,9 +150,9 @@ int bcm271x_mbox_hardware_get_revison(void)
return mbox[5];
}
int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac)
int bcm271x_mbox_hardware_get_mac_address(uint8_t * mac)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_MAC_ADDRESS;
@ -186,7 +165,7 @@ int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
char *mac_str = (char *)&mbox[5];
char * mac_str = (char *)&mbox[5];
mac[0] = mac_str[0];
mac[1] = mac_str[1];
mac[2] = mac_str[2];
@ -197,9 +176,9 @@ int bcm271x_mbox_hardware_get_mac_address(uint8_t *mac)
}
int bcm271x_mbox_hardware_get_serial(rt_uint64_t *sn)
int bcm271x_mbox_hardware_get_serial(rt_uint64_t* sn)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_SERIAL;
@ -212,14 +191,14 @@ int bcm271x_mbox_hardware_get_serial(rt_uint64_t *sn)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
sn = (rt_uint64_t *)&mbox[5];
*sn = *(rt_uint64_t *)&mbox[5];
return 0;
}
int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t *base, rt_uint32_t *size)
int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t * base, rt_uint32_t * size)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_ARM_MEMORY;
@ -239,9 +218,9 @@ int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t *base, rt_uint32_t *size)
}
int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t *base, rt_uint32_t *size)
int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t * base, rt_uint32_t * size)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_HARDWARE_GET_VC_MEMORY;
@ -262,7 +241,7 @@ int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t *base, rt_uint32_t *size)
int bcm271x_mbox_clock_get_turbo(void)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_GET_TURBO;
@ -275,7 +254,7 @@ int bcm271x_mbox_clock_get_turbo(void)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != 0)
if(mbox[5] != 0)
{
return -1;
}
@ -285,7 +264,7 @@ int bcm271x_mbox_clock_get_turbo(void)
int bcm271x_mbox_clock_set_turbo(int level)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_SET_TURBO;
@ -298,7 +277,7 @@ int bcm271x_mbox_clock_set_turbo(int level)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != 0)
if(mbox[5] != 0)
{
return -1;
}
@ -308,7 +287,7 @@ int bcm271x_mbox_clock_set_turbo(int level)
int bcm271x_mbox_clock_get_state(int id)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_GET_STATE;
@ -321,7 +300,7 @@ int bcm271x_mbox_clock_get_state(int id)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -331,7 +310,7 @@ int bcm271x_mbox_clock_get_state(int id)
int bcm271x_mbox_clock_set_state(int id, int state)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_SET_STATE;
@ -344,7 +323,7 @@ int bcm271x_mbox_clock_set_state(int id, int state)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -354,7 +333,7 @@ int bcm271x_mbox_clock_set_state(int id, int state)
int bcm271x_mbox_clock_get_rate(int id)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_GET_RATE;
@ -367,7 +346,7 @@ int bcm271x_mbox_clock_get_rate(int id)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -377,7 +356,7 @@ int bcm271x_mbox_clock_get_rate(int id)
int bcm271x_mbox_clock_set_rate(int id, int rate)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_SET_RATE;
@ -390,7 +369,7 @@ int bcm271x_mbox_clock_set_rate(int id, int rate)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -400,7 +379,7 @@ int bcm271x_mbox_clock_set_rate(int id, int rate)
int bcm271x_mbox_clock_get_max_rate(int id)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_GET_MAX_RATE;
@ -413,7 +392,7 @@ int bcm271x_mbox_clock_get_max_rate(int id)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -423,7 +402,7 @@ int bcm271x_mbox_clock_get_max_rate(int id)
int bcm271x_mbox_clock_get_min_rate(int id)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_CLOCK_GET_MIN_RATE;
@ -436,7 +415,7 @@ int bcm271x_mbox_clock_get_min_rate(int id)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -446,7 +425,7 @@ int bcm271x_mbox_clock_get_min_rate(int id)
int bcm271x_mbox_power_get_state(int id)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_POWER_GET_STATE;
@ -459,7 +438,7 @@ int bcm271x_mbox_power_get_state(int id)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -469,7 +448,7 @@ int bcm271x_mbox_power_get_state(int id)
int bcm271x_mbox_power_set_state(int id, int state)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_POWER_SET_STATE;
@ -482,7 +461,7 @@ int bcm271x_mbox_power_set_state(int id, int state)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != id)
if(mbox[5] != id)
{
return -1;
}
@ -492,7 +471,7 @@ int bcm271x_mbox_power_set_state(int id, int state)
int bcm271x_mbox_temp_get(void)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_TEMP_GET;
@ -505,7 +484,7 @@ int bcm271x_mbox_temp_get(void)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != 0)
if(mbox[5] != 0)
{
return -1;
}
@ -515,7 +494,7 @@ int bcm271x_mbox_temp_get(void)
int bcm271x_mbox_temp_get_max(void)
{
mbox[0] = 8 * 4; // length of the message
mbox[0] = 8*4; // length of the message
mbox[1] = MBOX_REQUEST; // this is a request message
mbox[2] = MBOX_TAG_TEMP_GET_MAX;
@ -528,7 +507,7 @@ int bcm271x_mbox_temp_get_max(void)
mbox[7] = MBOX_TAG_LAST;
mbox_call(8, MMU_DISABLE);
if (mbox[5] != 0)
if(mbox[5] != 0)
{
return -1;
}

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-09-10 bigmagic first version
*/
#ifndef __MBOX_H__
#define __MBOX_H__
#include <rtthread.h>
//https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
//https://github.com/hermanhermitage/videocoreiv
/* 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_TAG_LAST 0
#define MMIO_BASE 0xFE000000
#define VIDEOCORE_MBOX (MMIO_BASE+0x0000B880)
extern size_t videocore_mbox;
#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)
/*
* raspi hardware info
*/
enum {
MBOX_TAG_HARDWARE_GET_MODEL = 0x00010001,
MBOX_TAG_HARDWARE_GET_REV = 0x00010002,
MBOX_TAG_HARDWARE_GET_MAC_ADDRESS = 0x00010003,
MBOX_TAG_HARDWARE_GET_SERIAL = 0x00010004,
MBOX_TAG_HARDWARE_GET_ARM_MEMORY = 0x00010005,
MBOX_TAG_HARDWARE_GET_VC_MEMORY = 0x00010006,
MBOX_TAG_HARDWARE_GET_CLOCKS = 0x00010007,
};
/*
* raspi clock
*/
enum {
MBOX_TAG_CLOCK_GET_TURBO = 0x00030009,
MBOX_TAG_CLOCK_SET_TURBO = 0x00038009,
MBOX_TAG_CLOCK_GET_STATE = 0x00030001,
MBOX_TAG_CLOCK_SET_STATE = 0x00038001,
MBOX_TAG_CLOCK_GET_RATE = 0x00030002,
MBOX_TAG_CLOCK_SET_RATE = 0x00038002,
MBOX_TAG_CLOCK_GET_MAX_RATE = 0x00030004,
MBOX_TAG_CLOCK_GET_MIN_RATE = 0x00030007,
};
/*
* raspi power
*/
enum {
MBOX_TAG_POWER_GET_STATE = 0x00020001,
MBOX_TAG_POWER_SET_STATE = 0x00028001,
};
/*
* raspi temperature
*/
enum {
MBOX_TAG_TEMP_GET = 0x00030006,
MBOX_TAG_TEMP_GET_MAX = 0x0003000A,
};
/*
* raspi Memory
*/
enum {
MBOX_TAG_ALLOCATE_MEMORY = 0x0003000C, // Memory: Allocates Contiguous Memory On The GPU (Response: Handle)
MBOX_TAG_LOCK_MEMORY = 0x0003000D, // Memory: Unlock Buffer (Response: Status)
MBOX_TAG_UNLOCK_MEMORY = 0x0003000E, // Memory: Unlock Buffer (Response: Status)
MBOX_TAG_RELEASE_MEMORY = 0x0003000F, // Memory: Free The Memory Buffer (Response: Status)
MBOX_TAG_EXECUTE_CODE = 0x00030010, // Memory: Calls The Function At Given (Bus) Address And With Arguments Given
};
/*
* raspi GPU
*/
enum {
MBOX_TAG_EXECUTE_QPU = 0x00030011, // QPU: Calls The QPU Function At Given (Bus) Address And With Arguments Given (Response: Number Of QPUs, Control, No Flush, Timeout In ms)
MBOX_TAG_ENABLE_QPU = 0x00030012, // QPU: Enables The QPU (Response: Enable State)
};
/*
* raspi HDMI
*/
#define MBOX_TAG_GET_EDID_BLOCK 0x00030020 // HDMI: Read Specificed EDID Block From Attached HDMI/DVI Device (Response: Block Number, Status, EDID Block (128 Bytes))
/*
* raspi NOTIFY
*/
#define MBOX_TAG_NOTIFY_REBOOT 0x00030048
#define MBOX_TAG_NOTIFY_XHCI_RESET 0x00030058
/*
* touch
*/
#define MBOX_TAG_GET_TOUCHBUF (0x0004000F)
#define MBOX_ADDR 0x08000000
extern size_t mbox_addr;
#define RES_CLK_ID (0x000000000)
#define EMMC_CLK_ID (0x000000001)
#define UART_CLK_ID (0x000000002)
#define ARM_CLK_ID (0x000000003)
#define CORE_CLK_ID (0x000000004)
#define V3D_CLK_ID (0x000000005)
#define H264_CLK_ID (0x000000006)
#define ISP_CLK_ID (0x000000007)
#define SDRAM_CLK_ID (0x000000008)
#define PIXEL_CLK_ID (0x000000009)
#define PWM_CLK_ID (0x00000000a)
int mbox_call(unsigned char ch, int mmu_enable);
int bcm271x_mbox_get_touch(void);
int bcm271x_notify_reboot(void);
int bcm271x_notify_xhci_reset(void);
int bcm271x_gpu_enable(void);
int bcm271x_mbox_hardware_get_model(void);
int bcm271x_mbox_hardware_get_revison(void);
int bcm271x_mbox_hardware_get_mac_address(uint8_t * mac);
int bcm271x_mbox_hardware_get_serial(rt_uint64_t* sn);
int bcm271x_mbox_hardware_get_arm_memory(rt_uint32_t * base, rt_uint32_t * size);
int bcm271x_mbox_hardware_get_vc_memory(rt_uint32_t * base, rt_uint32_t * size);
int bcm271x_mbox_clock_get_turbo(void);
int bcm271x_mbox_clock_set_turbo(int level);
int bcm271x_mbox_clock_get_state(int id);
int bcm271x_mbox_clock_set_state(int id, int state);
int bcm271x_mbox_clock_get_rate(int id);
int bcm271x_mbox_clock_set_rate(int id, int rate);
int bcm271x_mbox_clock_get_max_rate(int id);
int bcm271x_mbox_clock_get_min_rate(int id);
int bcm271x_mbox_power_get_state(int id);
int bcm271x_mbox_power_set_state(int id, int state);
int bcm271x_mbox_temp_get(void);
int bcm271x_mbox_temp_get_max(void);
#endif

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-06 RT-Thread first version
*/
#ifndef __RASPI4_H__
#define __RASPI4_H__
#include <rtthread.h>
//https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/rpi_DATA_2711_1p0.pdf
#define __REG32(x) (*((volatile unsigned int *)(x)))
#define __REG16(x) (*((volatile unsigned short *)(x)))
/* GIC IRQ MAX */
#define MAX_HANDLERS (256)
/* base address */
#define PER_BASE (0xFE000000)
//gpio offset
#define GPIO_BASE_OFFSET (0x00200000)
#define PL011_UART_BASE_OFFSET (0x00201000)
//pl011 offset
#define PL011_UART0_BASE_OFFSET (0x00201000)
#define PL011_UART2_BASE_OFFSET (0x00201400)
#define PL011_UART3_BASE_OFFSET (0x00201600)
#define PL011_UART4_BASE_OFFSET (0x00201800)
#define PL011_UART5_BASE_OFFSET (0x00201A00)
//pactl cs offset
#define PACTL_CS_OFFSET (0x00204E00)
//aux offset
#define AUX_BASE_OFFSET (0x00215000)
/* GPIO */
#define GPIO_BASE_ADDR (PER_BASE + GPIO_BASE_OFFSET)
extern size_t gpio_base_addr;
#define GPIO_BASE (gpio_base_addr)
#define GPIO_IRQ_NUM (3) //40 pin mode
#define IRQ_GPIO0 (96 + 49) //bank0 (0 to 27)
#define IRQ_GPIO1 (96 + 50) //bank1 (28 to 45)
#define IRQ_GPIO2 (96 + 51) //bank2 (46 to 57)
#define IRQ_GPIO3 (96 + 52) //bank3
/* Timer (ARM side) */
#define ARM_TIMER_IRQ (64)
extern size_t arm_timer_base;
#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)
/* UART PL011 */
#define UART_BASE (PER_BASE + PL011_UART_BASE_OFFSET)
//extern uint32_t uart_base_addr;
#define UART0_BASE (UART_BASE + 0x0)
#define UART2_BASE (UART_BASE + 0x400)
#define UART3_BASE (UART_BASE + 0x600)
#define UART4_BASE (UART_BASE + 0x800)
#define UART5_BASE (UART_BASE + 0xA00)
#define IRQ_AUX_UART (96 + 29)
#define UART_REFERENCE_CLOCK (48000000)
/* AUX */
//#define AUX_BASE_ADDR (PER_BASE + AUX_BASE_OFFSET)
//extern uint32_t aux_addr;
//#define AUX_BASE (aux_addr + 0x0)
#define AUX_BASE (PER_BASE + AUX_BASE_OFFSET)
#define IRQ_PL011 (96 + 57)
/* Peripheral IRQ OR-ing */
#define PACTL_CS_ADDR (PER_BASE + PACTL_CS_OFFSET)
extern size_t pactl_cs_base;
#define PACTL_CS HWREG32(pactl_cs_base)
typedef enum
{
IRQ_SPI0 = 0x00000000,
IRQ_SPI1 = 0x00000002,
IRQ_SPI2 = 0x00000004,
IRQ_SPI3 = 0x00000008,
IRQ_SPI4 = 0x00000010,
IRQ_SPI5 = 0x00000020,
IRQ_SPI6 = 0x00000040,
IRQ_I2C0 = 0x00000100,
IRQ_I2C1 = 0x00000200,
IRQ_I2C2 = 0x00000400,
IRQ_I2C3 = 0x00000800,
IRQ_I2C4 = 0x00001000,
IRQ_I2C5 = 0x00002000,
IRQ_I2C6 = 0x00004000,
IRQ_I2C7 = 0x00008000,
IRQ_UART5 = 0x00010000,
IRQ_UART4 = 0x00020000,
IRQ_UART3 = 0x00040000,
IRQ_UART2 = 0x00080000,
IRQ_UART0 = 0x00100000
} PACTL_CS_VAL;
// 0x40, 0x44, 0x48, 0x4c: Core 0~3 Timers interrupt control
#define CORE0_TIMER_IRQ_CTRL HWREG32(0xFF800040)
#define TIMER_IRQ 30
#define NON_SECURE_TIMER_IRQ (1 << 1)
/* GIC */
#define INTC_BASE (0xff800000)
#define ARM_GIC_NR_IRQS (512)
#define ARM_GIC_MAX_NR (512)
#define GIC_V2_BASE (INTC_BASE + 0x00040000)
extern size_t gic_base_addr;
#define GIC_V2_DISTRIBUTOR_BASE (gic_base_addr + 0x1000)
#define GIC_V2_CPU_INTERFACE_BASE (gic_base_addr + 0x2000)
#define GIC_V2_HYPERVISOR_BASE (gic_base_addr + 0x4000)
#define GIC_V2_VIRTUAL_CPU_BASE (gic_base_addr + 0x6000)
#define GIC_PL400_DISTRIBUTOR_PPTR GIC_V2_DISTRIBUTOR_BASE
#define GIC_PL400_CONTROLLER_PPTR GIC_V2_CPU_INTERFACE_BASE
#define GIC_IRQ_START 0
#define GIC_ACK_INTID_MASK 0x000003ff
//watchdog
#define WDT_BASE (PER_BASE + 0x00100000)
extern size_t wdt_base_addr;
#define PM_RSTC HWREG32(wdt_base_addr + 0x1c)
#define PM_RSTS HWREG32(wdt_base_addr + 0x20)
#define PM_WDOG HWREG32(wdt_base_addr + 0x24)
#define PM_PASSWORD (0x5A000000)
#define PM_WDOG_TIME_SET (0x000fffff)
#define PM_RSTS_HADWRH_SET (0x00000040)
#define PM_RSTC_WRCFG_FULL_RESET (0x00000020)
#define PM_RSTC_WRCFG_CLR (0xffffffcf)
#define PM_RSTC_RESET (0x00000102)
//timer
#define ST_BASE_OFFSET (0x003000)
#define STIMER_BASE (PER_BASE + ST_BASE_OFFSET)
extern size_t stimer_base_addr;
#define STIMER_CS __REG32(stimer_base_addr + 0x0000)
#define STIMER_CLO __REG32(stimer_base_addr + 0x0004)
#define STIMER_CHI __REG32(stimer_base_addr + 0x0008)
#define STIMER_C0 __REG32(stimer_base_addr + 0x000C)
#define STIMER_C1 __REG32(stimer_base_addr + 0x0010)
#define STIMER_C2 __REG32(stimer_base_addr + 0x0014)
#define STIMER_C3 __REG32(stimer_base_addr + 0x0018)
#define DELAY_MICROS(micros) \
do{ \
rt_uint32_t compare = STIMER_CLO + micros * 25; \
while (STIMER_CLO < compare); \
} while (0)
//External Mass Media Controller (SD Card)
#define MMC0_BASE_ADDR (PER_BASE+0x300000)
extern size_t mmc0_base_addr;
#define MMC2_BASE_ADDR (PER_BASE+0x340000)
extern size_t mmc2_base_addr;
//mac
#define MAC_REG (void *)(0xfd580000)
extern uint8_t * mac_reg_base_addr;
#define ETH_IRQ (160+29)
#define SEND_DATA_NO_CACHE (0x08200000)
extern uint8_t * eth_send_no_cache;
#define RECV_DATA_NO_CACHE (0x08400000)
extern uint8_t * eth_recv_no_cache;
/* the basic constants and interfaces needed by gic */
rt_inline size_t platform_get_gic_dist_base(void)
{
return GIC_PL400_DISTRIBUTOR_PPTR;
}
rt_inline size_t platform_get_gic_cpu_base(void)
{
return GIC_PL400_CONTROLLER_PPTR;
}
#endif

View File

@ -1,85 +1,66 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* 2017-5-30 bernard first version
*/
/* _EL1_STACK_SIZE = DEFINED(_EL1_STACK_SIZE) ? _EL1_STACK_SIZE : 0x20000; */
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
SECTIONS
{
. = 0x80000;
. = ALIGN(4096);
. = 0x208000;
/* . = 0xffff000000008000; */
__text_start = .;
.text :
{
KEEP(*(.text.entrypoint)) /* The entry point */
*(.vectors)
*(.text) /* remaining code */
*(.text.*) /* remaining code */
KEEP(*(.text.entrypoint))
KEEP(*(.vectors))
*(.text)
*(.text.*)
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
*(COMMON)
/* section information for utest */
. = ALIGN(4);
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
/* section information for finsh shell */
. = ALIGN(16);
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(16);
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(16);
. = ALIGN(4);
/* section information for initial. */
. = ALIGN(16);
/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for initialization */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
. = ALIGN(16);
} =0
__text_end = .;
. = ALIGN(16);
_etext = .;
}
.eh_frame_hdr :
.ARM.exidx :
{
*(.eh_frame_hdr)
*(.eh_frame_entry)
}
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
. = ALIGN(16);
.data :
{
*(.data)
*(.data.*)
*(.data1)
*(.data1.*)
. = ALIGN(16);
_gp = ABSOLUTE(.); /* Base of small data */
*(.sdata)
*(.sdata.*)
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
}
. = ALIGN(16);
__rodata_start = .;
.rodata : { *(.rodata) *(.rodata.*) }
__rodata_end = .;
. = ALIGN(4);
.ctors :
{
PROVIDE(__ctors_start__ = .);
/* new GCC version uses .init_array */
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(__ctors_end__ = .);
}
@ -91,17 +72,26 @@ SECTIONS
PROVIDE(__dtors_end__ = .);
}
. = ALIGN(16);
. = ALIGN(8);
__data_start = .;
.data :
{
*(.data)
*(.data.*)
}
__data_end = .;
. = ALIGN(8);
__bss_start = .;
.bss :
{
PROVIDE(__bss_start = .);
*(.bss)
*(.bss.*)
*(.dynbss)
PROVIDE(__bss_end = .);
*(COMMON)
. = ALIGN(4);
}
_end = .;
. = ALIGN(4);
__bss_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
@ -111,31 +101,9 @@ SECTIONS
.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) }
}
__bss_size = SIZEOF(.bss);
__data_size = SIZEOF(.data);
__bss_size = SIZEOF(.bss);
_end = .;
}

View File

@ -0,0 +1,109 @@
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
SECTIONS
{
/* . = 0x208000; */
. = 0xffff000000008000;
__text_start = .;
.text :
{
KEEP(*(.text.entrypoint))
KEEP(*(.vectors))
*(.text)
*(.text.*)
/* section information for utest */
. = ALIGN(4);
__rt_utest_tc_tab_start = .;
KEEP(*(UtestTcTab))
__rt_utest_tc_tab_end = .;
/* 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 modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for initialization */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
} =0
__text_end = .;
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
}
__rodata_start = .;
.rodata : { *(.rodata) *(.rodata.*) }
__rodata_end = .;
. = 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(8);
__data_start = .;
.data :
{
*(.data)
*(.data.*)
}
__data_end = .;
. = ALIGN(8);
__bss_start = .;
.bss :
{
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
}
. = ALIGN(4);
__bss_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) }
__data_size = SIZEOF(.data);
__bss_size = SIZEOF(.bss);
_end = .;
}

View File

@ -7,24 +7,29 @@
/* RT-Thread Kernel */
#define RT_NAME_MAX 8
#define RT_ALIGN_SIZE 8
#define RT_USING_SMP
#define RT_CPUS_NR 4
#define RT_ALIGN_SIZE 4
#define RT_THREAD_PRIORITY_32
#define RT_THREAD_PRIORITY_MAX 32
#define RT_TICK_PER_SECOND 100
#define RT_TICK_PER_SECOND 1000
#define RT_USING_OVERFLOW_CHECK
#define RT_USING_HOOK
#define RT_HOOK_USING_FUNC_PTR
#define RT_USING_IDLE_HOOK
#define RT_IDLE_HOOK_LIST_SIZE 4
#define IDLE_THREAD_STACK_SIZE 4096
#define IDLE_THREAD_STACK_SIZE 8192
#define SYSTEM_THREAD_STACK_SIZE 8192
#define RT_USING_TIMER_SOFT
#define RT_TIMER_THREAD_PRIO 4
#define RT_TIMER_THREAD_STACK_SIZE 4096
#define RT_TIMER_THREAD_STACK_SIZE 8192
/* kservice optimization */
#define RT_KSERVICE_USING_STDLIB
#define RT_KPRINTF_USING_LONGLONG
#define RT_DEBUG
#define RT_DEBUG_COLOR
/* Inter-Thread communication */
@ -37,20 +42,21 @@
/* Memory Management */
#define RT_PAGE_MAX_ORDER 11
#define RT_USING_MEMPOOL
#define RT_USING_SMALL_MEM
#define RT_USING_SMALL_MEM_AS_HEAP
#define RT_USING_SLAB
#define RT_USING_SLAB_AS_HEAP
#define RT_USING_HEAP
/* Kernel Device Object */
#define RT_USING_DEVICE
#define RT_USING_INTERRUPT_INFO
#define RT_USING_CONSOLE
#define RT_CONSOLEBUF_SIZE 128
#define RT_CONSOLEBUF_SIZE 256
#define RT_CONSOLE_DEVICE_NAME "uart0"
#define RT_VER_NUM 0x50000
#define ARCH_CPU_64BIT
#define RT_USING_CACHE
#define RT_USING_HW_ATOMIC
#define ARCH_MM_MMU
#define ARCH_ARM
#define ARCH_ARM_MMU
@ -60,14 +66,14 @@
#define RT_USING_COMPONENTS_INIT
#define RT_USING_USER_MAIN
#define RT_MAIN_THREAD_STACK_SIZE 4096
#define RT_MAIN_THREAD_STACK_SIZE 8192
#define RT_MAIN_THREAD_PRIORITY 10
#define RT_USING_MSH
#define RT_USING_FINSH
#define FINSH_USING_MSH
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_STACK_SIZE 4096
#define FINSH_THREAD_STACK_SIZE 8192
#define FINSH_USING_HISTORY
#define FINSH_HISTORY_LINES 5
#define FINSH_USING_SYMTAB
@ -78,9 +84,9 @@
#define RT_USING_DFS
#define DFS_USING_POSIX
#define DFS_USING_WORKDIR
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 16
#define DFS_FILESYSTEMS_MAX 4
#define DFS_FILESYSTEM_TYPES_MAX 4
#define DFS_FD_MAX 32
#define RT_USING_DFS_ELMFAT
/* elm-chan's FatFs, Generic FAT Filesystem Module */
@ -97,6 +103,7 @@
#define RT_DFS_ELM_REENTRANT
#define RT_DFS_ELM_MUTEX_TIMEOUT 3000
#define RT_USING_DFS_DEVFS
#define RT_USING_DFS_TMPFS
/* Device Drivers */
@ -109,16 +116,26 @@
#define RT_USING_SERIAL_V1
#define RT_SERIAL_USING_DMA
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_HWTIMER
#define RT_USING_I2C
#define RT_USING_I2C_BITOPS
#define RT_USING_PIN
#define RT_USING_NULL
#define RT_USING_ZERO
#define RT_USING_RANDOM
#define RT_USING_RTC
#define RT_USING_ALARM
#define RT_USING_SOFT_RTC
#define RT_USING_SDIO
#define RT_SDIO_STACK_SIZE 512
#define RT_SDIO_STACK_SIZE 8192
#define RT_SDIO_THREAD_PRIORITY 15
#define RT_MMCSD_STACK_SIZE 8192
#define RT_MMCSD_THREAD_PREORITY 22
#define RT_MMCSD_MAX_PARTITION 16
#define RT_USING_SPI
#define RT_USING_WDT
#define RT_USING_TOUCH
#define RT_USING_LCD
#define RT_USING_DEV_BUS
/* Using USB */
@ -129,6 +146,13 @@
/* POSIX (Portable Operating System Interface) layer */
#define RT_USING_POSIX_FS
#define RT_USING_POSIX_DEVIO
#define RT_USING_POSIX_STDIO
#define RT_USING_POSIX_TERMIOS
#define RT_USING_POSIX_DELAY
#define RT_USING_POSIX_CLOCK
#define RT_USING_POSIX_TIMER
/* Interprocess Communication (IPC) */
@ -153,8 +177,8 @@
#define NETDEV_IPV4 1
#define NETDEV_IPV6 0
#define RT_USING_LWIP
#define RT_USING_LWIP203
#define RT_USING_LWIP_VER_NUM 0x20003
#define RT_USING_LWIP212
#define RT_USING_LWIP_VER_NUM 0x20102
#define RT_LWIP_MEM_ALIGNMENT 4
#define RT_LWIP_IGMP
#define RT_LWIP_ICMP
@ -165,26 +189,27 @@
/* Static IPv4 Address */
#define RT_LWIP_IPADDR "192.168.1.30"
#define RT_LWIP_GWADDR "192.168.1.1"
#define RT_LWIP_IPADDR "192.168.137.100"
#define RT_LWIP_GWADDR "192.168.137.1"
#define RT_LWIP_MSKADDR "255.255.255.0"
#define RT_LWIP_UDP
#define RT_LWIP_TCP
#define RT_LWIP_RAW
#define RT_MEMP_NUM_NETCONN 8
#define RT_MEMP_NUM_NETCONN 16
#define RT_LWIP_PBUF_NUM 16
#define RT_LWIP_RAW_PCB_NUM 4
#define RT_LWIP_UDP_PCB_NUM 4
#define RT_LWIP_TCP_PCB_NUM 4
#define RT_LWIP_UDP_PCB_NUM 8
#define RT_LWIP_TCP_PCB_NUM 8
#define RT_LWIP_TCP_SEG_NUM 40
#define RT_LWIP_TCP_SND_BUF 8196
#define RT_LWIP_TCP_WND 8196
#define RT_LWIP_TCP_SND_BUF 8192
#define RT_LWIP_TCP_WND 8192
#define RT_LWIP_TCPTHREAD_PRIORITY 10
#define RT_LWIP_TCPTHREAD_MBOX_SIZE 8
#define RT_LWIP_TCPTHREAD_STACKSIZE 4096
#define RT_LWIP_TCPTHREAD_STACKSIZE 16384
#define RT_LWIP_ETHTHREAD_PRIORITY 12
#define RT_LWIP_ETHTHREAD_STACKSIZE 4096
#define RT_LWIP_ETHTHREAD_STACKSIZE 16384
#define RT_LWIP_ETHTHREAD_MBOX_SIZE 8
#define RT_LWIP_REASSEMBLY_FRAG
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define SO_REUSE 1
@ -192,13 +217,15 @@
#define LWIP_SO_SNDTIMEO 1
#define LWIP_SO_RCVBUF 1
#define LWIP_SO_LINGER 0
#define LWIP_NETIF_LOOPBACK 0
#define RT_LWIP_NETIF_LOOPBACK
#define LWIP_NETIF_LOOPBACK 1
#define RT_LWIP_USING_PING
/* Utilities */
#define RT_USING_RYM
#define YMODEM_USING_FILE_TRANSFER
#define RT_USING_UTEST
#define UTEST_THR_STACK_SIZE 8192
#define UTEST_THR_PRIORITY 20
#define RT_USING_ADT
/* RT-Thread Utestcases */
@ -261,11 +288,6 @@
/* peripheral libraries and drivers */
/* sensors drivers */
/* touch drivers */
/* Kendryte SDK */
@ -273,9 +295,6 @@
/* AI packages */
/* Signal Processing and Control Algorithm Packages */
/* miscellaneous packages */
/* project laboratory */
@ -319,15 +338,8 @@
/* Uncategorized */
/* Privated Packages of RealThread */
/* Network Utilities */
/* RT-Thread Smart */
#define BCM2711_SOC
#define BSP_SUPPORT_FPU
/* Hardware Drivers Config */
@ -335,17 +347,18 @@
#define BSP_USING_UART
#define RT_USING_UART0
#define RT_USING_UART3
#define RT_USING_UART4
#define BSP_USING_GIC
#define BSP_USING_GICV2
#define BSP_USING_PIN
#define BSP_USING_CORETIMER
#define BSP_USING_WDT
#define BSP_USING_RTC
#define BSP_USING_ALARM
#define BSP_USING_SDIO
#define BSP_USING_SDIO0
/* Board Peripheral Drivers */
#define BSP_USING_HDMI
#endif

View File

@ -35,15 +35,15 @@ if PLATFORM == 'gcc':
OBJCPY = PREFIX + 'objcopy'
DEVICE = ' -march=armv8-a -mtune=cortex-a72'
CFLAGS = DEVICE + ' -Wall -Wno-cpp'
CFLAGS = DEVICE + ' -Wall -Wno-cpp -D_POSIX_SOURCE'
AFLAGS = ' -c' + ' -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'
CFLAGS += ' -O0 -ggdb'
AFLAGS += ' -ggdb'
else:
CFLAGS += ' -O2'

View File

@ -0,0 +1,5 @@
enable_uart=1
kernel=u-boot64.bin
#kernel=kernel7.img
#kernel_address=0xc0000000
arm_64bit=1

Binary file not shown.