原始版本

This commit is contained in:
冯佳
2025-06-19 21:56:46 +08:00
parent fe98e5f010
commit a4841450cf
4152 changed files with 1910684 additions and 0 deletions

View File

@ -0,0 +1,150 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-07 aozima the first version
* 2018-11-16 Ernest Chen add finsh command and update adc function
* 2022-05-11 Stanley Lwin add finsh voltage conversion command
*/
#ifndef __ADC_H__
#define __ADC_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_ADC ADC
*
* @brief ADC driver api
*
* <b>Example</b>
* @code {.c}
* #define ADC_DEV_NAME "adc1"
* #define ADC_DEV_CHANNEL 5
* #define REFER_VOLTAGE 330
* #define CONVERT_BITS (1 << 12)
*
* static int adc_vol_sample(int argc, char *argv[])
* {
* rt_adc_device_t adc_dev;
* rt_uint32_t value, vol;
*
* rt_err_t ret = RT_EOK;
*
* adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEV_NAME);
* if (adc_dev == RT_NULL)
* {
* rt_kprintf("adc sample run failed! can't find %s device!\n", ADC_DEV_NAME);
* return -RT_ERROR;
* }
*
* ret = rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
*
* value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
* rt_kprintf("the value is :%d \n", value);
*
* vol = value * REFER_VOLTAGE / CONVERT_BITS;
* rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
*
* ret = rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);
*
* return ret;
* }
* MSH_CMD_EXPORT(adc_vol_sample, adc voltage convert sample);
*
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_ADC
* @{
*/
#define RT_ADC_INTERN_CH_TEMPER (-1)
#define RT_ADC_INTERN_CH_VREF (-2)
#define RT_ADC_INTERN_CH_VBAT (-3)
struct rt_adc_device;
/**
* @brief Configure the adc device
*/
struct rt_adc_ops
{
rt_err_t (*enabled)(struct rt_adc_device *device, rt_int8_t channel, rt_bool_t enabled);
rt_err_t (*convert)(struct rt_adc_device *device, rt_int8_t channel, rt_uint32_t *value);
rt_uint8_t (*get_resolution)(struct rt_adc_device *device);
rt_int16_t (*get_vref) (struct rt_adc_device *device);
};
/**
* @brief adc device
*/
struct rt_adc_device
{
struct rt_device parent;
const struct rt_adc_ops *ops;
};
typedef struct rt_adc_device *rt_adc_device_t;
typedef enum
{
RT_ADC_CMD_ENABLE = RT_DEVICE_CTRL_BASE(ADC) + 1,
RT_ADC_CMD_DISABLE = RT_DEVICE_CTRL_BASE(ADC) + 2,
RT_ADC_CMD_GET_RESOLUTION = RT_DEVICE_CTRL_BASE(ADC) + 3, /* get the resolution in bits */
RT_ADC_CMD_GET_VREF = RT_DEVICE_CTRL_BASE(ADC) + 4, /* get reference voltage */
} rt_adc_cmd_t;
/**
* @brief register the adc device
* @param adc adc device
* @param name device name
* @param ops device ops
* @param user_data device private data
* @return rt_err_t error code
* @ingroup group_ADC
*/
rt_err_t rt_hw_adc_register(rt_adc_device_t adc,const char *name, const struct rt_adc_ops *ops, const void *user_data);
/**
* @brief read the adc value
* @param dev adc device
* @param channel adc channel
* @return rt_uint32_t adc value
* @ingroup group_ADC
*/
rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_int8_t channel);
/**
* @brief enable the adc channel
* @param dev adc device
* @param channel adc channel
* @return rt_err_t error code
* @ingroup group_ADC
*/
rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_int8_t channel);
/**
* @brief disable the adc channel
* @param dev adc device
* @param channel adc channel
* @return rt_err_t error code
* @ingroup group_ADC
*/
rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_int8_t channel);
/**
* @brief get the adc resolution
* @param dev adc device
* @param channel adc channel
* @return rt_int16_t adc resolution
* @ingroup group_ADC
*/
rt_int16_t rt_adc_voltage(rt_adc_device_t dev, rt_int8_t channel);
/*! @}*/
#endif /* __ADC_H__ */

View File

@ -0,0 +1,397 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __AHCI_H__
#define __AHCI_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/scsi.h>
#include <drivers/misc.h>
struct rt_ahci_ops;
/* Generic Host Control */
#define RT_AHCI_HBA_CAP 0x00 /* Host capability*/
#define RT_AHCI_CAP_NP RT_GENMASK(4, 0) /* Number of Ports */
#define RT_AHCI_CAP_NCS RT_GENMASK(8, 12) /* Number of Command Slots */
#define RT_AHCI_CAP_PSC RT_BIT(13) /* Partial State Capable */
#define RT_AHCI_CAP_SSC RT_BIT(14) /* Slumber capable */
#define RT_AHCI_CAP_PMD RT_BIT(15) /* PIO Multiple DRQ Block */
#define RT_AHCI_CAP_SPM RT_BIT(17) /* Port Multiplier */
#define RT_AHCI_CAP_AHCI RT_BIT(18) /* AHCI only */
#define RT_AHCI_CAP_SNZO RT_BIT(19) /* Non-Zero DMA Offsets */
#define RT_AHCI_CAP_ISS RT_GENMASK(23, 20) /* Interface Speed Support */
#define RT_AHCI_CAP_CLO RT_BIT(24) /* Command List Override support */
#define RT_AHCI_CAP_SAL RT_BIT(25) /* Activity LED */
#define RT_AHCI_CAP_SALP RT_BIT(26) /* Aggressive Link Power Management */
#define RT_AHCI_CAP_SSS RT_BIT(27) /* Staggered Spin-up */
#define RT_AHCI_CAP_SIS RT_BIT(28) /* Interlock Switch */
#define RT_AHCI_CAP_NCQ RT_BIT(30) /* Native Command Queueing */
#define RT_AHCI_CAP_64 RT_BIT(31) /* PCI DAC (64-bit DMA) support */
#define RT_AHCI_HBA_GHC 0x04 /* Global host control */
#define RT_AHCI_GHC_RESET RT_BIT(0) /* Reset controller; self-clear */
#define RT_AHCI_GHC_IRQ_EN RT_BIT(1) /* Global IRQ enable */
#define RT_AHCI_GHC_AHCI_EN RT_BIT(31) /* AHCI enabled */
#define RT_AHCI_HBA_INTS 0x08 /* Interrupt status */
#define RT_AHCI_HBA_PI 0x0c /* Port implemented */
#define RT_AHCI_HBA_VS 0x10 /* Version */
#define RT_AHCI_HBA_CCC_CTL 0x14 /* Command completion coalescing control */
#define RT_AHCI_HBA_CCC_PTS 0x18 /* Command completion coalescing ports */
#define RT_AHCI_HBA_EM_LOC 0x1c /* Enclosure management location */
#define RT_AHCI_HBA_EM_CTL 0x20 /* Enclosure management control */
#define RT_AHCI_HBA_CAP2 0x24 /* Host capabilities extended */
#define RT_AHCI_HBA_BOHC 0x28 /* BIOS/OS handoff control and status */
#define RT_AHCI_HBA_VENDOR 0xa0 /* Vendor specific registers (0xa0 - 0xff) */
#define RT_AHCI_PORT_CLB 0x00 /* Command list base address, 1K-byte aligned */
#define RT_AHCI_PORT_CLBU 0x04 /* Command list base address upper 32 bits */
#define RT_AHCI_PORT_FB 0x08 /* FIS base address, 256-byte aligned */
#define RT_AHCI_PORT_FBU 0x0C /* FIS base address upper 32 bits */
#define RT_AHCI_PORT_INTS 0x10 /* Interrupt status */
#define RT_AHCI_PORT_INTE 0x14 /* Interrupt enable */
#define RT_AHCI_PORT_INTE_D2H_REG_FIS RT_BIT(0) /* D2H Register FIS rx'd */
#define RT_AHCI_PORT_INTE_PIOS_FIS RT_BIT(1) /* PIO Setup FIS rx'd */
#define RT_AHCI_PORT_INTE_DMAS_FIS RT_BIT(2) /* DMA Setup FIS rx'd */
#define RT_AHCI_PORT_INTE_SDB_FIS RT_BIT(3) /* Set Device Bits FIS rx'd */
#define RT_AHCI_PORT_INTE_UNK_FIS RT_BIT(4) /* Unknown FIS rx'd */
#define RT_AHCI_PORT_INTE_SG_DONE RT_BIT(5) /* Descriptor processed */
#define RT_AHCI_PORT_INTE_CONNECT RT_BIT(6) /* Port connect change status */
#define RT_AHCI_PORT_INTE_DMPS RT_BIT(7) /* Mechanical presence status */
#define RT_AHCI_PORT_INTE_PHYRDY RT_BIT(22) /* PhyRdy changed */
#define RT_AHCI_PORT_INTE_BAD_PMP RT_BIT(23) /* Incorrect port multiplier */
#define RT_AHCI_PORT_INTE_OVERFLOW RT_BIT(24) /* Xfer exhausted available S/G */
#define RT_AHCI_PORT_INTE_IF_NONFATAL RT_BIT(26) /* Interface non-fatal error */
#define RT_AHCI_PORT_INTE_IF_ERR RT_BIT(27) /* Interface fatal error */
#define RT_AHCI_PORT_INTE_HBUS_DATA_ERR RT_BIT(28) /* Host bus data error */
#define RT_AHCI_PORT_INTE_HBUS_ERR RT_BIT(29) /* Host bus fatal error */
#define RT_AHCI_PORT_INTE_TF_ERR RT_BIT(30) /* Task file error */
#define RT_AHCI_PORT_INTE_COLD_PRES RT_BIT(31) /* Cold presence detect */
#define RT_AHCI_PORT_CMD 0x18 /* Command and status */
#define RT_AHCI_PORT_CMD_START RT_BIT(0) /* Enable port DMA engine */
#define RT_AHCI_PORT_CMD_SPIN_UP RT_BIT(1) /* Spin up device */
#define RT_AHCI_PORT_CMD_POWER_ON RT_BIT(2) /* Power up device */
#define RT_AHCI_PORT_CMD_CLO RT_BIT(3) /* Command list override */
#define RT_AHCI_PORT_CMD_FIS_RX RT_BIT(4) /* Enable FIS receive DMA engine */
#define RT_AHCI_PORT_CMD_FIS_ON RT_BIT(14) /* FIS DMA engine running */
#define RT_AHCI_PORT_CMD_LIST_ON RT_BIT(15) /* cmd list DMA engine running */
#define RT_AHCI_PORT_CMD_ATAPI RT_BIT(24) /* Device is ATAPI */
#define RT_AHCI_PORT_CMD_ACTIVE RT_BIT(28) /* Active state */
#define RT_AHCI_PORT_TFD 0x20 /* Task file data */
#define RT_AHCI_PORT_TFDATA_ERR RT_BIT(0) /* Indicates an error during the transfer */
#define RT_AHCI_PORT_TFDATA_DRQ RT_BIT(3) /* Indicates a data transfer is requested */
#define RT_AHCI_PORT_TFDATA_BSY RT_BIT(7) /* Indicates the interface is busy */
#define RT_AHCI_PORT_SIG 0x24 /* Signature */
#define RT_AHCI_PORT_SIG_REG_MASK 0xff
#define RT_AHCI_PORT_SIG_SECTOR_NR_SHIFT 0 /* Sector Count Register */
#define RT_AHCI_PORT_SIG_LBA_LOW_SHIFT 8 /* LBA Low Register */
#define RT_AHCI_PORT_SIG_LBA_MID_SHIFT 16 /* LBA Mid Register */
#define RT_AHCI_PORT_SIG_LBA_HIGH_SHIFT 24 /* LBA High Register */
#define RT_AHCI_PORT_SIG_SATA_CDROM 0xeb140101
#define RT_AHCI_PORT_SIG_SATA_DISK 0x00000101
#define RT_AHCI_PORT_SSTS 0x28 /* SATA status (SCR0:SStatus) */
#define RT_AHCI_PORT_SSTS_DET_MASK 0x3
#define RT_AHCI_PORT_SSTS_DET_COMINIT 0x1
#define RT_AHCI_PORT_SSTS_DET_PHYRDY 0x3
#define RT_AHCI_PORT_SCTL 0x2c /* SATA control (SCR2:SControl) */
#define RT_AHCI_PORT_SERR 0x30 /* SATA error (SCR1:SError) */
#define RT_AHCI_PORT_SERR_ERR_I RT_BIT(0) /* Recovered Data Integrity Error */
#define RT_AHCI_PORT_SERR_ERR_M RT_BIT(1) /* Recovered Communications Error */
#define RT_AHCI_PORT_SERR_ERR_T RT_BIT(8) /* Transient Data Integrity Error */
#define RT_AHCI_PORT_SERR_ERR_C RT_BIT(9) /* Persistent Communication or Data Integrity Error */
#define RT_AHCI_PORT_SERR_ERR_P RT_BIT(10) /* Protocol Error */
#define RT_AHCI_PORT_SERR_ERR_E RT_BIT(11) /* Internal Error */
#define RT_AHCI_PORT_SERR_DIAG_N RT_BIT(16) /* PhyRdy Change */
#define RT_AHCI_PORT_SERR_DIAG_I RT_BIT(17) /* Phy Internal Error */
#define RT_AHCI_PORT_SERR_DIAG_W RT_BIT(18) /* Comm Wake */
#define RT_AHCI_PORT_SERR_DIAG_B RT_BIT(19) /* 10B to 8B Decode Error */
#define RT_AHCI_PORT_SERR_DIAG_D RT_BIT(20) /* Disparity Error */
#define RT_AHCI_PORT_SERR_DIAG_C RT_BIT(21) /* CRC Error */
#define RT_AHCI_PORT_SERR_DIAG_H RT_BIT(22) /* Handshake Error */
#define RT_AHCI_PORT_SERR_DIAG_S RT_BIT(23) /* Link Sequence Error */
#define RT_AHCI_PORT_SERR_DIAG_T RT_BIT(24) /* Transport state transition error */
#define RT_AHCI_PORT_SERR_DIAG_F RT_BIT(25) /* Unknown FIS Type */
#define RT_AHCI_PORT_SERR_DIAG_X RT_BIT(26) /* Exchanged */
#define RT_AHCI_PORT_SACT 0x34 /* SATA active (SCR3:SActive) */
#define RT_AHCI_PORT_CI 0x38 /* Command issue */
#define RT_AHCI_PORT_SNTF 0x3c /* SATA notification (SCR4:SNotification) */
#define RT_AHCI_PORT_FBS 0x40 /* FIS-based switch control */
#define RT_AHCI_PORT_VENDOR 0x70 /* Vendor specific (0x70 - 0x7f) */
#define RT_AHCI_MAX_SG 56
#define RT_AHCI_CMD_SLOT_SIZE 32
#define RT_AHCI_MAX_CMD_SLOT 32
#define RT_AHCI_RX_FIS_SIZE 256
#define RT_AHCI_CMD_TBL_HDR 0x80
#define RT_AHCI_CMD_TBL_CDB 0x40
#define RT_AHCI_CMD_TBL_SIZE RT_AHCI_CMD_TBL_HDR + (RT_AHCI_MAX_SG * 16)
#define RT_AHCI_DMA_SIZE (RT_AHCI_CMD_SLOT_SIZE * RT_AHCI_MAX_CMD_SLOT + RT_AHCI_CMD_TBL_SIZE + RT_AHCI_RX_FIS_SIZE)
#define RT_ACHI_PRDT_BYTES_MAX (4 * 1024 * 1024)
#define RT_AHCI_FIS_TYPE_REG_H2D 0x27 /* Register FIS - host to device */
#define RT_AHCI_FIS_TYPE_REG_D2H 0x34 /* Register FIS - device to host */
#define RT_AHCI_FIS_TYPE_DMA_ACT 0x39 /* DMA activate FIS - device to host */
#define RT_AHCI_FIS_TYPE_DMA_SETUP 0x41 /* DMA setup FIS - bidirectional */
#define RT_AHCI_FIS_TYPE_DATA 0x46 /* Data FIS - bidirectional */
#define RT_AHCI_FIS_TYPE_BIST 0x58 /* BIST activate FIS - bidirectional */
#define RT_AHCI_FIS_TYPE_PIO_SETUP 0x5f /* PIO setup FIS - device to host */
#define RT_AHCI_FIS_TYPE_DEV_BITS 0xa1 /* Set device bits FIS - device to host */
#define RT_AHCI_ATA_ID_WORDS 256
#define RT_AHCI_ATA_ID_CONFIG 0
#define RT_AHCI_ATA_ID_CYLS 1
#define RT_AHCI_ATA_ID_HEADS 3
#define RT_AHCI_ATA_ID_SECTORS 6
#define RT_AHCI_ATA_ID_SERNO 10
#define RT_AHCI_ATA_ID_BUF_SIZE 21
#define RT_AHCI_ATA_ID_FW_REV 23
#define RT_AHCI_ATA_ID_PROD 27
#define RT_AHCI_ATA_ID_MAX_MULTSECT 47
#define RT_AHCI_ATA_ID_DWORD_IO 48
#define RT_AHCI_ATA_ID_TRUSTED 48
#define RT_AHCI_ATA_ID_CAPABILITY 49
#define RT_AHCI_ATA_ID_OLD_PIO_MODES 51
#define RT_AHCI_ATA_ID_OLD_DMA_MODES 52
#define RT_AHCI_ATA_ID_FIELD_VALID 53
#define RT_AHCI_ATA_ID_CUR_CYLS 54
#define RT_AHCI_ATA_ID_CUR_HEADS 55
#define RT_AHCI_ATA_ID_CUR_SECTORS 56
#define RT_AHCI_ATA_ID_MULTSECT 59
#define RT_AHCI_ATA_ID_LBA_CAPACITY 60
#define RT_AHCI_ATA_ID_SWDMA_MODES 62
#define RT_AHCI_ATA_ID_MWDMA_MODES 63
#define RT_AHCI_ATA_ID_PIO_MODES 64
#define RT_AHCI_ATA_ID_EIDE_DMA_MIN 65
#define RT_AHCI_ATA_ID_EIDE_DMA_TIME 66
#define RT_AHCI_ATA_ID_EIDE_PIO 67
#define RT_AHCI_ATA_ID_EIDE_PIO_IORDY 68
#define RT_AHCI_ATA_ID_ADDITIONAL_SUPP 69
#define RT_AHCI_ATA_ID_QUEUE_DEPTH 75
#define RT_AHCI_ATA_ID_SATA_CAPABILITY 76
#define RT_AHCI_ATA_ID_SATA_CAPABILITY_2 77
#define RT_AHCI_ATA_ID_FEATURE_SUPP 78
#define RT_AHCI_ATA_ID_MAJOR_VER 80
#define RT_AHCI_ATA_ID_COMMAND_SET_1 82
#define RT_AHCI_ATA_ID_COMMAND_SET_2 83
#define RT_AHCI_ATA_ID_CFSSE 84
#define RT_AHCI_ATA_ID_CFS_ENABLE_1 85
#define RT_AHCI_ATA_ID_CFS_ENABLE_2 86
#define RT_AHCI_ATA_ID_CSF_DEFAULT 87
#define RT_AHCI_ATA_ID_UDMA_MODES 88
#define RT_AHCI_ATA_ID_HW_CONFIG 93
#define RT_AHCI_ATA_ID_SPG 98
#define RT_AHCI_ATA_ID_LBA_CAPACITY_2 100
#define RT_AHCI_ATA_ID_SECTOR_SIZE 106
#define RT_AHCI_ATA_ID_WWN 108
#define RT_AHCI_ATA_ID_LOGICAL_SECTOR_SIZE 117
#define RT_AHCI_ATA_ID_COMMAND_SET_3 119
#define RT_AHCI_ATA_ID_COMMAND_SET_4 120
#define RT_AHCI_ATA_ID_LAST_LUN 126
#define RT_AHCI_ATA_ID_DLF 128
#define RT_AHCI_ATA_ID_CSFO 129
#define RT_AHCI_ATA_ID_CFA_POWER 160
#define RT_AHCI_ATA_ID_CFA_KEY_MGMT 162
#define RT_AHCI_ATA_ID_CFA_MODES 163
#define RT_AHCI_ATA_ID_DATA_SET_MGMT 169
#define RT_AHCI_ATA_ID_SCT_CMD_XPORT 206
#define RT_AHCI_ATA_ID_ROT_SPEED 217
#define RT_AHCI_ATA_ID_PIO4 (1 << 1)
#define RT_AHCI_ATA_ID_SERNO_LEN 20
#define RT_AHCI_ATA_ID_FW_REV_LEN 8
#define RT_AHCI_ATA_ID_PROD_LEN 40
#define RT_AHCI_ATA_ID_WWN_LEN 8
#define RT_AHCI_ATA_CMD_DSM 0x06
#define RT_AHCI_ATA_CMD_DEV_RESET 0x08 /* ATAPI device reset */
#define RT_AHCI_ATA_CMD_PIO_READ 0x20 /* Read sectors with retry */
#define RT_AHCI_ATA_CMD_PIO_READ_EXT 0x24
#define RT_AHCI_ATA_CMD_READ_EXT 0x25
#define RT_AHCI_ATA_CMD_READ_NATIVE_MAX_EXT 0x27
#define RT_AHCI_ATA_CMD_READ_MULTI_EXT 0x29
#define RT_AHCI_ATA_CMD_READ_LOG_EXT 0x2f
#define RT_AHCI_ATA_CMD_PIO_WRITE 0x30 /* Write sectors with retry */
#define RT_AHCI_ATA_CMD_PIO_WRITE_EXT 0x34
#define RT_AHCI_ATA_CMD_WRITE_EXT 0x35
#define RT_AHCI_ATA_CMD_SET_MAX_EXT 0x37
#define RT_AHCI_ATA_CMD_WRITE_MULTI_EXT 0x39
#define RT_AHCI_ATA_CMD_WRITE_FUA_EXT 0x3d
#define RT_AHCI_ATA_CMD_VERIFY 0x40 /* Read verify sectors with retry */
#define RT_AHCI_ATA_CMD_VERIFY_EXT 0x42
#define RT_AHCI_ATA_CMD_FPDMA_READ 0x60
#define RT_AHCI_ATA_CMD_FPDMA_WRITE 0x61
#define RT_AHCI_ATA_CMD_EDD 0x90 /* Execute device diagnostic */
#define RT_AHCI_ATA_CMD_INIT_DEV_PARAMS 0x91 /* Initialize device parameters */
#define RT_AHCI_ATA_CMD_PACKET 0xa0 /* ATAPI packet */
#define RT_AHCI_ATA_CMD_ID_ATAPI 0xa1 /* ATAPI identify device */
#define RT_AHCI_ATA_CMD_CONF_OVERLAY 0xb1
#define RT_AHCI_ATA_CMD_READ_MULTI 0xc4 /* Read multiple */
#define RT_AHCI_ATA_CMD_WRITE_MULTI 0xc5 /* Write multiple */
#define RT_AHCI_ATA_CMD_SET_MULTI 0xc6 /* Set multiple mode */
#define RT_AHCI_ATA_CMD_READ 0xc8 /* Read DMA with retry */
#define RT_AHCI_ATA_CMD_WRITE 0xca /* Write DMA with retry */
#define RT_AHCI_ATA_CMD_WRITE_MULTI_FUA_EXT 0xce
#define RT_AHCI_ATA_CMD_STANDBYNOW1 0xe0 /* Standby immediate */
#define RT_AHCI_ATA_CMD_IDLEIMMEDIATE 0xe1 /* Idle immediate */
#define RT_AHCI_ATA_CMD_STANDBY 0xe2 /* Place in standby power mode */
#define RT_AHCI_ATA_CMD_IDLE 0xe3 /* Place in idle power mode */
#define RT_AHCI_ATA_CMD_PMP_READ 0xe4 /* Read buffer */
#define RT_AHCI_ATA_CMD_CHK_POWER 0xe5 /* Check power mode */
#define RT_AHCI_ATA_CMD_SLEEP 0xe6 /* Sleep */
#define RT_AHCI_ATA_CMD_FLUSH 0xe7
#define RT_AHCI_ATA_CMD_PMP_WRITE 0xe8 /* Write buffer */
#define RT_AHCI_ATA_CMD_FLUSH_EXT 0xea
#define RT_AHCI_ATA_CMD_ID_ATA 0xec /* Identify device */
#define RT_AHCI_ATA_CMD_SET_FEATURES 0xef /* Set features */
#define RT_AHCI_ATA_CMD_SEC_FREEZE_LOCK 0xf5 /* Security freeze */
#define RT_AHCI_ATA_CMD_READ_NATIVE_MAX 0xf8
#define RT_AHCI_ATA_CMD_SET_MAX 0xf9
#define RT_AHCI_ATA_DSM_TRIM 0x01
#define RT_AHCI_ATA_PROT_FLAG_PIO RT_BIT(0)
#define RT_AHCI_ATA_PROT_FLAG_DMA RT_BIT(1)
#define RT_AHCI_ATA_PROT_FLAG_NCQ RT_BIT(2)
#define RT_AHCI_ATA_PROT_FLAG_ATAPI RT_BIT(3)
#define rt_ahci_ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
#define rt_ahci_ata_id_has_lba(id) ((id)[49] & (1 << 9))
#define rt_ahci_ata_id_has_dma(id) ((id)[49] & (1 << 8))
#define rt_ahci_ata_id_has_ncq(id) ((id)[76] & (1 << 8))
#define rt_ahci_ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
#define rt_ahci_ata_id_removeable(id) ((id)[0] & (1 << 7))
#define rt_ahci_ata_id_iordy_disable(id) ((id)[49] & (1 << 10))
#define rt_ahci_ata_id_has_iordy(id) ((id)[49] & (1 << 11))
#define rt_ahci_ata_id_u32(id, n) (((rt_uint32_t)(id)[(n) + 1] << 16) | ((rt_uint32_t) (id)[(n)]))
#define rt_ahci_ata_id_u64(id, n) (((rt_uint64_t)(id)[(n) + 3] << 48) | ((rt_uint64_t)(id)[(n) + 2] << 32) | \
((rt_uint64_t)(id)[(n) + 1] << 16) | ((rt_uint64_t)(id)[(n) + 0]) )
rt_inline rt_bool_t rt_ahci_ata_id_has_lba48(const rt_uint16_t *id)
{
if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000 ||
!rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2))
{
return 0;
}
return !!(id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 10));
}
rt_inline rt_uint64_t rt_ahci_ata_id_n_sectors(rt_uint16_t *id)
{
if (rt_ahci_ata_id_has_lba(id))
{
if (rt_ahci_ata_id_has_lba48(id))
{
return rt_ahci_ata_id_u64(id, RT_AHCI_ATA_ID_LBA_CAPACITY_2);
}
return rt_ahci_ata_id_u32(id, RT_AHCI_ATA_ID_LBA_CAPACITY);
}
return 0;
}
rt_inline rt_bool_t rt_ahci_ata_id_wcache_enabled(const rt_uint16_t *id)
{
if ((id[RT_AHCI_ATA_ID_CSF_DEFAULT] & 0xc000) != 0x4000)
{
return RT_FALSE;
}
return id[RT_AHCI_ATA_ID_CFS_ENABLE_1] & (1 << 5);
}
rt_inline rt_bool_t rt_ahci_ata_id_has_flush(const rt_uint16_t *id)
{
if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000)
{
return RT_FALSE;
}
return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 12);
}
rt_inline rt_bool_t rt_ahci_ata_id_has_flush_ext(const rt_uint16_t *id)
{
if ((id[RT_AHCI_ATA_ID_COMMAND_SET_2] & 0xc000) != 0x4000)
{
return RT_FALSE;
}
return id[RT_AHCI_ATA_ID_COMMAND_SET_2] & (1 << 13);
}
struct rt_ahci_cmd_hdr
{
rt_uint32_t opts;
rt_uint32_t status;
rt_uint32_t tbl_addr_lo;
rt_uint32_t tbl_addr_hi;
rt_uint32_t reserved[4];
};
struct rt_ahci_sg
{
rt_uint32_t addr_lo;
rt_uint32_t addr_hi;
rt_uint32_t reserved;
rt_uint32_t flags_size;
};
struct rt_ahci_port
{
void *regs;
void *dma;
rt_ubase_t dma_handle;
struct rt_ahci_cmd_hdr *cmd_slot;
struct rt_ahci_sg *cmd_tbl_sg;
void *cmd_tbl;
rt_ubase_t cmd_tbl_dma;
void *rx_fis;
rt_uint32_t int_enabled;
rt_size_t block_size;
rt_uint16_t *ataid;
rt_bool_t link;
struct rt_completion done;
};
struct rt_ahci_host
{
struct rt_scsi_host parent;
int irq;
void *regs;
rt_size_t ports_nr;
rt_uint32_t ports_map;
struct rt_ahci_port ports[32];
rt_uint32_t cap;
rt_uint32_t max_blocks;
const struct rt_ahci_ops *ops;
};
struct rt_ahci_ops
{
rt_err_t (*host_init)(struct rt_ahci_host *host);
rt_err_t (*port_init)(struct rt_ahci_host *host, struct rt_ahci_port *port);
rt_err_t (*port_link_up)(struct rt_ahci_host *host, struct rt_ahci_port *port);
rt_err_t (*port_dma_init)(struct rt_ahci_host *host, struct rt_ahci_port *port);
rt_err_t (*port_isr)(struct rt_ahci_host *host, struct rt_ahci_port *port, rt_uint32_t isr);
};
rt_err_t rt_ahci_host_register(struct rt_ahci_host *host);
rt_err_t rt_ahci_host_unregister(struct rt_ahci_host *host);
#endif /* __AHCI_H__ */

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI first version
* 2025-01-24 wumingzi add doxygen comment
*/
#ifndef __BLK_H__
#define __BLK_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/classes/block.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_blk blk
* @brief blk driver api
* @ingroup group_Drivers
* @addtogroup group_blk
* @{
*/
struct rt_dm_ida;
struct rt_blk_device;
struct rt_blk_disk_ops;
/**
* @brief Physical blk device
*/
struct rt_blk_disk
{
struct rt_device parent;
const struct rt_blk_disk_ops *ops;
#ifdef RT_USING_DM
struct rt_dm_ida *ida;
#endif
rt_uint32_t read_only:1;
rt_uint32_t parallel_io:1;
rt_uint32_t removable:1;
#define RT_BLK_DISK_MAGIC 0xbdaabdaa
rt_uint32_t __magic;
rt_uint32_t partitions;
#define RT_BLK_PARTITION_NONE (-1)
#define RT_BLK_PARTITION_MAX (RT_UINT32_MAX >> 1)
rt_int32_t max_partitions;
rt_list_t part_nodes;
struct rt_spinlock lock;
struct rt_semaphore usr_lock;
};
/**
* @brief Configure the blk device.
*/
struct rt_blk_disk_ops
{
rt_ssize_t (*read)(struct rt_blk_disk *disk, rt_off_t sector, void *buffer,
rt_size_t sector_count);
rt_ssize_t (*write)(struct rt_blk_disk *disk, rt_off_t sector, const void *buffer,
rt_size_t sector_count);
rt_err_t (*getgeome)(struct rt_blk_disk *disk, struct rt_device_blk_geometry *geometry);
rt_err_t (*sync)(struct rt_blk_disk *disk);
rt_err_t (*erase)(struct rt_blk_disk *disk);
rt_err_t (*autorefresh)(struct rt_blk_disk *disk, rt_bool_t is_auto);
rt_err_t (*control)(struct rt_blk_disk *disk, struct rt_blk_device *blk, int cmd, void *args);
};
#ifndef __DFS_H__
#include <dfs_fs.h>
/**
* @brief Logical blk device, if you don't used DFS it will be defined by default.
*/
struct rt_blk_device
{
struct rt_device parent;
int partno;
struct dfs_partition partition;
rt_list_t list;
struct rt_blk_disk *disk;
rt_size_t sector_start;
rt_size_t sector_count;
};
#else
struct rt_blk_device;
#endif /* __DFS_H__ */
/**
* @brief Register the blk disk device
* @param disk Point to blk disk
* @return rt_err_t error code
*/
rt_err_t rt_hw_blk_disk_register(struct rt_blk_disk *disk);
/**
* @brief Unregister the blk disk device
* @param disk Point to blk disk
* @return rt_err_t error code
*/
rt_err_t rt_hw_blk_disk_unregister(struct rt_blk_disk *disk);
/**
* @brief Probe and register the blk disk partition
* @param disk Point to blk disk
* @return rt_err_t error code
*/
rt_err_t rt_blk_disk_probe_partition(struct rt_blk_disk *disk);
/**
* @brief Get the blk disk capacity
* @param disk Point to blk disk
* @return rt_ssize_t sector count or error code
*/
rt_ssize_t rt_blk_disk_get_capacity(struct rt_blk_disk *disk);
/**
* @brief Get the sector size
* @param disk Point to blk disk
* @return rt_ssize_t bytes per sector or error code
*/
rt_ssize_t rt_blk_disk_get_logical_block_size(struct rt_blk_disk *disk);
/*! @}*/
#endif /* __BLK_H__ */

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __BYTEORDER__
#define __BYTEORDER__
#ifdef __CHECKER__
#define __bitwise __attribute__((bitwise))
#else
#define __bitwise
#endif
typedef rt_uint16_t __bitwise rt_le16_t;
typedef rt_uint32_t __bitwise rt_le32_t;
typedef rt_uint64_t __bitwise rt_le64_t;
typedef rt_uint16_t __bitwise rt_be16_t;
typedef rt_uint32_t __bitwise rt_be32_t;
typedef rt_uint64_t __bitwise rt_be64_t;
/* gcc defines __BIG_ENDIAN__ on big endian targets */
#if defined(__BIG_ENDIAN__) || defined(ARCH_CPU_BIG_ENDIAN)
#define rt_cpu_to_be16(x) (x)
#define rt_cpu_to_be32(x) (x)
#define rt_cpu_to_be64(x) (x)
#define rt_be16_to_cpu(x) (x)
#define rt_be32_to_cpu(x) (x)
#define rt_be64_to_cpu(x) (x)
#define rt_le16_to_cpu(x) __builtin_bswap16(x)
#define rt_le32_to_cpu(x) __builtin_bswap32(x)
#define rt_le64_to_cpu(x) __builtin_bswap64(x)
#define rt_cpu_to_le16(x) __builtin_bswap16(x)
#define rt_cpu_to_le32(x) __builtin_bswap32(x)
#define rt_cpu_to_le64(x) __builtin_bswap64(x)
#else
#define rt_cpu_to_be16(x) __builtin_bswap16(x)
#define rt_cpu_to_be32(x) __builtin_bswap32(x)
#define rt_cpu_to_be64(x) __builtin_bswap64(x)
#define rt_be16_to_cpu(x) __builtin_bswap16(x)
#define rt_be32_to_cpu(x) __builtin_bswap32(x)
#define rt_be64_to_cpu(x) __builtin_bswap64(x)
#define rt_le16_to_cpu(x) (x)
#define rt_le32_to_cpu(x) (x)
#define rt_le64_to_cpu(x) (x)
#define rt_cpu_to_le16(x) (x)
#define rt_cpu_to_le32(x) (x)
#define rt_cpu_to_le64(x) (x)
#endif /* __BIG_ENDIAN__ || ARCH_CPU_BIG_ENDIAN */
#undef __bitwise
#endif /* __BYTEORDER__ */

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-10-11 zmshahaha move from <rtdef.h>
*/
#ifndef __BLOCK_H__
#define __BLOCK_H__
#include <rtdef.h>
/* block device commands*/
#define RT_DEVICE_CTRL_BLK_GETGEOME (RT_DEVICE_CTRL_BASE(Block) + 1) /**< get geometry information */
#define RT_DEVICE_CTRL_BLK_SYNC (RT_DEVICE_CTRL_BASE(Block) + 2) /**< flush data to block device */
#define RT_DEVICE_CTRL_BLK_ERASE (RT_DEVICE_CTRL_BASE(Block) + 3) /**< erase block on block device */
#define RT_DEVICE_CTRL_BLK_AUTOREFRESH (RT_DEVICE_CTRL_BASE(Block) + 4) /**< block device : enter/exit auto refresh mode */
#define RT_DEVICE_CTRL_BLK_PARTITION (RT_DEVICE_CTRL_BASE(Block) + 5) /**< get block device partition */
/**
* block device geometry structure
*/
struct rt_device_blk_geometry
{
rt_uint64_t sector_count; /**< count of sectors */
rt_uint32_t bytes_per_sector; /**< number of bytes per sector */
rt_uint32_t block_size; /**< number of bytes to erase one block */
};
/**
* sector arrange struct on block device
*/
struct rt_device_blk_sectors
{
rt_uint64_t sector_begin; /**< begin sector */
rt_uint64_t sector_end; /**< end sector */
};
#endif /* __BLOCK_H__ */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-10-11 zmshahaha move from <rtdef.h>
*/
#ifndef __CHAR_H__
#define __CHAR_H__
#include <rtdef.h>
/* char device commands*/
#define RT_DEVICE_CTRL_CHAR_STREAM (RT_DEVICE_CTRL_BASE(Char) + 1) /**< stream mode on char device */
#endif /* __CHAR_H__ */

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-10-11 zmshahaha move from <rtdef.h>
*/
#ifndef __GRAPHIC_H__
#define __GRAPHIC_H__
#include <rtdef.h>
/**
* cursor control command
*/
#define RT_DEVICE_CTRL_CURSOR_SET_POSITION 0x10
#define RT_DEVICE_CTRL_CURSOR_SET_TYPE 0x11
/**
* graphic device control command
*/
#define RTGRAPHIC_CTRL_RECT_UPDATE (RT_DEVICE_CTRL_BASE(Graphic) + 0)
#define RTGRAPHIC_CTRL_POWERON (RT_DEVICE_CTRL_BASE(Graphic) + 1)
#define RTGRAPHIC_CTRL_POWEROFF (RT_DEVICE_CTRL_BASE(Graphic) + 2)
#define RTGRAPHIC_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Graphic) + 3)
#define RTGRAPHIC_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Graphic) + 4)
#define RTGRAPHIC_CTRL_GET_EXT (RT_DEVICE_CTRL_BASE(Graphic) + 5)
#define RTGRAPHIC_CTRL_SET_BRIGHTNESS (RT_DEVICE_CTRL_BASE(Graphic) + 6)
#define RTGRAPHIC_CTRL_GET_BRIGHTNESS (RT_DEVICE_CTRL_BASE(Graphic) + 7)
#define RTGRAPHIC_CTRL_GET_MODE (RT_DEVICE_CTRL_BASE(Graphic) + 8)
#define RTGRAPHIC_CTRL_GET_STATUS (RT_DEVICE_CTRL_BASE(Graphic) + 9)
#define RTGRAPHIC_CTRL_PAN_DISPLAY (RT_DEVICE_CTRL_BASE(Graphic) + 10)
#define RTGRAPHIC_CTRL_WAIT_VSYNC (RT_DEVICE_CTRL_BASE(Graphic) + 11)
/* graphic device */
enum
{
RTGRAPHIC_PIXEL_FORMAT_MONO = 0,
RTGRAPHIC_PIXEL_FORMAT_GRAY4,
RTGRAPHIC_PIXEL_FORMAT_GRAY16,
RTGRAPHIC_PIXEL_FORMAT_RGB332,
RTGRAPHIC_PIXEL_FORMAT_RGB444,
RTGRAPHIC_PIXEL_FORMAT_RGB565,
RTGRAPHIC_PIXEL_FORMAT_RGB565P,
RTGRAPHIC_PIXEL_FORMAT_BGR565 = RTGRAPHIC_PIXEL_FORMAT_RGB565P,
RTGRAPHIC_PIXEL_FORMAT_RGB666,
RTGRAPHIC_PIXEL_FORMAT_RGB888,
RTGRAPHIC_PIXEL_FORMAT_BGR888,
RTGRAPHIC_PIXEL_FORMAT_ARGB888,
RTGRAPHIC_PIXEL_FORMAT_ABGR888,
RTGRAPHIC_PIXEL_FORMAT_RESERVED,
};
/**
* build a pixel position according to (x, y) coordinates.
*/
#define RTGRAPHIC_PIXEL_POSITION(x, y) ((x << 16) | y)
/**
* graphic device information structure
*/
struct rt_device_graphic_info
{
rt_uint8_t pixel_format; /**< graphic format */
rt_uint8_t bits_per_pixel; /**< bits per pixel */
rt_uint16_t pitch; /**< bytes per line */
rt_uint16_t width; /**< width of graphic device */
rt_uint16_t height; /**< height of graphic device */
rt_uint8_t *framebuffer; /**< frame buffer */
rt_uint32_t smem_len; /**< allocated frame buffer size */
};
/**
* rectangle information structure
*/
struct rt_device_rect_info
{
rt_uint16_t x; /**< x coordinate */
rt_uint16_t y; /**< y coordinate */
rt_uint16_t width; /**< width */
rt_uint16_t height; /**< height */
};
/**
* graphic operations
*/
struct rt_device_graphic_ops
{
void (*set_pixel) (const char *pixel, int x, int y);
void (*get_pixel) (char *pixel, int x, int y);
void (*draw_hline)(const char *pixel, int x1, int x2, int y);
void (*draw_vline)(const char *pixel, int x, int y1, int y2);
void (*blit_line) (const char *pixel, int x, int y, rt_size_t size);
};
#define rt_graphix_ops(device) ((struct rt_device_graphic_ops *)(device->user_data))
#endif /* __GRAPHIC_H__ */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-10-11 zmshahaha move from <rtdef.h>
*/
#ifndef __MTD_H__
#define __MTD_H__
#include <rtdef.h>
/* mtd interface device*/
#define RT_DEVICE_CTRL_MTD_FORMAT (RT_DEVICE_CTRL_BASE(MTD) + 1) /**< format a MTD device */
#endif /* __MTD_H__ */

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-10-11 zmshahaha move from <rtdef.h>
*/
#ifndef __NET_H__
#define __NET_H__
#include <rtdef.h>
/* net interface device*/
#define RT_DEVICE_CTRL_NETIF_GETMAC (RT_DEVICE_CTRL_BASE(NetIf) + 1) /**< get mac address */
#endif /* __NET_H__ */

View File

@ -0,0 +1,221 @@
/*
* Copyright (c) 2006-2025 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
* 2025-01-24 wumingzi add doxygen comment
*/
#ifndef __CLK_H__
#define __CLK_H__
#include <rthw.h>
#include <ref.h>
#include <drivers/ofw.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_clk clk
* @brief clk driver api
* @ingroup group_Drivers
* @addtogroup group_clk
* @{
*/
#define RT_CLK_NODE_OBJ_NAME "CLKNP"
struct rt_clk_ops;
struct rt_reset_control_node;
/**
* @brief Clk node, it is a pat of clk source or controller
* @note Defined as the array like this if the CLK have multi out clocks:
* @code{.c}
* struct XYZ_single_clk
* {
* struct rt_clk_node parent;
* ...
* };
*
* struct XYZ_multi_clk
* {
* struct rt_clk_node parent[N];
* ...
* };
* @endcode
* We assume the 'N' is the max value of element in 'clock-indices' if OFW.
*/
struct rt_clk_node
{
struct rt_object rt_parent;
rt_list_t list;
rt_list_t children_nodes;
const char *name;
const struct rt_clk_ops *ops;
struct rt_clk_node *parent;
struct rt_ref ref;
rt_ubase_t rate;
rt_ubase_t min_rate;
rt_ubase_t max_rate;
rt_size_t notifier_count;
void *priv;
struct rt_clk *clk;
rt_size_t multi_clk;
};
/**
* @brief Constant rate clk
*/
struct rt_clk_fixed_rate
{
struct rt_clk_node clk;
rt_ubase_t fixed_rate;
rt_ubase_t fixed_accuracy;
};
/**
* @brief Clk object, it can be clk source or controller
*/
struct rt_clk
{
struct rt_clk_node *clk_np;
const char *dev_id;
const char *con_id;
rt_ubase_t rate;
int prepare_count;
int enable_count;
void *fw_node;
void *priv;
};
/**
* @brief Clk array
*/
struct rt_clk_array
{
rt_size_t count;
struct rt_clk *clks[];
};
struct rt_clk_ops
{
rt_err_t (*init)(struct rt_clk *, void *fw_data);
rt_err_t (*finit)(struct rt_clk *);
/* API */
rt_err_t (*prepare)(struct rt_clk *);
void (*unprepare)(struct rt_clk *);
rt_bool_t (*is_prepared)(struct rt_clk *);
rt_err_t (*enable)(struct rt_clk *);
void (*disable)(struct rt_clk *);
rt_bool_t (*is_enabled)(struct rt_clk *);
rt_err_t (*set_rate)(struct rt_clk *, rt_ubase_t rate, rt_ubase_t parent_rate);
rt_err_t (*set_parent)(struct rt_clk *, struct rt_clk *parent);
rt_err_t (*set_phase)(struct rt_clk *, int degrees);
rt_base_t (*get_phase)(struct rt_clk *);
rt_base_t (*round_rate)(struct rt_clk *, rt_ubase_t drate, rt_ubase_t *prate);
};
struct rt_clk_notifier;
#define RT_CLK_MSG_PRE_RATE_CHANGE RT_BIT(0)
#define RT_CLK_MSG_POST_RATE_CHANGE RT_BIT(1)
#define RT_CLK_MSG_ABORT_RATE_CHANGE RT_BIT(2)
typedef rt_err_t (*rt_clk_notifier_callback)(struct rt_clk_notifier *notifier,
rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate);
/**
* @brief Clock notifier, it containers of clock list and callback function
*/
struct rt_clk_notifier
{
rt_list_t list;
struct rt_clk *clk;
rt_clk_notifier_callback callback;
void *priv;
};
rt_err_t rt_clk_register(struct rt_clk_node *clk_np, struct rt_clk_node *parent_np);
rt_err_t rt_clk_unregister(struct rt_clk_node *clk_np);
rt_err_t rt_clk_notifier_register(struct rt_clk *clk, struct rt_clk_notifier *notifier);
rt_err_t rt_clk_notifier_unregister(struct rt_clk *clk, struct rt_clk_notifier *notifier);
rt_err_t rt_clk_set_parent(struct rt_clk *clk, struct rt_clk *clk_parent);
rt_err_t rt_clk_prepare(struct rt_clk *clk);
rt_err_t rt_clk_unprepare(struct rt_clk *clk);
rt_err_t rt_clk_enable(struct rt_clk *clk);
void rt_clk_disable(struct rt_clk *clk);
rt_err_t rt_clk_prepare_enable(struct rt_clk *clk);
void rt_clk_disable_unprepare(struct rt_clk *clk);
rt_err_t rt_clk_array_prepare(struct rt_clk_array *clk_arr);
rt_err_t rt_clk_array_unprepare(struct rt_clk_array *clk_arr);
rt_err_t rt_clk_array_enable(struct rt_clk_array *clk_arr);
void rt_clk_array_disable(struct rt_clk_array *clk_arr);
rt_err_t rt_clk_array_prepare_enable(struct rt_clk_array *clk_arr);
void rt_clk_array_disable_unprepare(struct rt_clk_array *clk_arr);
rt_err_t rt_clk_set_rate_range(struct rt_clk *clk, rt_ubase_t min, rt_ubase_t max);
rt_err_t rt_clk_set_min_rate(struct rt_clk *clk, rt_ubase_t rate);
rt_err_t rt_clk_set_max_rate(struct rt_clk *clk, rt_ubase_t rate);
rt_err_t rt_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate);
rt_ubase_t rt_clk_get_rate(struct rt_clk *clk);
rt_err_t rt_clk_set_phase(struct rt_clk *clk, int degrees);
rt_base_t rt_clk_get_phase(struct rt_clk *clk);
rt_base_t rt_clk_round_rate(struct rt_clk *clk, rt_ubase_t rate);
struct rt_clk *rt_clk_get_parent(struct rt_clk *clk);
struct rt_clk_array *rt_clk_get_array(struct rt_device *dev);
struct rt_clk *rt_clk_get_by_index(struct rt_device *dev, int index);
struct rt_clk *rt_clk_get_by_name(struct rt_device *dev, const char *name);
void rt_clk_array_put(struct rt_clk_array *clk_arr);
void rt_clk_put(struct rt_clk *clk);
#ifdef RT_USING_OFW
struct rt_clk_array *rt_ofw_get_clk_array(struct rt_ofw_node *np);
struct rt_clk *rt_ofw_get_clk(struct rt_ofw_node *np, int index);
struct rt_clk *rt_ofw_get_clk_by_name(struct rt_ofw_node *np, const char *name);
rt_ssize_t rt_ofw_count_of_clk(struct rt_ofw_node *clk_ofw_np);
#else
rt_inline struct rt_clk *rt_ofw_get_clk(struct rt_ofw_node *np, int index)
{
return RT_NULL;
}
rt_inline struct rt_clk *rt_ofw_get_clk_by_name(struct rt_ofw_node *np, const char *name)
{
return RT_NULL;
}
rt_inline rt_ssize_t rt_ofw_count_of_clk(struct rt_ofw_node *clk_ofw_np)
{
return 0;
}
#endif /* RT_USING_OFW */
/*! @}*/
#endif /* __CLK_H__ */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-12 ErikChan the first version
*/
#ifndef __CORE_BUS_H__
#define __CORE_BUS_H__
#include <rthw.h>
#include <rtdef.h>
#include <drivers/core/driver.h>
typedef struct rt_bus *rt_bus_t;
struct rt_bus
{
struct rt_object parent; /**< inherit from rt_object */
const char *name;
rt_list_t list;
rt_list_t dev_list;
rt_list_t drv_list;
struct rt_spinlock dev_lock;
struct rt_spinlock drv_lock;
rt_bool_t (*match)(rt_driver_t drv, rt_device_t dev);
rt_err_t (*probe)(rt_device_t dev);
rt_err_t (*remove)(rt_device_t dev);
rt_err_t (*shutdown)(rt_device_t dev);
};
rt_err_t rt_bus_for_each_dev(rt_bus_t bus, void *data, int (*fn)(rt_device_t dev, void *));
rt_err_t rt_bus_for_each_drv(rt_bus_t bus, void *data, int (*fn)(rt_driver_t drv, void *));
rt_err_t rt_bus_add_driver(rt_bus_t bus, rt_driver_t drv);
rt_err_t rt_bus_add_device(rt_bus_t bus, rt_device_t dev);
rt_err_t rt_bus_remove_driver(rt_driver_t drv);
rt_err_t rt_bus_remove_device(rt_device_t dev);
rt_err_t rt_bus_shutdown(void);
rt_bus_t rt_bus_find_by_name(const char *name);
rt_err_t rt_bus_reload_driver_device(rt_bus_t new_bus, rt_device_t dev);
rt_err_t rt_bus_register(rt_bus_t bus);
#endif /* __BUS_H__ */

View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-20 ErikChan the first version
*/
#ifndef __CORE_DM_H__
#define __CORE_DM_H__
#include <rthw.h>
#include <rtdef.h>
#include <bitmap.h>
#include <ioremap.h>
#include <drivers/misc.h>
#include <drivers/byteorder.h>
#include <drivers/core/master_id.h>
#ifndef RT_CPUS_NR
#define RT_CPUS_NR 1
#endif
#ifndef RT_USING_SMP
extern int rt_hw_cpu_id(void);
#endif
void rt_dm_secondary_cpu_init(void);
/* ID Allocation */
struct rt_dm_ida
{
rt_uint8_t master_id;
#define RT_DM_IDA_NUM 256
RT_BITMAP_DECLARE(map, RT_DM_IDA_NUM);
struct rt_spinlock lock;
};
#define RT_DM_IDA_INIT(id) { .master_id = MASTER_ID_##id }
#define rt_dm_ida_init(ida, id) \
do { \
(ida)->master_id = MASTER_ID_##id; \
rt_spin_lock_init(&(ida)->lock); \
} while (0)
int rt_dm_ida_alloc(struct rt_dm_ida *ida);
rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id);
void rt_dm_ida_free(struct rt_dm_ida *ida, int id);
rt_device_t rt_dm_device_find(int master_id, int device_id);
int rt_dm_dev_set_name_auto(rt_device_t dev, const char *prefix);
int rt_dm_dev_get_name_id(rt_device_t dev);
int rt_dm_dev_set_name(rt_device_t dev, const char *format, ...);
const char *rt_dm_dev_get_name(rt_device_t dev);
int rt_dm_dev_get_address_count(rt_device_t dev);
rt_err_t rt_dm_dev_get_address(rt_device_t dev, int index,
rt_uint64_t *out_address, rt_uint64_t *out_size);
rt_err_t rt_dm_dev_get_address_by_name(rt_device_t dev, const char *name,
rt_uint64_t *out_address, rt_uint64_t *out_size);
int rt_dm_dev_get_address_array(rt_device_t dev, int nr, rt_uint64_t *out_regs);
void *rt_dm_dev_iomap(rt_device_t dev, int index);
void *rt_dm_dev_iomap_by_name(rt_device_t dev, const char *name);
int rt_dm_dev_get_irq_count(rt_device_t dev);
int rt_dm_dev_get_irq(rt_device_t dev, int index);
int rt_dm_dev_get_irq_by_name(rt_device_t dev, const char *name);
void rt_dm_dev_bind_fwdata(rt_device_t dev, void *fw_np, void *data);
void rt_dm_dev_unbind_fwdata(rt_device_t dev, void *fw_np);
int rt_dm_dev_prop_read_u8_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint8_t *out_values);
int rt_dm_dev_prop_read_u16_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint16_t *out_values);
int rt_dm_dev_prop_read_u32_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint32_t *out_values);
int rt_dm_dev_prop_read_u64_array_index(rt_device_t dev, const char *propname,
int index, int nr, rt_uint64_t *out_values);
int rt_dm_dev_prop_read_string_array_index(rt_device_t dev, const char *propname,
int index, int nr, const char **out_strings);
int rt_dm_dev_prop_count_of_size(rt_device_t dev, const char *propname, int size);
int rt_dm_dev_prop_index_of_string(rt_device_t dev, const char *propname, const char *string);
rt_bool_t rt_dm_dev_prop_read_bool(rt_device_t dev, const char *propname);
rt_inline rt_err_t rt_dm_dev_prop_read_u8_index(rt_device_t dev, const char *propname,
int index, rt_uint8_t *out_value)
{
int nr = rt_dm_dev_prop_read_u8_array_index(dev, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_dm_dev_prop_read_u16_index(rt_device_t dev, const char *propname,
int index, rt_uint16_t *out_value)
{
int nr = rt_dm_dev_prop_read_u16_array_index(dev, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_dm_dev_prop_read_u32_index(rt_device_t dev, const char *propname,
int index, rt_uint32_t *out_value)
{
int nr = rt_dm_dev_prop_read_u32_array_index(dev, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_dm_dev_prop_read_u64_index(rt_device_t dev, const char *propname,
int index, rt_uint64_t *out_value)
{
int nr = rt_dm_dev_prop_read_u64_array_index(dev, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_dm_dev_prop_read_string_index(rt_device_t dev, const char *propname,
int index, const char **out_string)
{
int nr = rt_dm_dev_prop_read_string_array_index(dev, propname, index, 1, out_string);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_dm_dev_prop_read_u8(rt_device_t dev, const char *propname,
rt_uint8_t *out_value)
{
return rt_dm_dev_prop_read_u8_index(dev, propname, 0, out_value);
}
rt_inline rt_err_t rt_dm_dev_prop_read_u16(rt_device_t dev, const char *propname,
rt_uint16_t *out_value)
{
return rt_dm_dev_prop_read_u16_index(dev, propname, 0, out_value);
}
rt_inline rt_err_t rt_dm_dev_prop_read_u32(rt_device_t dev, const char *propname,
rt_uint32_t *out_value)
{
return rt_dm_dev_prop_read_u32_index(dev, propname, 0, out_value);
}
rt_inline rt_err_t rt_dm_dev_prop_read_s32(rt_device_t dev, const char *propname,
rt_int32_t *out_value)
{
return rt_dm_dev_prop_read_u32_index(dev, propname, 0, (rt_uint32_t *)out_value);
}
rt_inline rt_err_t rt_dm_dev_prop_read_u64(rt_device_t dev, const char *propname,
rt_uint64_t *out_value)
{
return rt_dm_dev_prop_read_u64_index(dev, propname, 0, out_value);
}
rt_inline rt_err_t rt_dm_dev_prop_read_string(rt_device_t dev, const char *propname,
const char **out_string)
{
return rt_dm_dev_prop_read_string_index(dev, propname, 0, out_string);
}
rt_inline int rt_dm_dev_prop_count_of_u8(rt_device_t dev, const char *propname)
{
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint8_t));
}
rt_inline int rt_dm_dev_prop_count_of_u16(rt_device_t dev, const char *propname)
{
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint16_t));
}
rt_inline int rt_dm_dev_prop_count_of_u32(rt_device_t dev, const char *propname)
{
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint32_t));
}
rt_inline int rt_dm_dev_prop_count_of_u64(rt_device_t dev, const char *propname)
{
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint64_t));
}
#endif /* __RT_DM_H__ */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-12 ErikChan the first version
*/
#ifndef __CORE_DRIVER_H__
#define __CORE_DRIVER_H__
#include <rtdef.h>
struct rt_driver
{
struct rt_object parent;
struct rt_bus *bus;
rt_list_t node;
rt_uint32_t ref_count;
#ifdef RT_USING_DEVICE_OPS
const struct rt_device_ops *dev_ops;
#else
/* common device interface */
rt_err_t (*init) (rt_device_t dev);
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
rt_err_t (*close) (rt_device_t dev);
rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
#endif
const struct filesystem_ops *fops;
int (*probe)(struct rt_device *dev);
int (*remove)(struct rt_device *dev);
int (*shutdown)(struct rt_device *dev);
};
rt_err_t rt_driver_register(rt_driver_t drv);
rt_err_t rt_driver_unregister(rt_driver_t drv);
#define RT_DRIVER_EXPORT(driver, bus_name, mode) \
static int ___##driver##_register(void) \
{ \
rt_##bus_name##_driver_register(&driver); \
return 0; \
} \
INIT_DEVICE_EXPORT(___##driver##_register); \
#endif /* __DRIVER_H__ */

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-20 GuEe-GUI the first version
*/
#ifndef __RT_DM_MASTER_ID_H__
#define __RT_DM_MASTER_ID_H__
#define MASTER_ID_CUSTOM 0
/* Block */
#define MASTER_ID_NVME 1
#define MASTER_ID_SCSI_SD 2
#define MASTER_ID_SCSI_CDROM 3
#define MASTER_ID_SDIO 4
#define MASTER_ID_VIRTUAL_BLOCK 5
/* Char */
#define MASTER_ID_RPMSG_EPT 11
#define MASTER_ID_RPMSG_CHAR 12
#define MASTER_ID_SERIAL 13
/* Clock Timer */
#define MASTER_ID_HWTIMER 21
#define MASTER_ID_PTP 22
#define MASTER_ID_RTC 23
/* Graphic Display */
#define MASTER_ID_GRAPHIC_BACKLIGHT 31
#define MASTER_ID_GRAPHIC_FRAMEBUFFER 32
#define MASTER_ID_LED 33
/* Hardware Monitor */
#define MASTER_ID_DVFS 41
#define MASTER_ID_SENSOR 42
#define MASTER_ID_THERMAL 43
#define MASTER_ID_WATCHDOG 44
/* I2C */
#define MASTER_ID_I2C_BUS 51
#define MASTER_ID_I2C_DEV 52
/* IO Contorl */
#define MASTER_ID_ADC 61
#define MASTER_ID_DAC 62
#define MASTER_ID_PIN 63
#define MASTER_ID_PWM 64
/* Memory */
#define MASTER_ID_MEM 71
#define MASTER_ID_MTD 72
/* MISC */
#define MASTER_ID_MISC 81
/* Multimedia */
#define MASTER_ID_AUDIO 91
/* Net */
#define MASTER_ID_CAN 101
#define MASTER_ID_ETH 102
#define MASTER_ID_PHY 103
#define MASTER_ID_WLAN 104
/* Input */
#define MASTER_ID_INPUT 111
#define MASTER_ID_TOUCH 112
/* Security */
#define MASTER_ID_HWCRYPTO 121
#define MASTER_ID_RNG 122
#define MASTER_ID_TEE 123
/* SPI */
#define MASTER_ID_SPI_BUS 131
#define MASTER_ID_SPI_DEV 132
/* TTY */
#define MASTER_ID_TTY 141
#define MASTER_ID_TTY_SLAVES 142
#define MASTER_ID_TTY_ALTERNATE 143
#define MASTER_ID_PTMX 144
/* USB */
#define MASTER_ID_USB_DEV 151
#define MASTER_ID_USB_BUS 152
#define MASTER_ID_USB_OTG 153
#endif /* __RT_DM_MASTER_ID_H__ */

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-09-24 GuEe-GUI the first version
*/
#ifndef __RT_DM_NUMA_H__
#define __RT_DM_NUMA_H__
#include <rthw.h>
#include <rtthread.h>
#include <bitmap.h>
/* NUMA: Non-Uniform Memory Access */
int rt_numa_cpu_id(int cpuid);
int rt_numa_device_id(struct rt_device *dev);
rt_err_t rt_numa_memory_affinity(rt_uint64_t phy_addr, rt_bitmap_t *out_affinity);
#endif /* __RT_DM_NUMA_H__ */

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-21 GuEe-GUI first version
*/
#ifndef __RT_DM_POWER_DOMAIN_H__
#define __RT_DM_POWER_DOMAIN_H__
#include <rthw.h>
#include <rtthread.h>
#include <ref.h>
#define RT_POWER_DOMAIN_OBJ_NAME "PMD"
#define RT_POWER_DOMAIN_PROXY_OBJ_NAME "PMP"
struct rt_ofw_node;
struct rt_ofw_cell_args;
struct rt_dm_power_domain_unit
{
rt_list_t list;
int id;
struct rt_dm_power_domain *domain;
};
struct rt_dm_power_domain_proxy
{
struct rt_object parent;
struct rt_dm_power_domain *(*ofw_parse)(struct rt_dm_power_domain_proxy *proxy,
struct rt_ofw_cell_args *args);
};
struct rt_dm_power_domain
{
struct rt_object parent;
struct rt_device *dev;
struct rt_dm_power_domain *parent_domain;
rt_list_t list;
rt_list_t child_nodes;
rt_list_t unit_nodes;
struct rt_ref ref;
struct rt_spinlock lock;
rt_err_t (*power_on)(struct rt_dm_power_domain *domain);
rt_err_t (*power_off)(struct rt_dm_power_domain *domain);
rt_err_t (*attach_dev)(struct rt_dm_power_domain *domain, struct rt_device *dev);
rt_err_t (*detach_dev)(struct rt_dm_power_domain *domain, struct rt_device *dev);
void *pirv;
};
void rt_dm_power_domain_proxy_default_name(struct rt_dm_power_domain_proxy *proxy);
void rt_dm_power_domain_proxy_ofw_bind(struct rt_dm_power_domain_proxy *proxy,
struct rt_ofw_node *np);
rt_err_t rt_dm_power_domain_register(struct rt_dm_power_domain *domain);
rt_err_t rt_dm_power_domain_unregister(struct rt_dm_power_domain *domain);
rt_err_t rt_dm_power_domain_register_child(struct rt_dm_power_domain *domain,
struct rt_dm_power_domain *child_domain);
rt_err_t rt_dm_power_domain_unregister_child(struct rt_dm_power_domain *domain,
struct rt_dm_power_domain *child_domain);
rt_err_t rt_dm_power_domain_power_on(struct rt_dm_power_domain *domain);
rt_err_t rt_dm_power_domain_power_off(struct rt_dm_power_domain *domain);
struct rt_dm_power_domain *rt_dm_power_domain_get_by_index(struct rt_device *dev, int index);
struct rt_dm_power_domain *rt_dm_power_domain_get_by_name(struct rt_device *dev, const char *name);
rt_err_t rt_dm_power_domain_put(struct rt_dm_power_domain *domain);
rt_err_t rt_dm_power_domain_attach(struct rt_device *dev, rt_bool_t on);
rt_err_t rt_dm_power_domain_detach(struct rt_device *dev, rt_bool_t off);
#endif /* __RT_DM_POWER_DOMAIN_H__ */

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-12-23 Bernard first version
*/
#ifndef CPUTIME_H__
#define CPUTIME_H__
#include <stdint.h>
#include "cputimer.h"
struct rt_clock_cputime_ops
{
uint64_t (*cputime_getres)(void);
uint64_t (*cputime_gettime)(void);
int (*cputime_settimeout)(uint64_t tick, void (*timeout)(void *param), void *param);
};
uint64_t clock_cpu_getres(void);
uint64_t clock_cpu_gettime(void);
int clock_cpu_settimeout(uint64_t tick, void (*timeout)(void *param), void *param);
int clock_cpu_issettimeout(void);
uint64_t clock_cpu_microsecond(uint64_t cpu_tick);
uint64_t clock_cpu_millisecond(uint64_t cpu_tick);
int clock_cpu_setops(const struct rt_clock_cputime_ops *ops);
#ifdef RT_USING_CPUTIME_RISCV
int riscv_cputime_init(void);
#endif /* RT_USING_CPUTIME_RISCV */
#endif

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-13 zhkag first version
*/
#ifndef CPUTIMER_H__
#define CPUTIMER_H__
#include <rtthread.h>
struct rt_cputimer
{
struct rt_object parent; /**< inherit from rt_object */
rt_list_t row;
void (*timeout_func)(void *parameter);
void *parameter;
rt_uint64_t init_tick;
rt_uint64_t timeout_tick;
struct rt_semaphore sem;
};
typedef struct rt_cputimer *rt_cputimer_t;
rt_err_t rt_cputimer_detach(rt_cputimer_t timer);
#ifdef RT_USING_HEAP
void rt_cputimer_init(rt_cputimer_t timer,
const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_uint64_t tick,
rt_uint8_t flag);
rt_err_t rt_cputimer_delete(rt_cputimer_t timer);
#endif
rt_err_t rt_cputimer_start(rt_cputimer_t timer);
rt_err_t rt_cputimer_stop(rt_cputimer_t timer);
rt_err_t rt_cputimer_control(rt_cputimer_t timer, int cmd, void *arg);
rt_err_t rt_cputime_sleep(rt_uint64_t tick);
rt_err_t rt_cputime_ndelay(rt_uint64_t ns);
rt_err_t rt_cputime_udelay(rt_uint64_t us);
rt_err_t rt_cputime_mdelay(rt_uint64_t ms);
#endif

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-17 tyx the first version
*/
#ifndef __CRYPTO_H__
#define __CRYPTO_H__
#include <rtthread.h>
#include <hwcrypto.h>
#include <hw_symmetric.h>
#include <hw_rng.h>
#include <hw_hash.h>
#include <hw_crc.h>
#include <hw_gcm.h>
#include <hw_bignum.h>
#endif

View File

@ -0,0 +1,136 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-06-19 thread-liu the first version
*/
#ifndef __DAC_H__
#define __DAC_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_DAC DAC
*
* @brief DAC driver api
*
* <b>Example</b>
* @code {.c}
*
* #include <rtthread.h>
* #include <rtdevice.h>
* #include <stdlib.h>
* #define DAC_DEV_NAME "dac1"
* #define DAC_DEV_CHANNEL 1
* #define REFER_VOLTAGE 330
* #define CONVERT_BITS (1 << 12)
*
* static int dac_vol_sample(int argc, char *argv[])
* {
* rt_dac_device_t dac_dev;
* rt_uint32_t value, vol;
* rt_err_t ret = RT_EOK;
*
* dac_dev = (rt_dac_device_t)rt_device_find(DAC_DEV_NAME);
* if (dac_dev == RT_NULL)
* {
* rt_kprintf("dac sample run failed! can't find %s device!\n", DAC_DEV_NAME);
* return -RT_ERROR;
* }
*
* ret = rt_dac_enable(dac_dev, DAC_DEV_CHANNEL);
*
* value = atoi(argv[1]);
* rt_dac_write(dac_dev, DAC_DEV_NAME, DAC_DEV_CHANNEL, value);
* rt_kprintf("the value is :%d \n", value);
*
* vol = value * REFER_VOLTAGE / CONVERT_BITS;
* rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100);
*
* rt_thread_mdelay(500);
*
* ret = rt_dac_disable(dac_dev, DAC_DEV_CHANNEL);
*
* return ret;
* }
* MSH_CMD_EXPORT(dac_vol_sample, dac voltage convert sample);
*
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_DAC
* @{
*/
struct rt_dac_device;
/**
* @brief Configuration of DAC device
*/
struct rt_dac_ops
{
rt_err_t (*disabled)(struct rt_dac_device *device, rt_uint32_t channel);
rt_err_t (*enabled)(struct rt_dac_device *device, rt_uint32_t channel);
rt_err_t (*convert)(struct rt_dac_device *device, rt_uint32_t channel, rt_uint32_t *value);
rt_uint8_t (*get_resolution)(struct rt_dac_device *device);
};
/**
* @brief DAC device structure
*
*/
struct rt_dac_device
{
struct rt_device parent;
const struct rt_dac_ops *ops;
};
typedef struct rt_dac_device *rt_dac_device_t;
typedef enum
{
RT_DAC_CMD_ENABLE = RT_DEVICE_CTRL_BASE(DAC) + 0,
RT_DAC_CMD_DISABLE = RT_DEVICE_CTRL_BASE(DAC) + 1,
RT_DAC_CMD_GET_RESOLUTION = RT_DEVICE_CTRL_BASE(DAC) + 2,
} rt_dac_cmd_t;
/**
* @brief Register a DAC device
* @param dac DAC device
* @param name DAC name
* @param ops the operations of DAC device
* @param user_data device private data
* @return rt_err_t error code
*/
rt_err_t rt_hw_dac_register(rt_dac_device_t dac,const char *name, const struct rt_dac_ops *ops, const void *user_data);
/**
* @brief set the value of DAC
* @param dev DAC device
* @param channel DAC channel
* @param value the value of DAC
* @return rt_err_t error code
*/
rt_err_t rt_dac_write(rt_dac_device_t dev, rt_uint32_t channel, rt_uint32_t value);
/**
* @brief enable the DAC channel
* @param dev DAC device
* @param channel DAC channel
* @return rt_err_t error code
*/
rt_err_t rt_dac_enable(rt_dac_device_t dev, rt_uint32_t channel);
/**
* @brief disable the DAC channel
* @param dev DAC device
* @param channel DAC channel
* @return rt_err_t error code
*/
rt_err_t rt_dac_disable(rt_dac_device_t dev, rt_uint32_t channel);
/*! @}*/
#endif /* __dac_H__ */

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-10-27 heyuanjie87 first version.
* 2013-05-17 aozima initial alarm event & mutex in system init.
* 2020-10-15 zhangsz add alarm flags hour minute second.
*/
#ifndef __DEV_ALARM_H__
#define __DEV_ALARM_H__
#include <sys/time.h>
#include <rtdef.h>
#define RT_ALARM_TM_NOW -1 /* set the alarm tm_day,tm_mon,tm_sec,etc.
to now.we also call it "don't care" value */
/* alarm flags */
#define RT_ALARM_ONESHOT 0x000 /* only alarm once */
#define RT_ALARM_DAILY 0x100 /* alarm everyday */
#define RT_ALARM_WEEKLY 0x200 /* alarm weekly at Monday or Friday etc. */
#define RT_ALARM_MONTHLY 0x400 /* alarm monthly at someday */
#define RT_ALARM_YAERLY 0x800 /* alarm yearly at a certain date */
#define RT_ALARM_HOUR 0x1000 /* alarm each hour at a certain min:second */
#define RT_ALARM_MINUTE 0x2000 /* alarm each minute at a certain second */
#define RT_ALARM_SECOND 0x4000 /* alarm each second */
#define RT_ALARM_STATE_INITED 0x02
#define RT_ALARM_STATE_START 0x01
#define RT_ALARM_STATE_STOP 0x00
/* alarm control cmd */
#define RT_ALARM_CTRL_MODIFY 1 /* modify alarm time or alarm flag */
typedef struct rt_alarm *rt_alarm_t;
typedef void (*rt_alarm_callback_t)(rt_alarm_t alarm, time_t timestamp);
struct rt_alarm
{
rt_list_t list;
rt_uint32_t flag;
rt_alarm_callback_t callback;
struct tm wktime;
void *user_data;
};
struct rt_alarm_setup
{
rt_uint32_t flag; /* alarm flag */
struct tm wktime; /* when will the alarm wake up user */
};
struct rt_alarm_container
{
rt_list_t head;
struct rt_mutex mutex;
struct rt_event event;
struct rt_alarm *current;
};
rt_alarm_t rt_alarm_create(rt_alarm_callback_t callback,
struct rt_alarm_setup *setup);
rt_err_t rt_alarm_control(rt_alarm_t alarm, int cmd, void *arg);
void rt_alarm_update(rt_device_t dev, rt_uint32_t event);
rt_err_t rt_alarm_delete(rt_alarm_t alarm);
rt_err_t rt_alarm_start(rt_alarm_t alarm);
rt_err_t rt_alarm_stop(rt_alarm_t alarm);
int rt_alarm_system_init(void);
#endif /* __DEV_ALARM_H__ */

View File

@ -0,0 +1,176 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-05-09 Urey first version
* 2019-07-09 Zero-Free improve device ops interface and data flows
*
*/
#ifndef __DEV_AUDIO_H__
#define __DEV_AUDIO_H__
#include "dev_audio_pipe.h"
/* AUDIO command */
#define _AUDIO_CTL(a) (RT_DEVICE_CTRL_BASE(Sound) + a)
#define AUDIO_CTL_GETCAPS _AUDIO_CTL(1)
#define AUDIO_CTL_CONFIGURE _AUDIO_CTL(2)
#define AUDIO_CTL_START _AUDIO_CTL(3)
#define AUDIO_CTL_STOP _AUDIO_CTL(4)
#define AUDIO_CTL_GETBUFFERINFO _AUDIO_CTL(5)
/* Audio Device Types */
#define AUDIO_TYPE_QUERY 0x00
#define AUDIO_TYPE_INPUT 0x01
#define AUDIO_TYPE_OUTPUT 0x02
#define AUDIO_TYPE_MIXER 0x04
/* Supported Sampling Rates */
#define AUDIO_SAMP_RATE_8K 0x0001
#define AUDIO_SAMP_RATE_11K 0x0002
#define AUDIO_SAMP_RATE_16K 0x0004
#define AUDIO_SAMP_RATE_22K 0x0008
#define AUDIO_SAMP_RATE_32K 0x0010
#define AUDIO_SAMP_RATE_44K 0x0020
#define AUDIO_SAMP_RATE_48K 0x0040
#define AUDIO_SAMP_RATE_96K 0x0080
#define AUDIO_SAMP_RATE_128K 0x0100
#define AUDIO_SAMP_RATE_160K 0x0200
#define AUDIO_SAMP_RATE_172K 0x0400
#define AUDIO_SAMP_RATE_192K 0x0800
/* Supported Bit Rates */
#define AUDIO_BIT_RATE_22K 0x01
#define AUDIO_BIT_RATE_44K 0x02
#define AUDIO_BIT_RATE_48K 0x04
#define AUDIO_BIT_RATE_96K 0x08
#define AUDIO_BIT_RATE_128K 0x10
#define AUDIO_BIT_RATE_160K 0x20
#define AUDIO_BIT_RATE_172K 0x40
#define AUDIO_BIT_RATE_192K 0x80
/* Support Dsp(input/output) Units controls */
#define AUDIO_DSP_PARAM 0 /* get/set all params */
#define AUDIO_DSP_SAMPLERATE 1 /* samplerate */
#define AUDIO_DSP_CHANNELS 2 /* channels */
#define AUDIO_DSP_SAMPLEBITS 3 /* sample bits width */
/* Supported Mixer Units controls */
#define AUDIO_MIXER_QUERY 0x0000
#define AUDIO_MIXER_MUTE 0x0001
#define AUDIO_MIXER_VOLUME 0x0002
#define AUDIO_MIXER_BASS 0x0004
#define AUDIO_MIXER_MID 0x0008
#define AUDIO_MIXER_TREBLE 0x0010
#define AUDIO_MIXER_EQUALIZER 0x0020
#define AUDIO_MIXER_LINE 0x0040
#define AUDIO_MIXER_DIGITAL 0x0080
#define AUDIO_MIXER_MIC 0x0100
#define AUDIO_MIXER_VITURAL 0x0200
#define AUDIO_MIXER_EXTEND 0x8000 /* extend mixer command */
#define AUDIO_VOLUME_MAX (100)
#define AUDIO_VOLUME_MIN (0)
#define CFG_AUDIO_REPLAY_QUEUE_COUNT 4
enum
{
AUDIO_STREAM_REPLAY = 0,
AUDIO_STREAM_RECORD,
AUDIO_STREAM_LAST = AUDIO_STREAM_RECORD,
};
/* the preferred number and size of audio pipeline buffer for the audio device */
struct rt_audio_buf_info
{
rt_uint8_t *buffer;
rt_uint16_t block_size;
rt_uint16_t block_count;
rt_uint32_t total_size;
};
struct rt_audio_device;
struct rt_audio_caps;
struct rt_audio_configure;
struct rt_audio_ops
{
rt_err_t (*getcaps)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
rt_err_t (*configure)(struct rt_audio_device *audio, struct rt_audio_caps *caps);
rt_err_t (*init)(struct rt_audio_device *audio);
rt_err_t (*start)(struct rt_audio_device *audio, int stream);
rt_err_t (*stop)(struct rt_audio_device *audio, int stream);
rt_ssize_t (*transmit)(struct rt_audio_device *audio, const void *writeBuf, void *readBuf, rt_size_t size);
/* get page size of codec or private buffer's info */
void (*buffer_info)(struct rt_audio_device *audio, struct rt_audio_buf_info *info);
};
struct rt_audio_configure
{
rt_uint32_t samplerate;
rt_uint16_t channels;
rt_uint16_t samplebits;
};
struct rt_audio_caps
{
int main_type;
int sub_type;
union
{
rt_uint32_t mask;
int value;
struct rt_audio_configure config;
} udata;
};
struct rt_audio_replay
{
struct rt_mempool *mp;
struct rt_data_queue queue;
struct rt_mutex lock;
struct rt_completion cmp;
struct rt_audio_buf_info buf_info;
rt_uint8_t *write_data;
rt_uint16_t write_index;
rt_uint16_t read_index;
rt_uint32_t pos;
rt_uint8_t event;
rt_bool_t activated;
};
struct rt_audio_record
{
struct rt_audio_pipe pipe;
rt_bool_t activated;
};
struct rt_audio_device
{
struct rt_device parent;
struct rt_audio_ops *ops;
struct rt_audio_replay *replay;
struct rt_audio_record *record;
};
rt_err_t rt_audio_register(struct rt_audio_device *audio, const char *name, rt_uint32_t flag, void *data);
void rt_audio_tx_complete(struct rt_audio_device *audio);
void rt_audio_rx_done(struct rt_audio_device *audio, rt_uint8_t *pbuf, rt_size_t len);
/* Device Control Commands */
#define CODEC_CMD_RESET 0
#define CODEC_CMD_SET_VOLUME 1
#define CODEC_CMD_GET_VOLUME 2
#define CODEC_CMD_SAMPLERATE 3
#define CODEC_CMD_EQ 4
#define CODEC_CMD_3D 5
#define CODEC_VOLUME_MAX (63)
#endif /* __DEV_AUDIO_H__ */

View File

@ -0,0 +1,547 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-05-14 aubrcool@qq.com first version
* 2015-07-06 Bernard remove RT_CAN_USING_LED.
* 2022-05-08 hpmicro add CANFD support, fixed typos
*/
#ifndef __DEV_CAN_H_
#define __DEV_CAN_H_
#include <rtthread.h>
#ifndef RT_CANMSG_BOX_SZ
#define RT_CANMSG_BOX_SZ 16
#endif
#ifndef RT_CANSND_BOX_NUM
#define RT_CANSND_BOX_NUM 1
#endif
enum CAN_DLC
{
CAN_MSG_0BYTE = 0,
CAN_MSG_1BYTE,
CAN_MSG_2BYTES,
CAN_MSG_3BYTES,
CAN_MSG_4BYTES,
CAN_MSG_5BYTES,
CAN_MSG_6BYTES,
CAN_MSG_7BYTES,
CAN_MSG_8BYTES,
CAN_MSG_12BYTES,
CAN_MSG_16BYTES,
CAN_MSG_20BYTES,
CAN_MSG_24BYTES,
CAN_MSG_32BYTES,
CAN_MSG_48BYTES,
CAN_MSG_64BYTES,
};
enum CANBAUD
{
CAN1MBaud = 1000UL * 1000,/* 1 MBit/sec */
CAN800kBaud = 1000UL * 800, /* 800 kBit/sec */
CAN500kBaud = 1000UL * 500, /* 500 kBit/sec */
CAN250kBaud = 1000UL * 250, /* 250 kBit/sec */
CAN125kBaud = 1000UL * 125, /* 125 kBit/sec */
CAN100kBaud = 1000UL * 100, /* 100 kBit/sec */
CAN50kBaud = 1000UL * 50, /* 50 kBit/sec */
CAN20kBaud = 1000UL * 20, /* 20 kBit/sec */
CAN10kBaud = 1000UL * 10 /* 10 kBit/sec */
};
#define RT_CAN_MODE_NORMAL 0
#define RT_CAN_MODE_LISTEN 1
#define RT_CAN_MODE_LOOPBACK 2
#define RT_CAN_MODE_LOOPBACKANLISTEN 3
#define RT_CAN_MODE_PRIV 0x01
#define RT_CAN_MODE_NOPRIV 0x00
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_CAN_Device CAN Driver
*
* @brief CAN driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include "rtdevice.h"
*
* #define CAN_DEV_NAME "can1" // CAN 设备名称
*
* static struct rt_semaphore rx_sem; // 用于接收消息的信号量
* static rt_device_t can_dev; // CAN 设备句柄
*
* // 接收数据回调函数
* static rt_err_t can_rx_call(rt_device_t dev, rt_size_t size)
* {
* // CAN 接收到数据后产生中断,调用此回调函数,然后发送接收信号量
* rt_sem_release(&rx_sem);
*
* return RT_EOK;
* }
*
* static void can_rx_thread(void *parameter)
* {
* int i;
* rt_err_t res;
* struct rt_can_msg rxmsg = {0};
*
* // 设置接收回调函数
* rt_device_set_rx_indicate(can_dev, can_rx_call);
*
* #ifdef RT_CAN_USING_HDR
* struct rt_can_filter_item items[5] =
* {
* RT_CAN_FILTER_ITEM_INIT(0x100, 0, 0, 0, 0x700, RT_NULL, RT_NULL), // std,match ID:0x100~0x1ffhdr 为 - 1设置默认过滤表
* RT_CAN_FILTER_ITEM_INIT(0x300, 0, 0, 0, 0x700, RT_NULL, RT_NULL), // std,match ID:0x300~0x3ffhdr 为 - 1
* RT_CAN_FILTER_ITEM_INIT(0x211, 0, 0, 0, 0x7ff, RT_NULL, RT_NULL), // std,match ID:0x211hdr 为 - 1
* RT_CAN_FILTER_STD_INIT(0x486, RT_NULL, RT_NULL), // std,match ID:0x486hdr 为 - 1
* {0x555, 0, 0, 0, 0x7ff, 7,} // std,match ID:0x555hdr 为 7指定设置 7 号过滤表
* };
* struct rt_can_filter_config cfg = {5, 1, items}; // 一共有 5 个过滤表
* // 设置硬件过滤表
* res = rt_device_control(can_dev, RT_CAN_CMD_SET_FILTER, &cfg);
* RT_ASSERT(res == RT_EOK);
* #endif
* res = RT_TRUE;
* res = rt_device_control(can_dev, RT_CAN_CMD_START, &res);
* while (1)
* {
* // hdr 值为 - 1表示直接从 uselist 链表读取数据
* rxmsg.hdr = -1;
* // 阻塞等待接收信号量
* rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
* // 从 CAN 读取一帧数据
* rt_device_read(can_dev, 0, &rxmsg, sizeof(rxmsg));
* // 打印数据 ID 及内容
* rt_kprintf("ID:%x", rxmsg.id);
* for (i = 0; i < 8; i++)
* {
* rt_kprintf("%2x", rxmsg.data[i]);
* }
*
* rt_kprintf("\n");
* }
* }
*
* int can_sample(int argc, char *argv[])
* {
* struct rt_can_msg msg = {0};
* rt_err_t res;
* rt_size_t size;
* rt_thread_t thread;
* char can_name[RT_NAME_MAX];
*
* if (argc == 2)
* {
* rt_strncpy(can_name, argv[1], RT_NAME_MAX);
* }
* else
* {
* rt_strncpy(can_name, CAN_DEV_NAME, RT_NAME_MAX);
* }
* // 查找 CAN 设备
* can_dev = rt_device_find(can_name);
* if (!can_dev)
* {
* rt_kprintf("find %s failed!\n", can_name);
* return -RT_ERROR;
* }
*
* // 初始化 CAN 接收信号量
* rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
*
* // 以中断接收及发送方式打开 CAN 设备
* res = rt_device_open(can_dev, RT_DEVICE_FLAG_INT_TX | RT_DEVICE_FLAG_INT_RX);
* RT_ASSERT(res == RT_EOK);
* // 创建数据接收线程
* thread = rt_thread_create("can_rx", can_rx_thread, RT_NULL, 1024, 25, 10);
* if (thread != RT_NULL)
* {
* rt_thread_startup(thread);
* }
* else
* {
* rt_kprintf("create can_rx thread failed!\n");
* }
*
* msg.id = 0x78; // ID 为 0x78
* msg.ide = RT_CAN_STDID; // 标准格式
* msg.rtr = RT_CAN_DTR; // 数据帧
* msg.len = 8; // 数据长度为 8
* // 待发送的 8 字节数据
* msg.data[0] = 0x00;
* msg.data[1] = 0x11;
* msg.data[2] = 0x22;
* msg.data[3] = 0x33;
* msg.data[4] = 0x44;
* msg.data[5] = 0x55;
* msg.data[6] = 0x66;
* msg.data[7] = 0x77;
* // 发送一帧 CAN 数据
* size = rt_device_write(can_dev, 0, &msg, sizeof(msg));
* if (size == 0)
* {
* rt_kprintf("can dev write data failed!\n");
* }
*
* return res;
* }
* // 导出到 msh 命令列表中
* MSH_CMD_EXPORT(can_sample, can device sample);
* @endcode
*
* @ingroup group_Drivers
*
*/
/*!
* @addtogroup group_CAN_Device
* @{
*/
#define CAN_RX_FIFO0 (0x00000000U) /*!< CAN receive FIFO 0 */
#define CAN_RX_FIFO1 (0x00000001U) /*!< CAN receive FIFO 1 */
/**
* @brief CAN filter item
*/
struct rt_can_filter_item
{
rt_uint32_t id : 29;
rt_uint32_t ide : 1;
rt_uint32_t rtr : 1;
rt_uint32_t mode : 1;
rt_uint32_t mask;
rt_int32_t hdr_bank;/*Should be defined as:rx.FilterBank,which should be changed to rt_int32_t hdr_bank*/
rt_uint32_t rxfifo;/*Add a configuration item that CAN_RX_FIFO0/CAN_RX_FIFO1*/
#ifdef RT_CAN_USING_HDR
rt_err_t (*ind)(rt_device_t dev, void *args , rt_int32_t hdr, rt_size_t size);
void *args;
#endif /*RT_CAN_USING_HDR*/
};
#ifdef RT_CAN_USING_HDR
#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask,ind,args) \
{(id), (ide), (rtr), (mode),(mask), -1, CAN_RX_FIFO0,(ind), (args)}/*0:CAN_RX_FIFO0*/
#define RT_CAN_FILTER_STD_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF,ind,args)
#define RT_CAN_FILTER_EXT_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF,ind,args)
#define RT_CAN_STD_RMT_FILTER_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF,ind,args)
#define RT_CAN_EXT_RMT_FILTER_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF,ind,args)
#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF,ind,args)
#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id,ind,args) \
RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF,ind,args)
#else
#define RT_CAN_FILTER_ITEM_INIT(id,ide,rtr,mode,mask) \
{(id), (ide), (rtr), (mode), (mask), -1, CAN_RX_FIFO0 }/*0:CAN_RX_FIFO0*/
#define RT_CAN_FILTER_STD_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,0,0xFFFFFFFF)
#define RT_CAN_FILTER_EXT_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,1,0,0,0xFFFFFFFF)
#define RT_CAN_STD_RMT_FILTER_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,0,1,0,0xFFFFFFFF)
#define RT_CAN_EXT_RMT_FILTER_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,1,1,0,0xFFFFFFFF)
#define RT_CAN_STD_RMT_DATA_FILTER_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,0,0,1,0xFFFFFFFF)
#define RT_CAN_EXT_RMT_DATA_FILTER_INIT(id) \
RT_CAN_FILTER_ITEM_INIT(id,1,0,1,0xFFFFFFFF)
#endif
/**
* @brief CAN filter configuration
*/
struct rt_can_filter_config
{
rt_uint32_t count;
rt_uint32_t actived;
struct rt_can_filter_item *items;
};
/**
* @brief CAN timing configuration
*/
struct rt_can_bit_timing
{
rt_uint16_t prescaler; /* Pre-scaler */
rt_uint16_t num_seg1; /* Bit Timing Segment 1, in terms of Tq */
rt_uint16_t num_seg2; /* Bit Timing Segment 2, in terms of Tq */
rt_uint8_t num_sjw; /* Synchronization Jump Width, in terms of Tq */
rt_uint8_t num_sspoff; /* Secondary Sample Point Offset, in terms of Tq */
};
/**
* @brief CAN bit timing configuration list
* @note
* items[0] always for CAN2.0/CANFD Arbitration Phase
* items[1] always for CANFD (if it exists)
*/
struct rt_can_bit_timing_config
{
rt_uint32_t count;
struct rt_can_bit_timing *items;
};
/**
* @brief CAN configuration
*/
struct can_configure
{
rt_uint32_t baud_rate;
rt_uint32_t msgboxsz;
rt_uint32_t sndboxnumber;
rt_uint32_t mode : 8;
rt_uint32_t privmode : 8;
rt_uint32_t reserved : 16;
rt_uint32_t ticks;
#ifdef RT_CAN_USING_HDR
rt_uint32_t maxhdr;
#endif
#ifdef RT_CAN_USING_CANFD
rt_uint32_t baud_rate_fd; /* CANFD data bit rate*/
rt_uint32_t use_bit_timing: 8; /* Use the bit timing for CAN timing configuration */
rt_uint32_t enable_canfd : 8; /* Enable CAN-FD mode */
rt_uint32_t reserved1 : 16;
/* The below fields take effect only if use_bit_timing is non-zero */
struct rt_can_bit_timing can_timing; /* CAN bit-timing /CANFD bit-timing for arbitration phase */
struct rt_can_bit_timing canfd_timing; /* CANFD bit-timing for datat phase */
#endif
};
#define CANDEFAULTCONFIG \
{\
CAN1MBaud,\
RT_CANMSG_BOX_SZ,\
RT_CANSND_BOX_NUM,\
RT_CAN_MODE_NORMAL,\
};
struct rt_can_ops;
#define RT_CAN_CMD_SET_FILTER 0x13
#define RT_CAN_CMD_SET_BAUD 0x14
#define RT_CAN_CMD_SET_MODE 0x15
#define RT_CAN_CMD_SET_PRIV 0x16
#define RT_CAN_CMD_GET_STATUS 0x17
#define RT_CAN_CMD_SET_STATUS_IND 0x18
#define RT_CAN_CMD_SET_BUS_HOOK 0x19
#define RT_CAN_CMD_SET_CANFD 0x1A
#define RT_CAN_CMD_SET_BAUD_FD 0x1B
#define RT_CAN_CMD_SET_BITTIMING 0x1C
#define RT_CAN_CMD_START 0x1D
#define RT_DEVICE_CAN_INT_ERR 0x1000
enum RT_CAN_STATUS_MODE
{
NORMAL = 0,
ERRWARNING = 1,
ERRPASSIVE = 2,
BUSOFF = 4,
};
enum RT_CAN_BUS_ERR
{
RT_CAN_BUS_NO_ERR = 0,
RT_CAN_BUS_BIT_PAD_ERR = 1,
RT_CAN_BUS_FORMAT_ERR = 2,
RT_CAN_BUS_ACK_ERR = 3,
RT_CAN_BUS_IMPLICIT_BIT_ERR = 4,
RT_CAN_BUS_EXPLICIT_BIT_ERR = 5,
RT_CAN_BUS_CRC_ERR = 6,
};
/**
* @brief CAN status
*/
struct rt_can_status
{
rt_uint32_t rcverrcnt;
rt_uint32_t snderrcnt;
rt_uint32_t errcode;
rt_uint32_t rcvpkg;
rt_uint32_t dropedrcvpkg;
rt_uint32_t sndpkg;
rt_uint32_t dropedsndpkg;
rt_uint32_t bitpaderrcnt;
rt_uint32_t formaterrcnt;
rt_uint32_t ackerrcnt;
rt_uint32_t biterrcnt;
rt_uint32_t crcerrcnt;
rt_uint32_t rcvchange;
rt_uint32_t sndchange;
rt_uint32_t lasterrtype;
};
#ifdef RT_CAN_USING_HDR
struct rt_can_hdr
{
rt_uint32_t connected;
rt_uint32_t msgs;
struct rt_can_filter_item filter;
struct rt_list_node list;
};
#endif
struct rt_can_device;
typedef rt_err_t (*rt_canstatus_ind)(struct rt_can_device *, void *);
typedef struct rt_can_status_ind_type
{
rt_canstatus_ind ind;
void *args;
} *rt_can_status_ind_type_t;
typedef void (*rt_can_bus_hook)(struct rt_can_device *);
struct rt_can_device
{
struct rt_device parent;
const struct rt_can_ops *ops;
struct can_configure config;
struct rt_can_status status;
rt_uint32_t timerinitflag;
struct rt_timer timer;
struct rt_can_status_ind_type status_indicate;
#ifdef RT_CAN_USING_HDR
struct rt_can_hdr *hdr;
#endif
#ifdef RT_CAN_USING_BUS_HOOK
rt_can_bus_hook bus_hook;
#endif /*RT_CAN_USING_BUS_HOOK*/
struct rt_mutex lock;
void *can_rx;
void *can_tx;
};
typedef struct rt_can_device *rt_can_t;
#define RT_CAN_STDID 0
#define RT_CAN_EXTID 1
#define RT_CAN_DTR 0
#define RT_CAN_RTR 1
typedef struct rt_can_status *rt_can_status_t;
struct rt_can_msg
{
rt_uint32_t id : 29;
rt_uint32_t ide : 1;
rt_uint32_t rtr : 1;
rt_uint32_t rsv : 1;
rt_uint32_t len : 8;
rt_uint32_t priv : 8;
rt_int32_t hdr_index : 8;/*Should be defined as:rx.FilterMatchIndex,which should be changed to rt_int32_t hdr_index : 8*/
#ifdef RT_CAN_USING_CANFD
rt_uint32_t fd_frame : 1;
rt_uint32_t brs : 1;
rt_uint32_t rxfifo : 2;/*Redefined to return :CAN RX FIFO0/CAN RX FIFO1*/
rt_uint32_t reserved : 4;
#else
rt_uint32_t rxfifo : 2;/*Redefined to return :CAN RX FIFO0/CAN RX FIFO1*/
rt_uint32_t reserved : 6;
#endif
#ifdef RT_CAN_USING_CANFD
rt_uint8_t data[64];
#else
rt_uint8_t data[8];
#endif
};
typedef struct rt_can_msg *rt_can_msg_t;
struct rt_can_msg_list
{
struct rt_list_node list;
#ifdef RT_CAN_USING_HDR
struct rt_list_node hdrlist;
struct rt_can_hdr *owner;
#endif
struct rt_can_msg data;
};
struct rt_can_rx_fifo
{
/* software fifo */
struct rt_can_msg_list *buffer;
rt_uint32_t freenumbers;
struct rt_list_node freelist;
struct rt_list_node uselist;
};
#define RT_CAN_SND_RESULT_OK 0
#define RT_CAN_SND_RESULT_ERR 1
#define RT_CAN_SND_RESULT_WAIT 2
#define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */
#define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx fail */
#define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
#define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */
struct rt_can_sndbxinx_list
{
struct rt_list_node list;
struct rt_completion completion;
rt_uint32_t result;
};
struct rt_can_tx_fifo
{
struct rt_can_sndbxinx_list *buffer;
struct rt_semaphore sem;
struct rt_list_node freelist;
};
/**
* @brief CAN operators
*/
struct rt_can_ops
{
rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg);
rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg);
rt_ssize_t (*sendmsg)(struct rt_can_device *can, const void *buf, rt_uint32_t boxno);
rt_ssize_t (*recvmsg)(struct rt_can_device *can, void *buf, rt_uint32_t boxno);
};
/**
* @brief Register a CAN device to device list
*
* @param can the CAN device object
* @param name the name of CAN device
* @param ops the CAN device operators
* @param data the private data of CAN device
*
* @return the error code, RT_EOK on successfully
*/
rt_err_t rt_hw_can_register(struct rt_can_device *can,
const char *name,
const struct rt_can_ops *ops,
void *data);
/**
* @brief CAN interrupt service routine
*
* @param can the CAN device
* @param event the event mask
*/
void rt_hw_can_isr(struct rt_can_device *can, int event);
/*! @}*/
#endif /*__DEV_CAN_H*/

View File

@ -0,0 +1,401 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-04-25 weety first version
* 2021-04-20 RiceChen added support for bus control api
*/
#ifndef __DEV_I2C_H__
#define __DEV_I2C_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_I2C I2C
*
* @brief I2C driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include <rtdevice.h>
*
* #define AHT10_I2C_BUS_NAME "i2c1" // 传感器连接的I2C总线设备名称
* #define AHT10_ADDR 0x38 // 从机地址
* #define AHT10_CALIBRATION_CMD 0xE1 // 校准命令
* #define AHT10_NORMAL_CMD 0xA8 // 一般命令
* #define AHT10_GET_DATA 0xAC // 获取数据命令
*
* static struct rt_i2c_bus_device *i2c_bus = RT_NULL; // I2C总线设备句柄
* static rt_bool_t initialized = RT_FALSE; // 传感器初始化状态
*
* // 写传感器寄存器
* static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data)
* {
* rt_uint8_t buf[3];
* struct rt_i2c_msg msgs;
* rt_uint32_t buf_size = 1;
*
* buf[0] = reg; //cmd
* if (data != RT_NULL)
* {
* buf[1] = data[0];
* buf[2] = data[1];
* buf_size = 3;
* }
*
* msgs.addr = AHT10_ADDR;
* msgs.flags = RT_I2C_WR;
* msgs.buf = buf;
* msgs.len = buf_size;
*
* // 调用I2C设备接口传输数据
* if (rt_i2c_transfer(bus, &msgs, 1) == 1)
* {
* return RT_EOK;
* }
* else
* {
* return -RT_ERROR;
* }
* }
*
* // 读传感器寄存器数据
* static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
* {
* struct rt_i2c_msg msgs;
*
* msgs.addr = AHT10_ADDR;
* msgs.flags = RT_I2C_RD;
* msgs.buf = buf;
* msgs.len = len;
*
* // 调用I2C设备接口传输数据
* if (rt_i2c_transfer(bus, &msgs, 1) == 1)
* {
* return RT_EOK;
* }
* else
* {
* return -RT_ERROR;
* }
* }
*
* static void read_temp_humi(float *cur_temp, float *cur_humi)
* {
* rt_uint8_t temp[6];
*
* write_reg(i2c_bus, AHT10_GET_DATA, RT_NULL); // 发送命令
* rt_thread_mdelay(400);
* read_regs(i2c_bus, 6, temp); // 获取传感器数据
*
* // 湿度数据转换
* *cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20);
* // 温度数据转换
* *cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
* }
*
* static void aht10_init(const char *name)
* {
* rt_uint8_t temp[2] = {0, 0};
*
* // 查找I2C总线设备获取I2C总线设备句柄
* i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
*
* if (i2c_bus == RT_NULL)
* {
* rt_kprintf("can't find %s device!\n", name);
* }
* else
* {
* write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);
* rt_thread_mdelay(400);
*
* temp[0] = 0x08;
* temp[1] = 0x00;
* write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);
* rt_thread_mdelay(400);
* initialized = RT_TRUE;
* }
* }
*
* static void i2c_aht10_sample(int argc, char *argv[])
* {
* float humidity, temperature;
* char name[RT_NAME_MAX];
*
* humidity = 0.0;
* temperature = 0.0;
*
* if (argc == 2)
* {
* rt_strncpy(name, argv[1], RT_NAME_MAX);
* }
* else
* {
* rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX);
* }
*
* if (!initialized)
* {
* // 传感器初始化
* aht10_init(name);
* }
* if (initialized)
* {
* // 读取温湿度数据
* read_temp_humi(&temperature, &humidity);
*
* rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10);
* if( temperature >= 0 )
* {
* rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(temperature * 10) % 10);
* }
* else
* {
* rt_kprintf("read aht10 sensor temperature: %d.%d°C\n", (int)temperature, (int)(-temperature * 10) % 10);
* }
* }
* else
* {
* rt_kprintf("initialize sensor failed!\n");
* }
* }
* // 导出到 msh 命令列表中
* MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_I2C
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#define RT_I2C_WR 0x0000 /*!< i2c wirte flag */
#define RT_I2C_RD (1u << 0) /*!< i2c read flag */
#define RT_I2C_ADDR_10BIT (1u << 2) /*!< this is a ten bit chip address */
#define RT_I2C_NO_START (1u << 4) /*!< do not generate START condition */
#define RT_I2C_IGNORE_NACK (1u << 5) /*!< ignore NACK from slave */
#define RT_I2C_NO_READ_ACK (1u << 6) /* when I2C reading, we do not ACK */
#define RT_I2C_NO_STOP (1u << 7) /*!< do not generate STOP condition */
#define RT_I2C_DEV_CTRL_10BIT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x01)
#define RT_I2C_DEV_CTRL_ADDR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x02)
#define RT_I2C_DEV_CTRL_TIMEOUT (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x03)
#define RT_I2C_DEV_CTRL_RW (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x04)
#define RT_I2C_DEV_CTRL_CLK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x05)
#define RT_I2C_DEV_CTRL_UNLOCK (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x06)
#define RT_I2C_DEV_CTRL_GET_STATE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x07)
#define RT_I2C_DEV_CTRL_GET_MODE (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x08)
#define RT_I2C_DEV_CTRL_GET_ERROR (RT_DEVICE_CTRL_BASE(I2CBUS) + 0x09)
/**
* @brief I2C Private Data
*/
struct rt_i2c_priv_data
{
struct rt_i2c_msg *msgs;
rt_size_t number;
};
/**
* @brief I2C Message
*/
struct rt_i2c_msg
{
rt_uint16_t addr;
rt_uint16_t flags;
rt_uint16_t len;
rt_uint8_t *buf;
};
struct rt_i2c_bus_device;
/**
* @brief I2C Bus Device Operations
*/
struct rt_i2c_bus_device_ops
{
rt_ssize_t (*master_xfer)(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msgs[],
rt_uint32_t num);
rt_ssize_t (*slave_xfer)(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msgs[],
rt_uint32_t num);
rt_err_t (*i2c_bus_control)(struct rt_i2c_bus_device *bus,
int cmd,
void *args);
};
/**
* @brief I2C Bus Device
*/
struct rt_i2c_bus_device
{
struct rt_device parent;
const struct rt_i2c_bus_device_ops *ops;
rt_uint16_t flags;
struct rt_mutex lock;
rt_uint32_t timeout;
rt_uint32_t retries;
void *priv;
};
/**
* @brief I2C Client
*/
struct rt_i2c_client
{
#ifdef RT_USING_DM
struct rt_device parent;
const char *name;
const struct rt_i2c_device_id *id;
const struct rt_ofw_node_id *ofw_id;
#endif
struct rt_i2c_bus_device *bus;
rt_uint16_t client_addr;
};
#ifdef RT_USING_DM
struct rt_i2c_device_id
{
char name[20];
void *data;
};
struct rt_i2c_driver
{
struct rt_driver parent;
const struct rt_i2c_device_id *ids;
const struct rt_ofw_node_id *ofw_ids;
rt_err_t (*probe)(struct rt_i2c_client *client);
rt_err_t (*remove)(struct rt_i2c_client *client);
rt_err_t (*shutdown)(struct rt_i2c_client *client);
};
rt_err_t rt_i2c_driver_register(struct rt_i2c_driver *driver);
rt_err_t rt_i2c_device_register(struct rt_i2c_client *client);
#define RT_I2C_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, i2c, BUILIN)
#endif /* RT_USING_DM */
/**
* @brief I2C Bus Device Initialization
*
* @param bus the I2C bus device
* @param name the name of I2C bus device
*
* @return rt_err_t error code
*/
rt_err_t rt_i2c_bus_device_device_init(struct rt_i2c_bus_device *bus,
const char *name);
/**
* @brief I2C Bus Device Register
*
* @param bus the I2C bus device
* @param bus_name the name of I2C bus device
*
* @return rt_err_t error code
*/
rt_err_t rt_i2c_bus_device_register(struct rt_i2c_bus_device *bus,
const char *bus_name);
/**
* @brief I2C Bus Device Find
*
* @param bus_name the name of I2C bus device
*
* @return rt_i2c_bus_device the I2C bus device
*/
struct rt_i2c_bus_device *rt_i2c_bus_device_find(const char *bus_name);
/**
* @brief I2C data transmission.
*
* @param bus the I2C bus device
* @param msgs the I2C message list
* @param num the number of I2C message
*
* @return rt_ssize_t the actual length of transmitted
*/
rt_ssize_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,
struct rt_i2c_msg msgs[],
rt_uint32_t num);
/**
* @brief I2C Control
*
* @param bus the I2C bus device
* @param cmd the I2C control command
* @param args the I2C control arguments
*
* @return rt_err_t error code
*/
rt_err_t rt_i2c_control(struct rt_i2c_bus_device *bus,
int cmd,
void *args);
/**
* @brief I2C Master Send
*
* @param bus the I2C bus device
* @param addr the I2C slave address
* @param flags the I2C flags
* @param buf the I2C send buffer
* @param count the I2C send buffer length
*
* @return rt_ssize_t the actual length of transmitted
*/
rt_ssize_t rt_i2c_master_send(struct rt_i2c_bus_device *bus,
rt_uint16_t addr,
rt_uint16_t flags,
const rt_uint8_t *buf,
rt_uint32_t count);
/**
* @brief I2C Master Receive
*
* @param bus the I2C bus device
* @param addr the I2C slave address
* @param flags the I2C flags
* @param buf the I2C receive buffer
* @param count the I2C receive buffer length
*
* @return rt_ssize_t the actual length of received
*/
rt_ssize_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus,
rt_uint16_t addr,
rt_uint16_t flags,
rt_uint8_t *buf,
rt_uint32_t count);
rt_inline rt_err_t rt_i2c_bus_lock(struct rt_i2c_bus_device *bus, rt_tick_t timeout)
{
return rt_mutex_take(&bus->lock, timeout);
}
rt_inline rt_err_t rt_i2c_bus_unlock(struct rt_i2c_bus_device *bus)
{
return rt_mutex_release(&bus->lock);
}
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-04-25 weety first version
*/
#ifndef __DEV_I2C_BIT_OPS_H__
#define __DEV_I2C_BIT_OPS_H__
#ifdef __cplusplus
extern "C" {
#endif
struct rt_i2c_bit_ops
{
void *data; /* private data for lowlevel routines */
void (*set_sda)(void *data, rt_int32_t state);
void (*set_scl)(void *data, rt_int32_t state);
rt_int32_t (*get_sda)(void *data);
rt_int32_t (*get_scl)(void *data);
void (*udelay)(rt_uint32_t us);
rt_uint32_t delay_us; /* scl and sda line delay */
rt_uint32_t timeout; /* in tick */
void (*pin_init)(void);
rt_bool_t i2c_pin_init_flag;
};
rt_err_t rt_i2c_bit_add_bus(struct rt_i2c_bus_device *bus,
const char *bus_name);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#ifndef __DEV_I2C_DM_H__
#define __DEV_I2C_DM_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/core/bus.h>
/* I2C Frequency Modes */
#define I2C_MAX_STANDARD_MODE_FREQ 100000
#define I2C_MAX_FAST_MODE_FREQ 400000
#define I2C_MAX_FAST_MODE_PLUS_FREQ 1000000
#define I2C_MAX_TURBO_MODE_FREQ 1400000
#define I2C_MAX_HIGH_SPEED_MODE_FREQ 3400000
#define I2C_MAX_ULTRA_FAST_MODE_FREQ 5000000
struct i2c_timings
{
rt_uint32_t bus_freq_hz; /* the bus frequency in Hz */
rt_uint32_t scl_rise_ns; /* time SCL signal takes to rise in ns; t(r) in the I2C specification */
rt_uint32_t scl_fall_ns; /* time SCL signal takes to fall in ns; t(f) in the I2C specification */
rt_uint32_t scl_int_delay_ns; /* time IP core additionally needs to setup SCL in ns */
rt_uint32_t sda_fall_ns; /* time SDA signal takes to fall in ns; t(f) in the I2C specification */
rt_uint32_t sda_hold_ns; /* time IP core additionally needs to hold SDA in ns */
rt_uint32_t digital_filter_width_ns; /* width in ns of spikes on i2c lines that the IP core digital filter can filter out */
rt_uint32_t analog_filter_cutoff_freq_hz; /* threshold frequency for the low pass IP core analog filter */
};
#ifdef RT_USING_OFW
rt_err_t i2c_timings_ofw_parse(struct rt_ofw_node *dev_np, struct i2c_timings *timings,
rt_bool_t use_defaults);
#else
rt_inline rt_err_t i2c_timings_ofw_parse(struct rt_ofw_node *dev_np, struct i2c_timings *timings,
rt_bool_t use_defaults)
{
return RT_EOK;
}
#endif /* RT_USING_OFW */
void i2c_bus_scan_clients(struct rt_i2c_bus_device *bus);
#endif /* __DEV_I2C_DM_H__ */

View File

@ -0,0 +1,195 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-06-15 hichard first version
* 2024-05-25 HPMicro add strobe support
*/
#ifndef __DEV_MMC_H__
#define __DEV_MMC_H__
#include <rtthread.h>
#include <drivers/mmcsd_host.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* EXT_CSD fields
*/
#define EXT_CSD_FLUSH_CACHE 32 /* W */
#define EXT_CSD_CACHE_CTRL 33 /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */
#define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */
#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
#define EXT_CSD_HPI_MGMT 161 /* R/W */
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_BKOPS_EN 163 /* R/W */
#define EXT_CSD_BKOPS_START 164 /* W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
#define EXT_CSD_RPMB_MULT 168 /* RO */
#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_STROBE_SUPPORT 184 /* RO */
#define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_POWER_CLASS 187 /* R/W */
#define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_STRUCTURE 194 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME 198 /* RO */
#define EXT_CSD_PART_SWITCH_TIME 199 /* RO */
#define EXT_CSD_PWR_CL_52_195 200 /* RO */
#define EXT_CSD_PWR_CL_26_195 201 /* RO */
#define EXT_CSD_PWR_CL_52_360 202 /* RO */
#define EXT_CSD_PWR_CL_26_360 203 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT 217 /* RO */
#define EXT_CSD_REL_WR_SEC_C 222 /* RO */
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT 223 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_TRIM_MULT 229 /* RO */
#define EXT_CSD_SEC_ERASE_MULT 230 /* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT 231 /* RO */
#define EXT_CSD_TRIM_MULT 232 /* RO */
#define EXT_CSD_PWR_CL_200_195 236 /* RO */
#define EXT_CSD_PWR_CL_200_360 237 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
#define EXT_CSD_BKOPS_STATUS 246 /* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */
#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
#define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */
#define EXT_CSD_MAX_PACKED_READS 501 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
#define EXT_CSD_HPI_FEATURES 503 /* RO */
/*
* EXT_CSD field definitions
*/
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_RPMB (0x3)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
#define EXT_CSD_PART_SUPPORT_PART_EN (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
#define EXT_CSD_CARD_TYPE_HS_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_HS_52 (1<<1) /* Card can run at 52MHz */
#define EXT_CSD_CARD_TYPE_HS (EXT_CSD_CARD_TYPE_HS_26 | \
EXT_CSD_CARD_TYPE_HS_52)
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_CARD_TYPE_HS200_1_8V (1<<4) /* Card can run at 200MHz */
#define EXT_CSD_CARD_TYPE_HS200_1_2V (1<<5) /* Card can run at 200MHz */
/* SDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
EXT_CSD_CARD_TYPE_HS200_1_2V)
#define EXT_CSD_CARD_TYPE_HS400_1_8V (1<<6) /* Card can run at 200MHz DDR, 1.8V */
#define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */
#define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \
EXT_CSD_CARD_TYPE_HS400_1_2V)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_DDR_BUS_WIDTH_8_EH_DS 0x86/* Card is in 8 bit DDR mode with Enhanced Data Strobe */
#define EXT_CSD_TIMING_BC 0 /* Backwards compatibility */
#define EXT_CSD_TIMING_HS 1 /* High speed */
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
#define EXT_CSD_TIMING_HS400 3 /* HS400 */
#define EXT_CSD_SEC_ER_EN BIT(0)
#define EXT_CSD_SEC_BD_BLK_EN BIT(2)
#define EXT_CSD_SEC_GB_CL_EN BIT(4)
#define EXT_CSD_SEC_SANITIZE BIT(6) /* v4.5 only */
#define EXT_CSD_RST_N_EN_MASK 0x3
#define EXT_CSD_RST_N_ENABLED 1 /* RST_n is enabled on card */
#define EXT_CSD_NO_POWER_NOTIFICATION 0
#define EXT_CSD_POWER_ON 1
#define EXT_CSD_POWER_OFF_SHORT 2
#define EXT_CSD_POWER_OFF_LONG 3
#define EXT_CSD_PWR_CL_8BIT_MASK 0xF0 /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */
#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
#define EXT_CSD_PACKED_EVENT_EN BIT(3)
/*
* EXCEPTION_EVENT_STATUS field
*/
#define EXT_CSD_URGENT_BKOPS BIT(0)
#define EXT_CSD_DYNCAP_NEEDED BIT(1)
#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
#define EXT_CSD_PACKED_FAILURE BIT(3)
#define EXT_CSD_PACKED_GENERIC_ERROR BIT(0)
#define EXT_CSD_PACKED_INDEXED_ERROR BIT(1)
/*
* BKOPS status level
*/
#define EXT_CSD_BKOPS_LEVEL_2 0x2
/*
* MMC_SWITCH access modes
*/
#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits which are 1 in value */
#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits which are 1 in value */
#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target to value */
/*
* extern function
*/
rt_err_t mmc_send_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *rocr);
rt_int32_t init_mmc(struct rt_mmcsd_host *host, rt_uint32_t ocr);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,260 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-07-25 weety first version
*/
#ifndef __DEV_MMCSD_CORE_H__
#define __DEV_MMCSD_CORE_H__
#include <rtthread.h>
#include <drivers/mmcsd_host.h>
#include <drivers/mmcsd_card.h>
#include <drivers/mmcsd_cmd.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_MMCSD_DBG
#define mmcsd_dbg(fmt, ...) rt_kprintf(fmt, ##__VA_ARGS__)
#else
#define mmcsd_dbg(fmt, ...)
#endif
struct rt_mmcsd_data
{
rt_uint32_t blksize;
rt_uint32_t blks;
rt_uint32_t *buf;
rt_int32_t err;
rt_uint32_t flags;
#define DATA_DIR_WRITE (1 << 0)
#define DATA_DIR_READ (1 << 1)
#define DATA_STREAM (1 << 2)
unsigned int bytes_xfered;
struct rt_mmcsd_cmd *stop; /* stop command */
struct rt_mmcsd_req *mrq; /* associated request */
rt_uint32_t timeout_ns;
rt_uint32_t timeout_clks;
void *sg; /* scatter list */
rt_uint16_t sg_len; /* size of scatter list */
rt_int16_t sg_count; /* mapped sg entries */
rt_ubase_t host_cookie; /* host driver private data */
};
struct rt_mmcsd_cmd
{
rt_uint32_t cmd_code;
rt_uint32_t arg;
rt_uint32_t resp[4];
rt_uint32_t flags;
/*rsponse types
*bits:0~3
*/
#define RESP_MASK (0xF)
#define RESP_NONE (0)
#define RESP_R1 (1 << 0)
#define RESP_R1B (2 << 0)
#define RESP_R2 (3 << 0)
#define RESP_R3 (4 << 0)
#define RESP_R4 (5 << 0)
#define RESP_R6 (6 << 0)
#define RESP_R7 (7 << 0)
#define RESP_R5 (8 << 0) /*SDIO command response type*/
/*command types
*bits:4~5
*/
#define CMD_MASK (3 << 4) /* command type */
#define CMD_AC (0 << 4)
#define CMD_ADTC (1 << 4)
#define CMD_BC (2 << 4)
#define CMD_BCR (3 << 4)
#define resp_type(cmd) ((cmd)->flags & RESP_MASK)
/*spi rsponse types
*bits:6~8
*/
#define RESP_SPI_MASK (0x7 << 6)
#define RESP_SPI_R1 (1 << 6)
#define RESP_SPI_R1B (2 << 6)
#define RESP_SPI_R2 (3 << 6)
#define RESP_SPI_R3 (4 << 6)
#define RESP_SPI_R4 (5 << 6)
#define RESP_SPI_R5 (6 << 6)
#define RESP_SPI_R7 (7 << 6)
#define spi_resp_type(cmd) ((cmd)->flags & RESP_SPI_MASK)
/*
* These are the command types.
*/
#define cmd_type(cmd) ((cmd)->flags & CMD_MASK)
rt_int32_t retries; /* max number of retries */
rt_int32_t err;
unsigned int busy_timeout; /* busy detect timeout in ms */
struct rt_mmcsd_data *data;
struct rt_mmcsd_req *mrq; /* associated request */
};
struct rt_mmcsd_req
{
struct rt_mmcsd_data *data;
struct rt_mmcsd_cmd *cmd;
struct rt_mmcsd_cmd *stop;
struct rt_mmcsd_cmd *sbc; /* SET_BLOCK_COUNT for multiblock */
/* Allow other commands during this ongoing data transfer or busy wait */
int cap_cmd_during_tfr;
};
/*the following is response bit*/
#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
#define R1_ERASE_PARAM (1 << 27) /* ex, c */
#define R1_WP_VIOLATION (1 << 26) /* erx, c */
#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
#define R1_CC_ERROR (1 << 20) /* erx, c */
#define R1_ERROR (1 << 19) /* erx, c */
#define R1_UNDERRUN (1 << 18) /* ex, c */
#define R1_OVERRUN (1 << 17) /* ex, c */
#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
#define R1_ERASE_RESET (1 << 13) /* sr, c */
#define R1_STATUS(x) (x & 0xFFFFE000)
#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
#define R1_APP_CMD (1 << 5) /* sr, c */
#define R1_SPI_IDLE (1 << 0)
#define R1_SPI_ERASE_RESET (1 << 1)
#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
#define R1_SPI_COM_CRC (1 << 3)
#define R1_SPI_ERASE_SEQ (1 << 4)
#define R1_SPI_ADDRESS (1 << 5)
#define R1_SPI_PARAMETER (1 << 6)
/* R1 bit 7 is always zero */
#define R2_SPI_CARD_LOCKED (1 << 8)
#define R2_SPI_WP_ERASE_SKIP (1 << 9) /* or lock/unlock fail */
#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP
#define R2_SPI_ERROR (1 << 10)
#define R2_SPI_CC_ERROR (1 << 11)
#define R2_SPI_CARD_ECC_ERROR (1 << 12)
#define R2_SPI_WP_VIOLATION (1 << 13)
#define R2_SPI_ERASE_PARAM (1 << 14)
#define R2_SPI_OUT_OF_RANGE (1 << 15) /* or CSD overwrite */
#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE
#define CARD_BUSY 0x80000000 /* Card Power up status bit */
/* R5 response bits */
#define R5_COM_CRC_ERROR (1 << 15)
#define R5_ILLEGAL_COMMAND (1 << 14)
#define R5_ERROR (1 << 11)
#define R5_FUNCTION_NUMBER (1 << 9)
#define R5_OUT_OF_RANGE (1 << 8)
#define R5_STATUS(x) (x & 0xCB00)
#define R5_IO_CURRENT_STATE(x) ((x & 0x3000) >> 12)
/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
rt_inline rt_uint32_t __rt_fls(rt_uint32_t val)
{
rt_uint32_t bit = 32;
if (!val)
return 0;
if (!(val & 0xffff0000u))
{
val <<= 16;
bit -= 16;
}
if (!(val & 0xff000000u))
{
val <<= 8;
bit -= 8;
}
if (!(val & 0xf0000000u))
{
val <<= 4;
bit -= 4;
}
if (!(val & 0xc0000000u))
{
val <<= 2;
bit -= 2;
}
if (!(val & 0x80000000u))
{
bit -= 1;
}
return bit;
}
#define MMCSD_HOST_PLUGED 0
#define MMCSD_HOST_UNPLUGED 1
rt_int32_t mmcsd_excute_tuning(struct rt_mmcsd_card *card);
int mmcsd_wait_cd_changed(rt_int32_t timeout);
void mmcsd_host_lock(struct rt_mmcsd_host *host);
void mmcsd_host_unlock(struct rt_mmcsd_host *host);
void mmcsd_req_complete(struct rt_mmcsd_host *host);
void mmcsd_send_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
rt_int32_t mmcsd_send_cmd(struct rt_mmcsd_host *host, struct rt_mmcsd_cmd *cmd, int retries);
rt_int32_t mmcsd_go_idle(struct rt_mmcsd_host *host);
rt_int32_t mmcsd_spi_read_ocr(struct rt_mmcsd_host *host, rt_int32_t high_capacity, rt_uint32_t *ocr);
rt_int32_t mmcsd_all_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid);
rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid);
rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd);
rt_int32_t mmcsd_select_card(struct rt_mmcsd_card *card);
rt_int32_t mmcsd_deselect_cards(struct rt_mmcsd_card *host);
rt_int32_t mmcsd_spi_use_crc(struct rt_mmcsd_host *host, rt_int32_t use_crc);
void mmcsd_set_chip_select(struct rt_mmcsd_host *host, rt_int32_t mode);
void mmcsd_set_clock(struct rt_mmcsd_host *host, rt_uint32_t clk);
void mmcsd_set_bus_mode(struct rt_mmcsd_host *host, rt_uint32_t mode);
void mmcsd_set_bus_width(struct rt_mmcsd_host *host, rt_uint32_t width);
void mmcsd_set_timing(struct rt_mmcsd_host *host, rt_uint32_t timing);
void mmcsd_set_data_timeout(struct rt_mmcsd_data *data, const struct rt_mmcsd_card *card);
rt_uint32_t mmcsd_select_voltage(struct rt_mmcsd_host *host, rt_uint32_t ocr);
void mmcsd_change(struct rt_mmcsd_host *host);
void mmcsd_detect(void *param);
void mmcsd_host_init(struct rt_mmcsd_host *host);
struct rt_mmcsd_host *mmcsd_alloc_host(void);
void mmcsd_free_host(struct rt_mmcsd_host *host);
int rt_mmcsd_core_init(void);
rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card);
void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,328 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015-01-20 Bernard the first version
* 2017-10-20 ZYH add mode open drain and input pull down
*/
#ifndef DEV_PIN_H__
#define DEV_PIN_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_Pin Pin
*
* @brief Pin driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include <rtdevice.h>
*
*
* #ifndef BEEP_PIN_NUM
* #define BEEP_PIN_NUM 35 // PB0
* #endif
* #ifndef KEY0_PIN_NUM
* #define KEY0_PIN_NUM 55 // PD8
* #endif
* #ifndef KEY1_PIN_NUM
* #define KEY1_PIN_NUM 56 // PD9
* #endif
*
* void beep_on(void *args)
* {
* rt_kprintf("turn on beep!\n");
*
* rt_pin_write(BEEP_PIN_NUM, PIN_HIGH);
* }
*
* void beep_off(void *args)
* {
* rt_kprintf("turn off beep!\n");
*
* rt_pin_write(BEEP_PIN_NUM, PIN_LOW);
* }
*
* static void pin_beep_sample(void)
* {
* rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
* rt_pin_write(BEEP_PIN_NUM, PIN_LOW);
*
* rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);
* rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
* rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);
*
*
* rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP);
* rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL);
* rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE);
* }
*
* MSH_CMD_EXPORT(pin_beep_sample, pin beep sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_Pin
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_DM
#include <drivers/pic.h>
struct rt_pin_irqchip
{
struct rt_pic parent;
int irq;
rt_base_t pin_range[2];
};
struct rt_pin_irq_hdr;
#endif /* RT_USING_DM */
/**
* @brief pin device structure
*/
struct rt_device_pin
{
struct rt_device parent;
#ifdef RT_USING_DM
/* MUST keep the order member after parent */
struct rt_pin_irqchip irqchip;
/* Fill by DM */
rt_base_t pin_start;
rt_size_t pin_nr;
rt_list_t list;
struct rt_pin_irq_hdr *legacy_isr;
#endif /* RT_USING_DM */
const struct rt_pin_ops *ops;
};
#define PIN_NONE (-RT_EEMPTY)
#define PIN_LOW 0x00 /*!< low level */
#define PIN_HIGH 0x01 /*!< high level */
#define PIN_MODE_OUTPUT 0x00 /*!< output mode */
#define PIN_MODE_INPUT 0x01 /*!< input mode */
#define PIN_MODE_INPUT_PULLUP 0x02 /*!< input mode with pull-up */
#define PIN_MODE_INPUT_PULLDOWN 0x03 /*!< input mode with pull-down */
#define PIN_MODE_OUTPUT_OD 0x04 /*!< output mode with open-drain */
#ifdef RT_USING_PINCTRL
enum
{
PIN_CONFIG_BIAS_BUS_HOLD,
PIN_CONFIG_BIAS_DISABLE,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_BIAS_PULL_PIN_DEFAULT,
PIN_CONFIG_BIAS_PULL_UP,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
PIN_CONFIG_DRIVE_PUSH_PULL,
PIN_CONFIG_DRIVE_STRENGTH,
PIN_CONFIG_DRIVE_STRENGTH_UA,
PIN_CONFIG_INPUT_DEBOUNCE,
PIN_CONFIG_INPUT_ENABLE,
PIN_CONFIG_INPUT_SCHMITT,
PIN_CONFIG_INPUT_SCHMITT_ENABLE,
PIN_CONFIG_MODE_LOW_POWER,
PIN_CONFIG_MODE_PWM,
PIN_CONFIG_OUTPUT,
PIN_CONFIG_OUTPUT_ENABLE,
PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS,
PIN_CONFIG_PERSIST_STATE,
PIN_CONFIG_POWER_SOURCE,
PIN_CONFIG_SKEW_DELAY,
PIN_CONFIG_SLEEP_HARDWARE_STATE,
PIN_CONFIG_SLEW_RATE,
PIN_CONFIG_END = 0x7f,
PIN_CONFIG_MAX = 0xff,
};
#endif /* RT_USING_PINCTRL */
#define PIN_IRQ_MODE_RISING 0x00 /*!< rising edge trigger */
#define PIN_IRQ_MODE_FALLING 0x01 /*!< falling edge trigger */
#define PIN_IRQ_MODE_RISING_FALLING 0x02 /*!< rising and falling edge trigger */
#define PIN_IRQ_MODE_HIGH_LEVEL 0x03 /*!< high level trigger */
#define PIN_IRQ_MODE_LOW_LEVEL 0x04 /*!< low level trigger */
#define PIN_IRQ_DISABLE 0x00 /*!< disable irq */
#define PIN_IRQ_ENABLE 0x01 /*!< enable irq */
#define PIN_IRQ_PIN_NONE PIN_NONE /*!< no pin irq */
/**
* @brief pin mode structure
*/
struct rt_device_pin_mode
{
rt_base_t pin;
rt_uint8_t mode; /* e.g. PIN_MODE_OUTPUT */
};
/**
* @brief pin value structure
*/
struct rt_device_pin_value
{
rt_base_t pin;
rt_uint8_t value; /* PIN_LOW or PIN_HIGH */
};
/**
* @brief pin irq structure
*/
struct rt_pin_irq_hdr
{
rt_base_t pin;
rt_uint8_t mode; /* e.g. PIN_IRQ_MODE_RISING */
void (*hdr)(void *args);
void *args;
};
#ifdef RT_USING_PINCTRL
/**
* @brief pin control configure structure
*/
struct rt_pin_ctrl_conf_params
{
const char *propname;
rt_uint32_t param;
rt_uint32_t default_value;
};
#endif /* RT_USING_PINCTRL */
/**
* @brief pin device operations
*/
struct rt_pin_ops
{
void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode);
void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_uint8_t value);
rt_ssize_t (*pin_read)(struct rt_device *device, rt_base_t pin);
rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_base_t pin,
rt_uint8_t mode, void (*hdr)(void *args), void *args);
rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_base_t pin);
rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled);
rt_base_t (*pin_get)(const char *name);
rt_err_t (*pin_debounce)(struct rt_device *device, rt_base_t pin, rt_uint32_t debounce);
#ifdef RT_USING_DM
rt_err_t (*pin_irq_mode)(struct rt_device *device, rt_base_t pin, rt_uint8_t mode);
rt_ssize_t (*pin_parse)(struct rt_device *device, struct rt_ofw_cell_args *args, rt_uint32_t *flags);
#endif
#ifdef RT_USING_PINCTRL
rt_err_t (*pin_ctrl_confs_apply)(struct rt_device *device, void *fw_conf_np);
#endif /* RT_USING_PINCTRL */
};
/**
* @brief register a pin device
* @param name the name of pin device
* @param ops the operations of pin device
* @param user_data the user data of pin device
* @return int error code
*/
int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
/**
* @brief set pin mode
* @param pin the pin number
* @param mode the pin mode
*/
void rt_pin_mode(rt_base_t pin, rt_uint8_t mode);
/**
* @brief write pin value
* @param pin the pin number
* @param value the pin value
*/
void rt_pin_write(rt_base_t pin, rt_ssize_t value);
/**
* @brief read pin value
* @param pin the pin number
* @return rt_ssize_t the pin value
*/
rt_ssize_t rt_pin_read(rt_base_t pin);
/**
* @brief get pin number by name
* @param name the pin name
* @return rt_base_t the pin number
*/
rt_base_t rt_pin_get(const char *name);
/**
* @brief bind the pin interrupt callback function
* @param pin the pin number
* @param mode the irq mode
* @param hdr the irq callback function
* @param args the argument of the callback function
* @return rt_err_t error code
*/
rt_err_t rt_pin_attach_irq(rt_base_t pin, rt_uint8_t mode,
void (*hdr)(void *args), void *args);
/**
* @brief detach the pin interrupt callback function
* @param pin the pin number
* @return rt_err_t error code
*/
rt_err_t rt_pin_detach_irq(rt_base_t pin);
/**
* @brief enable or disable the pin interrupt
* @param pin the pin number
* @param enabled PIN_IRQ_ENABLE or PIN_IRQ_DISABLE
* @return rt_err_t error code
*/
rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint8_t enabled);
/**
* @brief set the pin's debounce time
* @param pin the pin number
* @param debounce time
* @return rt_err_t error code
*/
rt_err_t rt_pin_debounce(rt_base_t pin, rt_uint32_t debounce);
#ifdef RT_USING_DM
rt_ssize_t rt_pin_get_named_pin(struct rt_device *dev, const char *propname, int index,
rt_uint8_t *out_mode, rt_uint8_t *out_value);
rt_ssize_t rt_pin_get_named_pin_count(struct rt_device *dev, const char *propname);
#ifdef RT_USING_OFW
rt_ssize_t rt_ofw_get_named_pin(struct rt_ofw_node *np, const char *propname, int index,
rt_uint8_t *out_mode, rt_uint8_t *out_value);
rt_ssize_t rt_ofw_get_named_pin_count(struct rt_ofw_node *np, const char *propname);
#endif
#endif /* RT_USING_DM */
#ifdef RT_USING_PINCTRL
rt_ssize_t rt_pin_ctrl_confs_lookup(struct rt_device *device, const char *name);
rt_err_t rt_pin_ctrl_confs_apply(struct rt_device *device, int index);
rt_err_t rt_pin_ctrl_confs_apply_by_name(struct rt_device *device, const char *name);
#endif /* RT_USING_PINCTRL */
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,209 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-05-07 aozima the first version
* 2022-09-24 yuqi add phase and dead time configuration
*/
#ifndef __DEV_PWM_H__
#define __DEV_PWM_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_PWM PWM
*
* @brief PWM driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include <rtdevice.h>
*
* #define PWM_DEV_NAME "pwm3" // PWM设备名称
* #define PWM_DEV_CHANNEL 4 // PWM通道
*
* struct rt_device_pwm *pwm_dev; // PWM设备句柄
*
* static int pwm_led_sample(int argc, char *argv[])
* {
* rt_uint32_t period, pulse, dir;
*
* period = 500000; // 周期为0.5ms单位为纳秒ns
* dir = 1; // PWM脉冲宽度值的增减方向
* pulse = 0; // PWM脉冲宽度值单位为纳秒ns
*
* // 查找设备
* pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
* if (pwm_dev == RT_NULL)
* {
* rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
* return -RT_ERROR;
* }
*
* // 设置PWM周期和脉冲宽度默认值
* rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
* // 使能设备
* rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
*
* while (1)
* {
* rt_thread_mdelay(50);
* if (dir)
* {
* pulse += 5000; // 从0值开始每次增加5000ns
* }
* else
* {
* pulse -= 5000; // 从最大值开始每次减少5000ns
* }
* if (pulse >= period)
* {
* dir = 0;
* }
* if (0 == pulse)
* {
* dir = 1;
* }
*
* // 设置PWM周期和脉冲宽度
* rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
* }
* }
*
* MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_PWM
* @{
*/
#define PWM_CMD_ENABLE (RT_DEVICE_CTRL_BASE(PWM) + 0)
#define PWM_CMD_DISABLE (RT_DEVICE_CTRL_BASE(PWM) + 1)
#define PWM_CMD_SET (RT_DEVICE_CTRL_BASE(PWM) + 2)
#define PWM_CMD_GET (RT_DEVICE_CTRL_BASE(PWM) + 3)
#define PWMN_CMD_ENABLE (RT_DEVICE_CTRL_BASE(PWM) + 4)
#define PWMN_CMD_DISABLE (RT_DEVICE_CTRL_BASE(PWM) + 5)
#define PWM_CMD_SET_PERIOD (RT_DEVICE_CTRL_BASE(PWM) + 6)
#define PWM_CMD_SET_PULSE (RT_DEVICE_CTRL_BASE(PWM) + 7)
#define PWM_CMD_SET_DEAD_TIME (RT_DEVICE_CTRL_BASE(PWM) + 8)
#define PWM_CMD_SET_PHASE (RT_DEVICE_CTRL_BASE(PWM) + 9)
#define PWM_CMD_ENABLE_IRQ (RT_DEVICE_CTRL_BASE(PWM) + 10)
#define PWM_CMD_DISABLE_IRQ (RT_DEVICE_CTRL_BASE(PWM) + 11)
/**
* @brief PWM configuration
*/
struct rt_pwm_configuration
{
rt_uint32_t channel; /* 0 ~ n or 0 ~ -n, which depends on specific MCU requirements */
rt_uint32_t period; /* unit:ns 1ns~4.29s:1Ghz~0.23hz */
rt_uint32_t pulse; /* unit:ns (pulse<=period) */
rt_uint32_t dead_time; /* unit:ns */
rt_uint32_t phase; /*unit: degree, 0~360, which is the phase of pwm output, */
/*
* RT_TRUE : The channel of pwm is complememtary.
* RT_FALSE : The channel of pwm is nomal.
*/
rt_bool_t complementary;
};
struct rt_device_pwm;
/**
* @brief PWM operations
*/
struct rt_pwm_ops
{
rt_err_t (*control)(struct rt_device_pwm *device, int cmd, void *arg);
};
/**
* @brief PWM device
*/
struct rt_device_pwm
{
struct rt_device parent;
const struct rt_pwm_ops *ops;
};
/**
* @brief register a PWM device
* @param device the PWM device
* @param name the name of PWM device
* @param ops the operations of PWM device
* @param user_data the user data of PWM device
* @return rt_err_t error code
*/
rt_err_t rt_device_pwm_register(struct rt_device_pwm *device, const char *name, const struct rt_pwm_ops *ops, const void *user_data);
/**
* @brief enable the PWM channel
* @param device the PWM device
* @param channel the channel of PWM
* @return rt_err_t error code
*/
rt_err_t rt_pwm_enable(struct rt_device_pwm *device, int channel);
/**
* @brief disable the PWM channel
* @param device the PWM device
* @param channel the channel of PWM
* @return rt_err_t error code
*/
rt_err_t rt_pwm_disable(struct rt_device_pwm *device, int channel);
/**
* @brief set the PWM channel
* @param device the PWM device
* @param channel the channel of PWM
* @param period the period of PWM
* @param pulse the pulse of PWM
* @return rt_err_t error code
*/
rt_err_t rt_pwm_set(struct rt_device_pwm *device, int channel, rt_uint32_t period, rt_uint32_t pulse);
/**
* @brief set the PWM channel period
* @param device the PWM device
* @param channel the channel of PWM
* @param period the period of PWM
* @return rt_err_t error code
*/
rt_err_t rt_pwm_set_period(struct rt_device_pwm *device, int channel, rt_uint32_t period);
/**
* @brief set the PWM channel pulse
* @param device the PWM device
* @param channel the channel of PWM
* @param pulse the period of PWM
* @return rt_err_t error code
*/
rt_err_t rt_pwm_set_pulse(struct rt_device_pwm *device, int channel, rt_uint32_t pulse);
/**
* @brief set the dead zone time of PWM
* @param device the PWM device
* @param channel the channel of PWM
* @param dead_time dead zone time
* @return rt_err_t error code
*/
rt_err_t rt_pwm_set_dead_time(struct rt_device_pwm *device, int channel, rt_uint32_t dead_time);
/**
* @brief set the phase of PWM
* @param device the PWM device
* @param channel the channel of PWM
* @param phase phase
* @return rt_err_t error code
*/
rt_err_t rt_pwm_set_phase(struct rt_device_pwm *device, int channel, rt_uint32_t phase);
/*! @}*/
#endif /* __DEV_PWM_H__ */

View File

@ -0,0 +1,194 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-10-10 aozima first version.
* 2021-06-11 iysheng implement RTC framework V2.0
* 2021-07-30 Meco Man move rtc_core.h to rtc.h
* 2022-04-05 tyx add timestamp function
*/
#ifndef __DEV_RTC_H__
#define __DEV_RTC_H__
#include <rtdef.h>
#include <sys/time.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_RTC RTC
*
* @brief RTC driver api
*
* <b>Example</b>
* @code {.c}
*
* #include <rtthread.h>
* #include <rtdevice.h>
*
* #define RTC_NAME "rtc"
*
* static int rtc_sample(int argc, char *argv[])
* {
* rt_err_t ret = RT_EOK;
* time_t now;
* rt_device_t device = RT_NULL;
*
* device = rt_device_find(RTC_NAME);
* if (!device)
* {
* LOG_E("find %s failed!", RTC_NAME);
* return -RT_ERROR;
* }
*
* if(rt_device_open(device, 0) != RT_EOK)
* {
* LOG_E("open %s failed!", RTC_NAME);
* return -RT_ERROR;
* }
*
* ret = set_date(2018, 12, 3);
* if (ret != RT_EOK)
* {
* rt_kprintf("set RTC date failed\n");
* return ret;
* }
*
* ret = set_time(11, 15, 50);
* if (ret != RT_EOK)
* {
* rt_kprintf("set RTC time failed\n");
* return ret;
* }
*
* rt_thread_mdelay(3000);
*
* now = time(RT_NULL);
* rt_kprintf("%s\n", ctime(&now));
*
* return ret;
* }
* MSH_CMD_EXPORT(rtc_sample, rtc sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_RTC
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#define RT_DEVICE_CTRL_RTC_GET_TIME (RT_DEVICE_CTRL_BASE(RTC) + 0x01) /**< get second time */
#define RT_DEVICE_CTRL_RTC_SET_TIME (RT_DEVICE_CTRL_BASE(RTC) + 0x02) /**< set second time */
#define RT_DEVICE_CTRL_RTC_GET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x03) /**< get timeval for gettimeofday */
#define RT_DEVICE_CTRL_RTC_SET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x04) /**< set timeval for gettimeofday */
#define RT_DEVICE_CTRL_RTC_GET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x05) /**< get alarm */
#define RT_DEVICE_CTRL_RTC_SET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x06) /**< set alarm */
#define RT_DEVICE_CTRL_RTC_GET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x07) /**< get timespec for clock_gettime */
#define RT_DEVICE_CTRL_RTC_SET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x08) /**< set timespec for clock_settime */
#define RT_DEVICE_CTRL_RTC_GET_TIMERES (RT_DEVICE_CTRL_BASE(RTC) + 0x09) /**< get resolution for clock_getres */
/**
* @brief RTC alarm structure
*/
struct rt_rtc_wkalarm
{
rt_bool_t enable; /* 0 = alarm disabled, 1 = alarm enabled */
rt_int32_t tm_sec; /* alarm at tm_sec */
rt_int32_t tm_min; /* alarm at tm_min */
rt_int32_t tm_hour; /* alarm at tm_hour */
rt_int32_t tm_mday; /* alarm at tm_mday */
rt_int32_t tm_mon; /* alarm at tm_mon */
rt_int32_t tm_year; /* alarm at tm_year */
};
/**
* @brief RTC operations
*/
struct rt_rtc_ops
{
rt_err_t (*init)(void);
rt_err_t (*get_secs)(time_t *sec);
rt_err_t (*set_secs)(time_t *sec);
rt_err_t (*get_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*set_alarm)(struct rt_rtc_wkalarm *alarm);
rt_err_t (*get_timeval)(struct timeval *tv);
rt_err_t (*set_timeval)(struct timeval *tv);
};
/**
* @brief RTC device structure
*/
typedef struct rt_rtc_device
{
struct rt_device parent;
const struct rt_rtc_ops *ops;
} rt_rtc_dev_t;
/**
* @brief Register a RTC device
*
* @param rtc RTC device
* @param name RTC device name
* @param flag RTC device flag
* @param data RTC device data
* @return rt_err_t error code
*/
rt_err_t rt_hw_rtc_register(rt_rtc_dev_t *rtc,
const char *name,
rt_uint32_t flag,
void *data);
/**
* @brief set date
*
* @param year year
* @param month month
* @param day day
* @return rt_err_t error code
*/
rt_err_t set_date(rt_uint32_t year, rt_uint32_t month, rt_uint32_t day);
/**
* @brief set time
*
* @param hour hour
* @param minute minute
* @param second second
* @return rt_err_t error code
*/
rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second);
/**
* @brief set timestamp
*
* @param timestamp A pointer to time
* @return rt_err_t error code
*/
rt_err_t set_timestamp(time_t timestamp);
/**
* @brief get timestamp
*
* @param timestamp A secondary pointer to time
* @return rt_err_t error code
*/
rt_err_t get_timestamp(time_t *timestamp);
#ifdef RT_USING_SYSTEM_WORKQUEUE
rt_err_t rt_soft_rtc_sync(void);
rt_err_t rt_soft_rtc_set_source(const char *name);
#endif
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* __DEV_RTC_H__ */

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-07-25 weety first version
* 2024-05-26 HPMicro Add UHS-I support
*/
#ifndef __DEV_SD_H__
#define __DEV_SD_H__
#include <rtthread.h>
#include <drivers/mmcsd_host.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* SWITCH_FUNC timing
*/
#define SD_SWITCH_FUNC_TIMING_DEFAULT 0
#define SD_SWITCH_FUNC_TIMING_HS 1
#define SD_SWITCH_FUNC_TIMING_SDR50 2
#define SD_SWITCH_FUNC_TIMING_SDR104 3
#define SD_SWITCH_FUNC_TIMING_DDR50 4
rt_err_t mmcsd_send_if_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr);
rt_err_t mmcsd_send_app_op_cond(struct rt_mmcsd_host *host, rt_uint32_t ocr, rt_uint32_t *rocr);
rt_err_t mmcsd_get_card_addr(struct rt_mmcsd_host *host, rt_uint32_t *rca);
rt_int32_t mmcsd_get_scr(struct rt_mmcsd_card *card, rt_uint32_t *scr);
rt_int32_t init_sd(struct rt_mmcsd_host *host, rt_uint32_t ocr);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,231 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-01-15 weety first version
*/
#ifndef __DEV_SDIO_H__
#define __DEV_SDIO_H__
#include <rtthread.h>
#include <drivers/mmcsd_host.h>
#include <drivers/mmcsd_card.h>
#include <drivers/sdio_func_ids.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* Card Common Control Registers (CCCR)
*/
#define SDIO_REG_CCCR_CCCR_REV 0x00
#define SDIO_CCCR_REV_1_00 0 /* CCCR/FBR Version 1.00 */
#define SDIO_CCCR_REV_1_10 1 /* CCCR/FBR Version 1.10 */
#define SDIO_CCCR_REV_1_20 2 /* CCCR/FBR Version 1.20 */
#define SDIO_CCCR_REV_3_00 3 /* CCCR/FBR Version 2.00 */
#define SDIO_SDIO_REV_1_00 0 /* SDIO Spec Version 1.00 */
#define SDIO_SDIO_REV_1_10 1 /* SDIO Spec Version 1.10 */
#define SDIO_SDIO_REV_1_20 2 /* SDIO Spec Version 1.20 */
#define SDIO_SDIO_REV_2_00 3 /* SDIO Spec Version 2.00 */
#define SDIO_REG_CCCR_SD_REV 0x01
#define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */
#define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */
#define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */
#define SDIO_REG_CCCR_IO_EN 0x02
#define SDIO_REG_CCCR_IO_RDY 0x03
#define SDIO_REG_CCCR_INT_EN 0x04 /* Function/Master Interrupt Enable */
#define SDIO_REG_CCCR_INT_PEND 0x05 /* Function Interrupt Pending */
#define SDIO_REG_CCCR_IO_ABORT 0x06 /* function abort/card reset */
#define SDIO_REG_CCCR_BUS_IF 0x07 /* bus interface controls */
#define SDIO_BUS_WIDTH_1BIT 0x00
#define SDIO_BUS_WIDTH_4BIT 0x02
#define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */
#define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */
#define SDIO_BUS_ASYNC_INT 0x20
#define SDIO_BUS_CD_DISABLE 0x80 /* disable pull-up on DAT3 (pin 1) */
#define SDIO_REG_CCCR_CARD_CAPS 0x08
#define SDIO_CCCR_CAP_SDC 0x01 /* can do CMD52 while data transfer */
#define SDIO_CCCR_CAP_SMB 0x02 /* can do multi-block xfers (CMD53) */
#define SDIO_CCCR_CAP_SRW 0x04 /* supports read-wait protocol */
#define SDIO_CCCR_CAP_SBS 0x08 /* supports suspend/resume */
#define SDIO_CCCR_CAP_S4MI 0x10 /* interrupt during 4-bit CMD53 */
#define SDIO_CCCR_CAP_E4MI 0x20 /* enable ints during 4-bit CMD53 */
#define SDIO_CCCR_CAP_LSC 0x40 /* low speed card */
#define SDIO_CCCR_CAP_4BLS 0x80 /* 4 bit low speed card */
#define SDIO_REG_CCCR_CIS_PTR 0x09 /* common CIS pointer (3 bytes) */
/* Following 4 regs are valid only if SBS is set */
#define SDIO_REG_CCCR_BUS_SUSPEND 0x0c
#define SDIO_REG_CCCR_FUNC_SEL 0x0d
#define SDIO_REG_CCCR_EXEC_FLAG 0x0e
#define SDIO_REG_CCCR_READY_FLAG 0x0f
#define SDIO_REG_CCCR_FN0_BLKSIZE 0x10 /* 2bytes, 0x10~0x11 */
#define SDIO_REG_CCCR_POWER_CTRL 0x12
#define SDIO_POWER_SMPC 0x01 /* Supports Master Power Control */
#define SDIO_POWER_EMPC 0x02 /* Enable Master Power Control */
#define SDIO_REG_CCCR_SPEED 0x13
#define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */
#define SDIO_SPEED_EHS 0x02 /* Enable High-Speed mode */
/*
* Function Basic Registers (FBR)
*/
#define SDIO_REG_FBR_BASE(f) ((f) * 0x100) /* base of function f's FBRs */
#define SDIO_REG_FBR_STD_FUNC_IF 0x00
#define SDIO_FBR_SUPPORTS_CSA 0x40 /* supports Code Storage Area */
#define SDIO_FBR_ENABLE_CSA 0x80 /* enable Code Storage Area */
#define SDIO_REG_FBR_STD_IF_EXT 0x01
#define SDIO_REG_FBR_POWER 0x02
#define SDIO_FBR_POWER_SPS 0x01 /* Supports Power Selection */
#define SDIO_FBR_POWER_EPS 0x02 /* Enable (low) Power Selection */
#define SDIO_REG_FBR_CIS 0x09 /* CIS pointer (3 bytes) */
#define SDIO_REG_FBR_CSA 0x0C /* CSA pointer (3 bytes) */
#define SDIO_REG_FBR_CSA_DATA 0x0F
#define SDIO_REG_FBR_BLKSIZE 0x10 /* block size (2 bytes) */
/* SDIO CIS Tuple code */
#define CISTPL_NULL 0x00
#define CISTPL_CHECKSUM 0x10
#define CISTPL_VERS_1 0x15
#define CISTPL_ALTSTR 0x16
#define CISTPL_MANFID 0x20
#define CISTPL_FUNCID 0x21
#define CISTPL_FUNCE 0x22
#define CISTPL_SDIO_STD 0x91
#define CISTPL_SDIO_EXT 0x92
#define CISTPL_END 0xff
/* SDIO device id */
#define SDIO_ANY_FUNC_ID 0xff
#define SDIO_ANY_MAN_ID 0xffff
#define SDIO_ANY_PROD_ID 0xffff
struct rt_sdio_device_id
{
rt_uint8_t func_code;
rt_uint16_t manufacturer;
rt_uint16_t product;
};
struct rt_sdio_driver
{
char *name;
rt_int32_t (*probe)(struct rt_mmcsd_card *card);
rt_int32_t (*remove)(struct rt_mmcsd_card *card);
struct rt_sdio_device_id *id;
};
rt_int32_t sdio_io_send_op_cond(struct rt_mmcsd_host *host,
rt_uint32_t ocr,
rt_uint32_t *cmd5_resp);
rt_int32_t sdio_io_rw_direct(struct rt_mmcsd_card *card,
rt_int32_t rw,
rt_uint32_t fn,
rt_uint32_t reg_addr,
rt_uint8_t *pdata,
rt_uint8_t raw);
rt_int32_t sdio_io_rw_extended(struct rt_mmcsd_card *card,
rt_int32_t rw,
rt_uint32_t fn,
rt_uint32_t addr,
rt_int32_t op_code,
rt_uint8_t *buf,
rt_uint32_t blocks,
rt_uint32_t blksize);
rt_int32_t sdio_io_rw_extended_block(struct rt_sdio_function *func,
rt_int32_t rw,
rt_uint32_t addr,
rt_int32_t op_code,
rt_uint8_t *buf,
rt_uint32_t len);
rt_uint8_t sdio_io_readb(struct rt_sdio_function *func,
rt_uint32_t reg,
rt_int32_t *err);
rt_int32_t sdio_io_writeb(struct rt_sdio_function *func,
rt_uint32_t reg,
rt_uint8_t data);
rt_uint16_t sdio_io_readw(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_int32_t *err);
rt_int32_t sdio_io_writew(struct rt_sdio_function *func,
rt_uint16_t data,
rt_uint32_t addr);
rt_uint32_t sdio_io_readl(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_int32_t *err);
rt_int32_t sdio_io_writel(struct rt_sdio_function *func,
rt_uint32_t data,
rt_uint32_t addr);
rt_int32_t sdio_io_read_multi_fifo_b(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_uint8_t *buf,
rt_uint32_t len);
rt_int32_t sdio_io_write_multi_fifo_b(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_uint8_t *buf,
rt_uint32_t len);
rt_int32_t sdio_io_read_multi_incr_b(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_uint8_t *buf,
rt_uint32_t len);
rt_int32_t sdio_io_write_multi_incr_b(struct rt_sdio_function *func,
rt_uint32_t addr,
rt_uint8_t *buf,
rt_uint32_t len);
rt_int32_t init_sdio(struct rt_mmcsd_host *host, rt_uint32_t ocr);
rt_int32_t sdio_attach_irq(struct rt_sdio_function *func,
rt_sdio_irq_handler_t *handler);
rt_int32_t sdio_detach_irq(struct rt_sdio_function *func);
void sdio_irq_wakeup(struct rt_mmcsd_host *host);
rt_int32_t sdio_enable_func(struct rt_sdio_function *func);
rt_int32_t sdio_disable_func(struct rt_sdio_function *func);
void sdio_set_drvdata(struct rt_sdio_function *func, void *data);
void* sdio_get_drvdata(struct rt_sdio_function *func);
rt_int32_t sdio_set_block_size(struct rt_sdio_function *func,
rt_uint32_t blksize);
rt_int32_t sdio_register_driver(struct rt_sdio_driver *driver);
rt_int32_t sdio_unregister_driver(struct rt_sdio_driver *driver);
void rt_sdio_init(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,325 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-05-15 lgnq first version.
* 2012-05-28 bernard change interfaces
* 2013-02-20 bernard use RT_SERIAL_RB_BUFSZ to define
* the size of ring buffer.
*/
#ifndef __DEV_SERIAL_H__
#define __DEV_SERIAL_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_Serial Serial
*
* @brief Serial driver api
*
* <b>Example</b>
* @code {.c}
*
* #include <rtthread.h>
*
* #define SAMPLE_UART_NAME "uart2"
* static struct rt_semaphore rx_sem;
* static rt_device_t serial;
*
* static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
* {
*
* rt_sem_release(&rx_sem);
*
* return RT_EOK;
* }
*
* static void serial_thread_entry(void *parameter)
* {
* char ch;
*
* while (1)
* {
*
* while (rt_device_read(serial, -1, &ch, 1) != 1)
* {
*
* rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
* }
*
* ch = ch + 1;
* rt_device_write(serial, 0, &ch, 1);
* }
* }
*
* static int uart_sample(int argc, char *argv[])
* {
* rt_err_t ret = RT_EOK;
* char uart_name[RT_NAME_MAX];
* char str[] = "hello RT-Thread!\r\n";
*
* if (argc == 2)
* {
* rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
* }
* else
* {
* rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
* }
*
*
* serial = rt_device_find(uart_name);
* if (!serial)
* {
* rt_kprintf("find %s failed!\n", uart_name);
* return -RT_ERROR;
* }
*
*
* rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
*
* rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
*
* rt_device_set_rx_indicate(serial, uart_input);
*
* rt_device_write(serial, 0, str, (sizeof(str) - 1));
*
*
* rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
*
* if (thread != RT_NULL)
* {
* rt_thread_startup(thread);
* }
* else
* {
* ret = -RT_ERROR;
* }
*
* return ret;
* }
*
* MSH_CMD_EXPORT(uart_sample, uart device sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_Serial
* @{
*/
#define BAUD_RATE_2400 2400
#define BAUD_RATE_4800 4800
#define BAUD_RATE_9600 9600
#define BAUD_RATE_19200 19200
#define BAUD_RATE_38400 38400
#define BAUD_RATE_57600 57600
#define BAUD_RATE_115200 115200
#define BAUD_RATE_230400 230400
#define BAUD_RATE_460800 460800
#define BAUD_RATE_500000 500000
#define BAUD_RATE_576000 576000
#define BAUD_RATE_921600 921600
#define BAUD_RATE_1000000 1000000
#define BAUD_RATE_1152000 1152000
#define BAUD_RATE_1500000 1500000
#define BAUD_RATE_2000000 2000000
#define BAUD_RATE_2500000 2500000
#define BAUD_RATE_3000000 3000000
#define BAUD_RATE_3500000 3500000
#define BAUD_RATE_4000000 4000000
#define DATA_BITS_5 5
#define DATA_BITS_6 6
#define DATA_BITS_7 7
#define DATA_BITS_8 8
#define DATA_BITS_9 9
#define STOP_BITS_1 0
#define STOP_BITS_2 1
#define STOP_BITS_3 2
#define STOP_BITS_4 3
#ifdef _WIN32
#include <windows.h>
#else
#define PARITY_NONE 0
#define PARITY_ODD 1
#define PARITY_EVEN 2
#endif
#define BIT_ORDER_LSB 0
#define BIT_ORDER_MSB 1
#define NRZ_NORMAL 0 /* Non Return to Zero : normal mode */
#define NRZ_INVERTED 1 /* Non Return to Zero : inverted mode */
#ifndef RT_SERIAL_RB_BUFSZ
#define RT_SERIAL_RB_BUFSZ 64
#endif
#define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */
#define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */
#define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */
#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
#define RT_SERIAL_DMA_RX 0x01
#define RT_SERIAL_DMA_TX 0x02
#define RT_SERIAL_RX_INT 0x01
#define RT_SERIAL_TX_INT 0x02
#define RT_SERIAL_ERR_OVERRUN 0x01
#define RT_SERIAL_ERR_FRAMING 0x02
#define RT_SERIAL_ERR_PARITY 0x03
#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048
#define RT_SERIAL_TX_DATAQUEUE_LWM 30
#define RT_SERIAL_FLOWCONTROL_CTSRTS 1
#define RT_SERIAL_FLOWCONTROL_NONE 0
/* Default config for serial_configure structure */
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
BAUD_RATE_115200, /* 115200 bits/s */ \
DATA_BITS_8, /* 8 databits */ \
STOP_BITS_1, /* 1 stopbit */ \
PARITY_NONE, /* No parity */ \
BIT_ORDER_LSB, /* LSB first sent */ \
NRZ_NORMAL, /* Normal mode */ \
RT_SERIAL_RB_BUFSZ, /* Buffer size */ \
RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
0 \
}
/**
* @brief Sets a hook function when RX indicate is called
*
*/
typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size);
RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind);
struct serial_configure
{
rt_uint32_t baud_rate;
rt_uint32_t data_bits :4;
rt_uint32_t stop_bits :2;
rt_uint32_t parity :2;
rt_uint32_t bit_order :1;
rt_uint32_t invert :1;
rt_uint32_t bufsz :16;
rt_uint32_t flowcontrol :1;
rt_uint32_t reserved :5;
};
/*
* Serial FIFO mode
*/
struct rt_serial_rx_fifo
{
/* software fifo */
rt_uint8_t *buffer;
rt_uint16_t put_index, get_index;
rt_bool_t is_full;
};
struct rt_serial_tx_fifo
{
struct rt_completion completion;
};
/*
* Serial DMA mode
*/
struct rt_serial_rx_dma
{
rt_bool_t activated;
};
struct rt_serial_tx_dma
{
rt_bool_t activated;
struct rt_data_queue data_queue;
};
struct rt_serial_device
{
struct rt_device parent;
const struct rt_uart_ops *ops;
struct serial_configure config;
void *serial_rx;
void *serial_tx;
struct rt_spinlock spinlock;
#ifdef RT_USING_SERIAL_BYPASS
struct rt_serial_bypass* bypass;
#endif
struct rt_device_notify rx_notify;
};
typedef struct rt_serial_device rt_serial_t;
/**
* @brief Configure the serial device
*/
struct rt_uart_ops
{
rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg);
rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg);
int (*putc)(struct rt_serial_device *serial, char c);
int (*getc)(struct rt_serial_device *serial);
rt_ssize_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
};
/**
* @brief Serial interrupt service routine
* @param serial serial device
* @param event event mask
* @ingroup group_Serial
*/
void rt_hw_serial_isr(struct rt_serial_device *serial, int event);
/**
* @brief Register a serial device to device list
*
* @param serial serial device
* @param name device name
* @param flag device flag
* @param data device private data
* @return rt_err_t error code
* @note This function will register a serial device to system device list,
* and add a device object to system object list.
* @ingroup group_Serial
*/
rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
const char *name,
rt_uint32_t flag,
void *data);
/**
* @brief register a serial device to system device list and add a device object to system object list
*
* @param serial serial device
* @return rt_err_t error code
*
* @ingroup group_Serial
*/
rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial);
/*! @}*/
#endif

View File

@ -0,0 +1,355 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-06-01 KyleChan first version
*/
#ifndef __DEV_SERIAL_V2_H__
#define __DEV_SERIAL_V2_H__
#include <rtthread.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_Serial_v2 Serial v2
*
* @brief Serial v2 driver api
*
* <b>Example</b>
* @code {.c}
*
* #include <rtthread.h>
* #include <rtdevice.h>
*
* #define SAMPLE_UART_NAME "uart1"
*
* struct rx_msg
* {
* rt_device_t dev;
* rt_size_t size;
* };
* static rt_device_t serial;
* static struct rt_messagequeue rx_mq;
*
* static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
* {
* struct rx_msg msg;
* rt_err_t result;
* msg.dev = dev;
* msg.size = size;
*
* result = rt_mq_send(&rx_mq, &msg, sizeof(msg));
* if (result == -RT_EFULL)
* {
* rt_kprintf("message queue full\n");
* }
* return result;
* }
*
* static void serial_thread_entry(void *parameter)
* {
* struct rx_msg msg;
* rt_err_t result;
* rt_uint32_t rx_length;
* static char rx_buffer[BSP_UART1_RX_BUFSIZE + 1];
*
* while (1)
* {
* rt_memset(&msg, 0, sizeof(msg));
* result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER);
* if (result > 0)
* {
* rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size);
* rx_buffer[rx_length] = '\0';
* rt_device_write(serial, 0, rx_buffer, rx_length);
* rt_kprintf("%s\n",rx_buffer);
* }
* }
* }
*
* static int uart_dma_sample(int argc, char *argv[])
* {
* rt_err_t ret = RT_EOK;
* char uart_name[RT_NAME_MAX];
* static char msg_pool[256];
* char str[] = "hello RT-Thread!\r\n";
*
* if (argc == 2)
* {
* rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
* }
* else
* {
* rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
* }
*
* serial = rt_device_find(uart_name);
* if (!serial)
* {
* rt_kprintf("find %s failed!\n", uart_name);
* return -RT_ERROR;
* }
*
* rt_mq_init(&rx_mq, "rx_mq",
* msg_pool,
* sizeof(struct rx_msg),
* sizeof(msg_pool),
* RT_IPC_FLAG_FIFO);
*
* rt_device_open(serial, RT_DEVICE_FLAG_RX_NON_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING);
* rt_device_set_rx_indicate(serial, uart_input);
* rt_device_write(serial, 0, str, (sizeof(str) - 1));
*
* rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
* if (thread != RT_NULL)
* {
* rt_thread_startup(thread);
* }
* else
* {
* ret = RT_ERROR;
* }
*
* return ret;
* }
* MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_Serial_v2
* @{
*/
#define BAUD_RATE_2400 2400
#define BAUD_RATE_4800 4800
#define BAUD_RATE_9600 9600
#define BAUD_RATE_19200 19200
#define BAUD_RATE_38400 38400
#define BAUD_RATE_57600 57600
#define BAUD_RATE_115200 115200
#define BAUD_RATE_230400 230400
#define BAUD_RATE_460800 460800
#define BAUD_RATE_500000 500000
#define BAUD_RATE_921600 921600
#define BAUD_RATE_2000000 2000000
#define BAUD_RATE_2500000 2500000
#define BAUD_RATE_3000000 3000000
#define DATA_BITS_5 5
#define DATA_BITS_6 6
#define DATA_BITS_7 7
#define DATA_BITS_8 8
#define DATA_BITS_9 9
#define STOP_BITS_1 0
#define STOP_BITS_2 1
#define STOP_BITS_3 2
#define STOP_BITS_4 3
#ifdef _WIN32
#include <windows.h>
#else
#define PARITY_NONE 0
#define PARITY_ODD 1
#define PARITY_EVEN 2
#endif
#define BIT_ORDER_LSB 0
#define BIT_ORDER_MSB 1
#define NRZ_NORMAL 0 /* Non Return to Zero : normal mode */
#define NRZ_INVERTED 1 /* Non Return to Zero : inverted mode */
#define RT_DEVICE_FLAG_RX_BLOCKING 0x1000
#define RT_DEVICE_FLAG_RX_NON_BLOCKING 0x2000
#define RT_DEVICE_FLAG_TX_BLOCKING 0x4000
#define RT_DEVICE_FLAG_TX_NON_BLOCKING 0x8000
#define RT_SERIAL_RX_BLOCKING RT_DEVICE_FLAG_RX_BLOCKING
#define RT_SERIAL_RX_NON_BLOCKING RT_DEVICE_FLAG_RX_NON_BLOCKING
#define RT_SERIAL_TX_BLOCKING RT_DEVICE_FLAG_TX_BLOCKING
#define RT_SERIAL_TX_NON_BLOCKING RT_DEVICE_FLAG_TX_NON_BLOCKING
#define RT_DEVICE_CHECK_OPTMODE 0x20
#define RT_SERIAL_EVENT_RX_IND 0x01 /* Rx indication */
#define RT_SERIAL_EVENT_TX_DONE 0x02 /* Tx complete */
#define RT_SERIAL_EVENT_RX_DMADONE 0x03 /* Rx DMA transfer done */
#define RT_SERIAL_EVENT_TX_DMADONE 0x04 /* Tx DMA transfer done */
#define RT_SERIAL_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */
#define RT_SERIAL_ERR_OVERRUN 0x01
#define RT_SERIAL_ERR_FRAMING 0x02
#define RT_SERIAL_ERR_PARITY 0x03
#define RT_SERIAL_TX_DATAQUEUE_SIZE 2048
#define RT_SERIAL_TX_DATAQUEUE_LWM 30
#define RT_SERIAL_RX_MINBUFSZ 64
#define RT_SERIAL_TX_MINBUFSZ 64
#define RT_SERIAL_TX_BLOCKING_BUFFER 1
#define RT_SERIAL_TX_BLOCKING_NO_BUFFER 0
#define RT_SERIAL_FLOWCONTROL_CTSRTS 1
#define RT_SERIAL_FLOWCONTROL_NONE 0
/* Default config for serial_configure structure */
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
BAUD_RATE_115200, /* 115200 bits/s */ \
DATA_BITS_8, /* 8 databits */ \
STOP_BITS_1, /* 1 stopbit */ \
PARITY_NONE, /* No parity */ \
BIT_ORDER_LSB, /* LSB first sent */ \
NRZ_NORMAL, /* Normal mode */ \
RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \
RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \
RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
0 \
}
/**
* @brief Serial receive indicate hook function type
*
*/
typedef void (*rt_hw_serial_rxind_hookproto_t)(rt_device_t dev, rt_size_t size);
RT_OBJECT_HOOKLIST_DECLARE(rt_hw_serial_rxind_hookproto_t, rt_hw_serial_rxind);
struct serial_configure
{
rt_uint32_t baud_rate;
rt_uint32_t data_bits :4;
rt_uint32_t stop_bits :2;
rt_uint32_t parity :2;
rt_uint32_t bit_order :1;
rt_uint32_t invert :1;
rt_uint32_t rx_bufsz :16;
rt_uint32_t tx_bufsz :16;
rt_uint32_t flowcontrol :1;
rt_uint32_t reserved :5;
};
/**
* @brief Serial Receive FIFO mode
*/
struct rt_serial_rx_fifo
{
struct rt_ringbuffer rb;
struct rt_completion rx_cpt;
rt_uint16_t rx_cpt_index;
/* software fifo */
rt_uint8_t buffer[];
};
/**
* @brief Serial Transmit FIFO mode
*
*/
struct rt_serial_tx_fifo
{
struct rt_ringbuffer rb;
rt_size_t put_size;
rt_bool_t activated;
struct rt_completion tx_cpt;
/* software fifo */
rt_uint8_t buffer[];
};
/**
* @brief serial device structure
*
*/
struct rt_serial_device
{
struct rt_device parent;
const struct rt_uart_ops *ops;
struct serial_configure config;
void *serial_rx;
void *serial_tx;
struct rt_device_notify rx_notify;
};
/**
* @brief uart device operations
*
*/
struct rt_uart_ops
{
rt_err_t (*configure)(struct rt_serial_device *serial,
struct serial_configure *cfg);
rt_err_t (*control)(struct rt_serial_device *serial,
int cmd,
void *arg);
int (*putc)(struct rt_serial_device *serial, char c);
int (*getc)(struct rt_serial_device *serial);
rt_ssize_t (*transmit)(struct rt_serial_device *serial,
rt_uint8_t *buf,
rt_size_t size,
rt_uint32_t tx_flag);
};
/**
* @brief Serial interrupt service routine
* @param serial serial device
* @param event event mask
* @ingroup group_Serial_v2
*/
void rt_hw_serial_isr(struct rt_serial_device *serial, int event);
/**
* @brief Register a serial device to device list
*
* @param serial serial device
* @param name device name
* @param flag device flag
* @param data device private data
* @return rt_err_t error code
* @note This function will register a serial device to system device list,
* and add a device object to system object list.
* @ingroup group_Serial_v2
*/
rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
const char *name,
rt_uint32_t flag,
void *data);
/**
* @brief register a serial device to system device list and add a device object to system object list
*
* @param serial serial device
* @return rt_err_t error code
*
* @ingroup group_Serial_v2
*/
rt_err_t rt_hw_serial_register_tty(struct rt_serial_device *serial);
/*! @}*/
#endif

View File

@ -0,0 +1,636 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-11-23 Bernard Add extern "C"
* 2020-06-13 armink fix the 3 wires issue
* 2022-09-01 liYony fix api rt_spi_sendrecv16 about MSB and LSB bug
*/
#ifndef __DEV_SPI_H__
#define __DEV_SPI_H__
#include <stdlib.h>
#include <rtthread.h>
#include <drivers/dev_pin.h>
#include <drivers/core/driver.h>
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_SPI SPI
*
* @brief SPI driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include <rtdevice.h>
*
* #define W25Q_SPI_DEVICE_NAME "qspi10"
*
* static void spi_w25q_sample(int argc, char *argv[])
* {
* struct rt_spi_device *spi_dev_w25q;
* char name[RT_NAME_MAX];
* rt_uint8_t w25x_read_id = 0x90;
* rt_uint8_t id[5] = {0};
*
* if (argc == 2)
* {
* rt_strncpy(name, argv[1], RT_NAME_MAX);
* }
* else
* {
* rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
* }
*
* // 查找 spi 设备获取设备句柄
* spi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);
* if (!spi_dev_w25q)
* {
* rt_kprintf("spi sample run failed! can't find %s device!\n", name);
* }
* else
* {
* // 方式1使用 rt_spi_send_then_recv()发送命令读取ID
* rt_spi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
* rt_kprintf("use rt_spi_send_then_recv() read w25q ID is:%x%x\n", id[3], id[4]);
*
* // 方式2使用 rt_spi_transfer_message()发送命令读取ID
* struct rt_spi_message msg1, msg2;
*
* msg1.send_buf = &w25x_read_id;
* msg1.recv_buf = RT_NULL;
* msg1.length = 1;
* msg1.cs_take = 1;
* msg1.cs_release = 0;
* msg1.next = &msg2;
*
* msg2.send_buf = RT_NULL;
* msg2.recv_buf = id;
* msg2.length = 5;
* msg2.cs_take = 0;
* msg2.cs_release = 1;
* msg2.next = RT_NULL;
*
* rt_spi_transfer_message(spi_dev_w25q, &msg1);
* rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id[3], id[4]);
*
* }
* }
* // 导出到 msh 命令列表中
* MSH_CMD_EXPORT(spi_w25q_sample, spi w25q sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_SPI
* @{
*/
#ifdef __cplusplus
extern "C"{
#endif
/**
* At CPOL=0 the base value of the clock is zero
* - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
* and data are propagated on a falling edge (high->low clock transition).
* - For CPHA=1, data are captured on the clock's falling edge and data are
* propagated on a rising edge.
* At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
* - For CPHA=0, data are captured on clock's falling edge and data are propagated
* on a rising edge.
* - For CPHA=1, data are captured on clock's rising edge and data are propagated
* on a falling edge.
*/
#define RT_SPI_CPHA (1<<0) /*!< bit[0]:CPHA, clock phase */
#define RT_SPI_CPOL (1<<1) /*!< bit[1]:CPOL, clock polarity */
#define RT_SPI_LSB (0<<2) /*!< bit[2]: 0-LSB */
#define RT_SPI_MSB (1<<2) /*!< bit[2]: 1-MSB */
#define RT_SPI_MASTER (0<<3) /*!< SPI master device */
#define RT_SPI_SLAVE (1<<3) /*!< SPI slave device */
#define RT_SPI_CS_HIGH (1<<4) /*!< Chipselect active high */
#define RT_SPI_NO_CS (1<<5) /*!< No chipselect */
#define RT_SPI_3WIRE (1<<6) /*!< SI/SO pin shared */
#define RT_SPI_READY (1<<7) /*!< Slave pulls low to pause */
#define RT_SPI_MODE_MASK (RT_SPI_CPHA | RT_SPI_CPOL | RT_SPI_MSB | RT_SPI_SLAVE | RT_SPI_CS_HIGH | RT_SPI_NO_CS | RT_SPI_3WIRE | RT_SPI_READY)
#define RT_SPI_MODE_0 (0 | 0) /*!< CPOL = 0, CPHA = 0 */
#define RT_SPI_MODE_1 (0 | RT_SPI_CPHA) /*!< CPOL = 0, CPHA = 1 */
#define RT_SPI_MODE_2 (RT_SPI_CPOL | 0) /*!< CPOL = 1, CPHA = 0 */
#define RT_SPI_MODE_3 (RT_SPI_CPOL | RT_SPI_CPHA) /*!< CPOL = 1, CPHA = 1 */
#define RT_SPI_BUS_MODE_SPI (1<<0)
#define RT_SPI_BUS_MODE_QSPI (1<<1)
#define RT_SPI_CS_CNT_MAX 16
/**
* @brief SPI message structure
*/
struct rt_spi_message
{
const void *send_buf;
void *recv_buf;
rt_size_t length;
struct rt_spi_message *next;
unsigned cs_take : 1;
unsigned cs_release : 1;
};
/**
* @brief SPI configuration structure
*/
struct rt_spi_configuration
{
rt_uint8_t mode;
rt_uint8_t data_width;
#ifdef RT_USING_DM
rt_uint8_t data_width_tx;
rt_uint8_t data_width_rx;
#else
rt_uint16_t reserved;
#endif
rt_uint32_t max_hz;
};
struct rt_spi_ops;
/**
* @brief SPI bus structure
*/
struct rt_spi_bus
{
struct rt_device parent;
rt_uint8_t mode;
const struct rt_spi_ops *ops;
#ifdef RT_USING_DM
rt_base_t cs_pins[RT_SPI_CS_CNT_MAX];
rt_uint8_t cs_active_vals[RT_SPI_CS_CNT_MAX];
rt_bool_t slave;
int num_chipselect;
#endif /* RT_USING_DM */
struct rt_mutex lock;
struct rt_spi_device *owner;
};
/**
* @brief SPI operators
*/
struct rt_spi_ops
{
rt_err_t (*configure)(struct rt_spi_device *device, struct rt_spi_configuration *configuration);
rt_ssize_t (*xfer)(struct rt_spi_device *device, struct rt_spi_message *message);
};
#ifdef RT_USING_DM
/**
* @brief SPI delay info
*/
struct rt_spi_delay
{
#define RT_SPI_DELAY_UNIT_USECS 0
#define RT_SPI_DELAY_UNIT_NSECS 1
#define RT_SPI_DELAY_UNIT_SCK 2
rt_uint16_t value;
rt_uint8_t unit;
};
#endif /* RT_USING_DM */
/**
* @brief SPI Virtual BUS, one device must connected to a virtual BUS
*/
struct rt_spi_device
{
struct rt_device parent;
struct rt_spi_bus *bus;
#ifdef RT_USING_DM
const char *name;
const struct rt_spi_device_id *id;
const struct rt_ofw_node_id *ofw_id;
rt_uint8_t chip_select[RT_SPI_CS_CNT_MAX];
struct rt_spi_delay cs_setup;
struct rt_spi_delay cs_hold;
struct rt_spi_delay cs_inactive;
#endif
struct rt_spi_configuration config;
rt_base_t cs_pin;
void *user_data;
};
/**
* @brief QSPI message structure
*/
struct rt_qspi_message
{
struct rt_spi_message parent;
/* instruction stage */
struct
{
rt_uint8_t content;
rt_uint8_t qspi_lines;
} instruction;
/* address and alternate_bytes stage */
struct
{
rt_uint32_t content;
rt_uint8_t size;
rt_uint8_t qspi_lines;
} address, alternate_bytes;
/* dummy_cycles stage */
rt_uint32_t dummy_cycles;
/* number of lines in qspi data stage, the other configuration items are in parent */
rt_uint8_t qspi_data_lines;
};
/**
* @brief QSPI configuration structure
*/
struct rt_qspi_configuration
{
struct rt_spi_configuration parent;
/* The size of medium */
rt_uint32_t medium_size;
/* double data rate mode */
rt_uint8_t ddr_mode;
/* the data lines max width which QSPI bus supported, such as 1, 2, 4 */
rt_uint8_t qspi_dl_width ;
};
/**
* @brief QSPI operators
*/
struct rt_qspi_device
{
struct rt_spi_device parent;
struct rt_qspi_configuration config;
void (*enter_qspi_mode)(struct rt_qspi_device *device);
void (*exit_qspi_mode)(struct rt_qspi_device *device);
};
#define SPI_DEVICE(dev) ((struct rt_spi_device *)(dev))
#ifdef RT_USING_DM
struct rt_spi_device_id
{
char name[20];
void *data;
};
struct rt_spi_driver
{
struct rt_driver parent;
const struct rt_spi_device_id *ids;
const struct rt_ofw_node_id *ofw_ids;
rt_err_t (*probe)(struct rt_spi_device *device);
rt_err_t (*remove)(struct rt_spi_device *device);
rt_err_t (*shutdown)(struct rt_spi_device *device);
};
rt_err_t rt_spi_driver_register(struct rt_spi_driver *driver);
rt_err_t rt_spi_device_register(struct rt_spi_device *device);
#define RT_SPI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, spi, BUILIN)
#endif /* RT_USING_DM */
/**
* @brief register a SPI bus
*
* @param bus the SPI bus
* @param name the name of SPI bus
* @param ops the operations of SPI bus
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus,
const char *name,
const struct rt_spi_ops *ops);
/**
* @brief attach a device on SPI bus
*
* @param device the SPI device
* @param name the name of SPI device
* @param bus_name the name of SPI bus
* @param user_data the user data of SPI device
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device,
const char *name,
const char *bus_name,
void *user_data);
/**
* @brief attach a device on SPI bus with CS pin
*
* @param device the SPI device
* @param name the name of SPI device
* @param bus_name the name of SPI bus
* @param cs_pin the CS pin of SPI device
* @param user_data the user data of SPI device
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_bus_attach_device_cspin(struct rt_spi_device *device,
const char *name,
const char *bus_name,
rt_base_t cs_pin,
void *user_data);
/**
* @brief Reconfigure the SPI bus for the specified device.
*
* @param device: Pointer to the SPI device attached to the SPI bus.
* @retval RT_EOK if the SPI device was successfully released and the bus was configured.
* RT_EBUSY if the SPI bus is currently in use; the new configuration will take effect once the device releases the bus.
* Other return values indicate failure to configure the SPI bus due to various reasons.
* @note If the configuration of the SPI device has been updated and requires bus re-initialization,
* call this function directly. This function will reconfigure the SPI bus for the specified device.
* If this is the first time to initialize the SPI device, please call rt_spi_configure or rt_qspi_configure.
* This function is used to reconfigure the SPI bus when the SPI device is already in use.
* For further details, refer to:
* https://github.com/RT-Thread/rt-thread/pull/8528
*/
rt_err_t rt_spi_bus_configure(struct rt_spi_device *device);
/**
* @brief This function takes SPI bus.
*
* @param device the SPI device attached to SPI bus
*
* @return RT_EOK on taken SPI bus successfully. others on taken SPI bus failed.
*/
rt_err_t rt_spi_take_bus(struct rt_spi_device *device);
/**
* @brief This function releases SPI bus.
*
* @param device the SPI device attached to SPI bus
*
* @return RT_EOK on release SPI bus successfully.
*/
rt_err_t rt_spi_release_bus(struct rt_spi_device *device);
/**
* @brief This function take SPI device (takes CS of SPI device).
*
* @param device the SPI device attached to SPI bus
*
* @return RT_EOK on release SPI bus successfully. others on taken SPI bus failed.
*/
rt_err_t rt_spi_take(struct rt_spi_device *device);
/**
* @brief This function releases SPI device (releases CS of SPI device).
*
* @param device the SPI device attached to SPI bus
*
* @return RT_EOK on release SPI device successfully.
*/
rt_err_t rt_spi_release(struct rt_spi_device *device);
/**
* @brief This function can set configuration on SPI device.
*
* @param device: the SPI device attached to SPI bus
* @param cfg: the configuration pointer.
*
* @retval RT_EOK on release SPI device successfully.
* RT_EBUSY is not an error condition and the configuration will take effect once the device has the bus
* others on taken SPI bus failed.
*/
rt_err_t rt_spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *cfg);
/**
* @brief This function can send data then receive data from SPI device.
*
* @param device the SPI device attached to SPI bus
* @param send_buf the buffer to be transmitted to SPI device.
* @param send_length the number of data to be transmitted.
* @param recv_buf the buffer to be recivied from SPI device.
* @param recv_length the data to be recivied.
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device,
const void *send_buf,
rt_size_t send_length,
void *recv_buf,
rt_size_t recv_length);
/**
* @brief This function can send data then send data from SPI device.
*
* @param device the SPI device attached to SPI bus
* @param send_buf1 the buffer to be transmitted to SPI device.
* @param send_length1 the number of data to be transmitted.
* @param send_buf2 the buffer to be transmitted to SPI device.
* @param send_length2 the number of data to be transmitted.
*
* @return the status of transmit.
*/
rt_err_t rt_spi_send_then_send(struct rt_spi_device *device,
const void *send_buf1,
rt_size_t send_length1,
const void *send_buf2,
rt_size_t send_length2);
/**
* @brief This function transmits data to SPI device.
*
* @param device the SPI device attached to SPI bus
* @param send_buf the buffer to be transmitted to SPI device.
* @param recv_buf the buffer to save received data from SPI device.
* @param length the length of transmitted data.
*
* @return the actual length of transmitted.
*/
rt_ssize_t rt_spi_transfer(struct rt_spi_device *device,
const void *send_buf,
void *recv_buf,
rt_size_t length);
/**
* @brief The SPI device transmits 8 bytes of data
*
* @param device the SPI device attached to SPI bus
* @param senddata send data buffer
* @param recvdata receive data buffer
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_sendrecv8(struct rt_spi_device *device,
rt_uint8_t senddata,
rt_uint8_t *recvdata);
/**
* @brief The SPI device transmits 16 bytes of data
*
* @param device the SPI device attached to SPI bus
* @param senddata send data buffer
* @param recvdata receive data buffer
*
* @return rt_err_t error code
*/
rt_err_t rt_spi_sendrecv16(struct rt_spi_device *device,
rt_uint16_t senddata,
rt_uint16_t *recvdata);
/**
* @brief This function transfers a message list to the SPI device.
*
* @param device the SPI device attached to SPI bus
* @param message the message list to be transmitted to SPI device
*
* @return RT_NULL if transmits message list successfully,
* SPI message which be transmitted failed.
*/
struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device,
struct rt_spi_message *message);
/**
* @brief This function receives data from SPI device.
*
* @param device the SPI device attached to SPI bus
* @param recv_buf the buffer to be recivied from SPI device.
* @param length the data to be recivied.
*
* @return the actual length of received.
*/
rt_inline rt_size_t rt_spi_recv(struct rt_spi_device *device,
void *recv_buf,
rt_size_t length)
{
return rt_spi_transfer(device, RT_NULL, recv_buf, length);
}
/**
* @brief This function sends data to SPI device.
*
* @param device the SPI device attached to SPI bus
* @param send_buf the buffer to be transmitted to SPI device.
* @param length the number of data to be transmitted.
*
* @return the actual length of send.
*/
rt_inline rt_size_t rt_spi_send(struct rt_spi_device *device,
const void *send_buf,
rt_size_t length)
{
return rt_spi_transfer(device, send_buf, RT_NULL, length);
}
/**
* @brief This function appends a message to the SPI message list.
*
* @param list the SPI message list header.
* @param message the message pointer to be appended to the message list.
*/
rt_inline void rt_spi_message_append(struct rt_spi_message *list,
struct rt_spi_message *message)
{
RT_ASSERT(list != RT_NULL);
if (message == RT_NULL)
return; /* not append */
while (list->next != RT_NULL)
{
list = list->next;
}
list->next = message;
message->next = RT_NULL;
}
/**
* @brief This function can set configuration on QSPI device.
*
* @param device the QSPI device attached to QSPI bus.
* @param cfg the configuration pointer.
*
* @return the actual length of transmitted.
*/
rt_err_t rt_qspi_configure(struct rt_qspi_device *device, struct rt_qspi_configuration *cfg);
/**
* @brief This function can register a SPI bus for QSPI mode.
*
* @param bus the SPI bus for QSPI mode.
* @param name The name of the spi bus.
* @param ops the SPI bus instance to be registered.
*
* @return the actual length of transmitted.
*/
rt_err_t rt_qspi_bus_register(struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops);
/**
* @brief This function transmits data to QSPI device.
*
* @param device the QSPI device attached to QSPI bus.
* @param message the message pointer.
*
* @return the actual length of transmitted.
*/
rt_size_t rt_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message);
/**
* @brief This function can send data then receive data from QSPI device
*
* @param device the QSPI device attached to QSPI bus.
* @param send_buf the buffer to be transmitted to QSPI device.
* @param send_length the number of data to be transmitted.
* @param recv_buf the buffer to be recivied from QSPI device.
* @param recv_length the data to be recivied.
*
* @return the status of transmit.
*/
rt_err_t rt_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length,void *recv_buf, rt_size_t recv_length);
/**
* @brief This function can send data to QSPI device
*
* @param device the QSPI device attached to QSPI bus.
* @param send_buf the buffer to be transmitted to QSPI device.
* @param length the number of data to be transmitted.
*
* @return the status of transmit.
*/
rt_err_t rt_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length);
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif

View File

@ -0,0 +1,248 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-05-20 tyustli the first version
*/
#ifndef __DEV_TOUCH_H__
#define __DEV_TOUCH_H__
#include <rtthread.h>
#include "dev_pin.h"
/**
* @addtogroup group_Drivers RTTHREAD Driver
* @defgroup group_Touch Touch
*
* @brief Touch driver api
*
* <b>Example</b>
* @code {.c}
* #include <rtthread.h>
* #include "rtdevice.h"
*
* static rt_thread_t gt9147_thread = RT_NULL;
* static rt_sem_t gt9147_sem = RT_NULL;
* static rt_device_t dev = RT_NULL;
* static struct rt_touch_data *read_data;
*
* // 读取数据线程入口函数
* static void gt9147_entry(void *parameter)
* {
* struct rt_touch_data *read_data;
* read_data = (struct rt_touch_data *)rt_malloc(sizeof(struct rt_touch_data) * 5);
*
* while (1)
* {
* // 请求信号量
* rt_sem_take(gt9147_sem, RT_WAITING_FOREVER);
* // 读取五个点的触摸信息
* if (rt_device_read(dev, 0, read_data, 5) == 5)
* {
* for (rt_uint8_t i = 0; i < 5; i++)
* {
* if (read_data[i].event == RT_TOUCH_EVENT_DOWN || read_data[i].event == RT_TOUCH_EVENT_MOVE)
* {
* rt_kprintf("%d %d %d %d %d\n",
* read_data[i].track_id,
* read_data[i].x_coordinate,
* read_data[i].y_coordinate,
* read_data[i].timestamp,
* read_data[i].width);
* }
* }
* }
* // 打开中断
* rt_device_control(dev, RT_TOUCH_CTRL_ENABLE_INT, RT_NULL);
* }
* }
*
* // 接收回调函数
* static rt_err_t rx_callback(rt_device_t dev, rt_size_t size)
* {
* // 关闭中断
* rt_device_control(dev, RT_TOUCH_CTRL_DISABLE_INT, RT_NULL);
* // 释放信号量
* rt_sem_release(gt9147_sem);
* return 0;
* }
*
* static int gt9147_sample(void)
* {
* // 查找 Touch 设备
* dev = rt_device_find("touch");
*
* if (dev == RT_NULL)
* {
* rt_kprintf("can't find device:%s\n", "touch");
* return -1;
* }
* // 以中断的方式打开设备
* if (rt_device_open(dev, RT_DEVICE_FLAG_INT_RX) != RT_EOK)
* {
* rt_kprintf("open device failed!");
* return -1;
* }
* // 设置接收回调
* rt_device_set_rx_indicate(dev, rx_callback);
* // 创建信号量
* gt9147_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO);
*
* if (gt9147_sem == RT_NULL)
* {
* rt_kprintf("create dynamic semaphore failed.\n");
* return -1;
* }
* // 创建读取数据线程
* gt9147_thread = rt_thread_create("thread1",
* gt9147_entry,
* RT_NULL,
* THREAD_STACK_SIZE,
* THREAD_PRIORITY,
* THREAD_TIMESLICE);
* // 启动线程
* if (gt9147_thread != RT_NULL)
* rt_thread_startup(gt9147_thread);
*
* return 0;
* }
* MSH_CMD_EXPORT(gt9147_sample, gt9147 sample);
* @endcode
*
* @ingroup group_Drivers
*/
/*!
* @addtogroup group_Touch
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_RTC
#define rt_touch_get_ts() time(RT_NULL) /* API for the touch to get the timestamp */
#else
#define rt_touch_get_ts() rt_tick_get() /* API for the touch to get the timestamp */
#endif
/* Touch vendor types */
#define RT_TOUCH_VENDOR_UNKNOWN (0) /* unknown */
#define RT_TOUCH_VENDOR_GT (1) /* GTxx series */
#define RT_TOUCH_VENDOR_FT (2) /* FTxx series */
/* Touch ic type*/
#define RT_TOUCH_TYPE_NONE (0) /* touch ic none */
#define RT_TOUCH_TYPE_CAPACITANCE (1) /* capacitance ic */
#define RT_TOUCH_TYPE_RESISTANCE (2) /* resistance ic */
/* Touch control cmd types */
#define RT_TOUCH_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Touch) + 0) /* Get device id */
#define RT_TOUCH_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Touch) + 1) /* Get touch info */
#define RT_TOUCH_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Touch) + 2) /* Set touch's work mode. ex. RT_TOUCH_MODE_POLLING,RT_TOUCH_MODE_INT */
#define RT_TOUCH_CTRL_SET_X_RANGE (RT_DEVICE_CTRL_BASE(Touch) + 3) /* Set x coordinate range */
#define RT_TOUCH_CTRL_SET_Y_RANGE (RT_DEVICE_CTRL_BASE(Touch) + 4) /* Set y coordinate range */
#define RT_TOUCH_CTRL_SET_X_TO_Y (RT_DEVICE_CTRL_BASE(Touch) + 5) /* Set X Y coordinate exchange */
#define RT_TOUCH_CTRL_DISABLE_INT (RT_DEVICE_CTRL_BASE(Touch) + 6) /* Disable interrupt */
#define RT_TOUCH_CTRL_ENABLE_INT (RT_DEVICE_CTRL_BASE(Touch) + 7) /* Enable interrupt */
#define RT_TOUCH_CTRL_POWER_ON (RT_DEVICE_CTRL_BASE(Touch) + 8) /* Touch Power On */
#define RT_TOUCH_CTRL_POWER_OFF (RT_DEVICE_CTRL_BASE(Touch) + 9) /* Touch Power Off */
#define RT_TOUCH_CTRL_GET_STATUS (RT_DEVICE_CTRL_BASE(Touch) + 10) /* Get Touch Power Status */
/* Touch event */
#define RT_TOUCH_EVENT_NONE (0) /* Touch none */
#define RT_TOUCH_EVENT_UP (1) /* Touch up event */
#define RT_TOUCH_EVENT_DOWN (2) /* Touch down event */
#define RT_TOUCH_EVENT_MOVE (3) /* Touch move event */
/**
* @brief Touch information
*/
struct rt_touch_info
{
rt_uint8_t type; /* The touch type */
rt_uint8_t vendor; /* Vendor of touchs */
rt_uint8_t point_num; /* Support point num */
rt_int32_t range_x; /* X coordinate range */
rt_int32_t range_y; /* Y coordinate range */
};
/**
* @brief Touch configuration
*/
struct rt_touch_config
{
#ifdef RT_TOUCH_PIN_IRQ
struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
#endif
char *dev_name; /* The name of the communication device */
void *user_data;
};
typedef struct rt_touch_device *rt_touch_t;
/**
* @brief Touch device
*/
struct rt_touch_device
{
struct rt_device parent; /* The standard device */
struct rt_touch_info info; /* The touch info data */
struct rt_touch_config config; /* The touch config data */
const struct rt_touch_ops *ops; /* The touch ops */
rt_err_t (*irq_handle)(rt_touch_t touch); /* Called when an interrupt is generated, registered by the driver */
};
/**
* @brief Touch data
*/
struct rt_touch_data
{
rt_uint8_t event; /* The touch event of the data */
rt_uint8_t track_id; /* Track id of point */
rt_uint8_t width; /* Point of width */
rt_uint16_t x_coordinate; /* Point of x coordinate */
rt_uint16_t y_coordinate; /* Point of y coordinate */
rt_tick_t timestamp; /* The timestamp when the data was received */
};
/**
* @brief Touch device operations
*/
struct rt_touch_ops
{
rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num);
rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg);
};
/**
* @brief register a touch device
* @param touch the touch device
* @param name the name of touch device
* @param flag the flag of touch device
* @param data the user data of touch device
* @return rt_err_t error code
*/
int rt_hw_touch_register(rt_touch_t touch,
const char *name,
rt_uint32_t flag,
void *data);
/**
* @brief Touch irq handle
* @param touch the touch device
*
* @note If you doesn't use pin device. you must call this function in your touch irq callback
*/
void rt_hw_touch_isr(rt_touch_t touch);
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* __DEV_TOUCH_H__ */

View File

@ -0,0 +1,42 @@
/*
* COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-09-12 heyuanjie87 first version.
*/
#ifndef __DEV_WATCHDOG_H__
#define __DEV_WATCHDOG_H__
#include <rtthread.h>
#define RT_DEVICE_CTRL_WDT_GET_TIMEOUT (RT_DEVICE_CTRL_BASE(WDT) + 1) /* get timeout(in seconds) */
#define RT_DEVICE_CTRL_WDT_SET_TIMEOUT (RT_DEVICE_CTRL_BASE(WDT) + 2) /* set timeout(in seconds) */
#define RT_DEVICE_CTRL_WDT_GET_TIMELEFT (RT_DEVICE_CTRL_BASE(WDT) + 3) /* get the left time before reboot(in seconds) */
#define RT_DEVICE_CTRL_WDT_KEEPALIVE (RT_DEVICE_CTRL_BASE(WDT) + 4) /* refresh watchdog */
#define RT_DEVICE_CTRL_WDT_START (RT_DEVICE_CTRL_BASE(WDT) + 5) /* start watchdog */
#define RT_DEVICE_CTRL_WDT_STOP (RT_DEVICE_CTRL_BASE(WDT) + 6) /* stop watchdog */
struct rt_watchdog_ops;
struct rt_watchdog_device
{
struct rt_device parent;
const struct rt_watchdog_ops *ops;
};
typedef struct rt_watchdog_device rt_watchdog_t;
struct rt_watchdog_ops
{
rt_err_t (*init)(rt_watchdog_t *wdt);
rt_err_t (*control)(rt_watchdog_t *wdt, int cmd, void *arg);
};
rt_err_t rt_hw_watchdog_register(rt_watchdog_t *wdt,
const char *name,
rt_uint32_t flag,
void *data);
#endif /* __DEV_WATCHDOG_H__ */

View File

@ -0,0 +1,234 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __DMA_H__
#define __DMA_H__
#include <rtthread.h>
#include <drivers/ofw.h>
#include <drivers/misc.h>
#include <drivers/core/dm.h>
#include <mmu.h>
#include <mm_page.h>
#include <bitmap.h>
struct rt_dma_chan;
struct rt_dma_controller_ops;
enum rt_dma_transfer_direction
{
RT_DMA_MEM_TO_MEM,
RT_DMA_MEM_TO_DEV,
RT_DMA_DEV_TO_MEM,
RT_DMA_DEV_TO_DEV,
RT_DMA_DIR_MAX,
};
enum rt_dma_slave_buswidth
{
RT_DMA_SLAVE_BUSWIDTH_UNDEFINED = 0,
RT_DMA_SLAVE_BUSWIDTH_1_BYTE = 1,
RT_DMA_SLAVE_BUSWIDTH_2_BYTES = 2,
RT_DMA_SLAVE_BUSWIDTH_3_BYTES = 3,
RT_DMA_SLAVE_BUSWIDTH_4_BYTES = 4,
RT_DMA_SLAVE_BUSWIDTH_8_BYTES = 8,
RT_DMA_SLAVE_BUSWIDTH_16_BYTES = 16,
RT_DMA_SLAVE_BUSWIDTH_32_BYTES = 32,
RT_DMA_SLAVE_BUSWIDTH_64_BYTES = 64,
RT_DMA_SLAVE_BUSWIDTH_128_BYTES = 128,
RT_DMA_SLAVE_BUSWIDTH_BYTES_MAX,
};
struct rt_dma_slave_config
{
enum rt_dma_transfer_direction direction;
enum rt_dma_slave_buswidth src_addr_width;
enum rt_dma_slave_buswidth dst_addr_width;
rt_ubase_t src_addr;
rt_ubase_t dst_addr;
rt_uint32_t src_maxburst;
rt_uint32_t dst_maxburst;
rt_uint32_t src_port_window_size;
rt_uint32_t dst_port_window_size;
};
struct rt_dma_slave_transfer
{
rt_ubase_t src_addr;
rt_ubase_t dst_addr;
void *buffer;
rt_ubase_t dma_handle;
rt_size_t buffer_len;
rt_size_t period_len;
};
struct rt_dma_controller
{
rt_list_t list;
struct rt_device *dev;
RT_BITMAP_DECLARE(dir_cap, RT_DMA_DIR_MAX);
const struct rt_dma_controller_ops *ops;
rt_list_t channels_nodes;
struct rt_mutex mutex;
};
struct rt_dma_controller_ops
{
struct rt_dma_chan *(*request_chan)(struct rt_dma_controller *ctrl,
struct rt_device *slave, void *fw_data);
rt_err_t (*release_chan)(struct rt_dma_chan *chan);
rt_err_t (*start)(struct rt_dma_chan *chan);
rt_err_t (*stop)(struct rt_dma_chan *chan);
rt_err_t (*config)(struct rt_dma_chan *chan, struct rt_dma_slave_config *conf);
rt_err_t (*prep_memcpy)(struct rt_dma_chan *chan,
rt_ubase_t dma_addr_src, rt_ubase_t dma_addr_dst, rt_size_t len);
rt_err_t (*prep_cyclic)(struct rt_dma_chan *chan,
rt_ubase_t dma_buf_addr, rt_size_t buf_len, rt_size_t period_len,
enum rt_dma_transfer_direction dir);
rt_err_t (*prep_single)(struct rt_dma_chan *chan,
rt_ubase_t dma_buf_addr, rt_size_t buf_len,
enum rt_dma_transfer_direction dir);
};
struct rt_dma_chan
{
const char *name;
struct rt_dma_controller *ctrl;
struct rt_device *slave;
rt_list_t list;
rt_err_t conf_err;
rt_err_t prep_err;
struct rt_dma_slave_config conf;
struct rt_dma_slave_transfer transfer;
void (*callback)(struct rt_dma_chan *chan, rt_size_t size);
void *priv;
};
struct rt_dma_pool
{
rt_region_t region;
rt_list_t list;
rt_ubase_t flags;
rt_bitmap_t *map;
rt_size_t bits;
rt_ubase_t start;
struct rt_device *dev;
};
struct rt_dma_map_ops
{
void *(*alloc)(struct rt_device *dev, rt_size_t size,
rt_ubase_t *dma_handle, rt_ubase_t flags);
void (*free)(struct rt_device *dev, rt_size_t size,
void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags);
rt_err_t (*sync_out_data)(struct rt_device *dev, void *data, rt_size_t size,
rt_ubase_t *dma_handle, rt_ubase_t flags);
rt_err_t (*sync_in_data)(struct rt_device *dev, void *out_data, rt_size_t size,
rt_ubase_t dma_handle, rt_ubase_t flags);
};
rt_inline void rt_dma_controller_add_direction(struct rt_dma_controller *ctrl,
enum rt_dma_transfer_direction dir)
{
RT_ASSERT(ctrl != RT_NULL);
RT_ASSERT(dir < RT_DMA_DIR_MAX);
rt_bitmap_set_bit(ctrl->dir_cap, dir);
}
rt_err_t rt_dma_controller_register(struct rt_dma_controller *ctrl);
rt_err_t rt_dma_controller_unregister(struct rt_dma_controller *ctrl);
rt_err_t rt_dma_chan_start(struct rt_dma_chan *chan);
rt_err_t rt_dma_chan_stop(struct rt_dma_chan *chan);
rt_err_t rt_dma_chan_config(struct rt_dma_chan *chan,
struct rt_dma_slave_config *conf);
rt_err_t rt_dma_chan_done(struct rt_dma_chan *chan, rt_size_t size);
rt_err_t rt_dma_prep_memcpy(struct rt_dma_chan *chan,
struct rt_dma_slave_transfer *transfer);
rt_err_t rt_dma_prep_cyclic(struct rt_dma_chan *chan,
struct rt_dma_slave_transfer *transfer);
rt_err_t rt_dma_prep_single(struct rt_dma_chan *chan,
struct rt_dma_slave_transfer *transfer);
struct rt_dma_chan *rt_dma_chan_request(struct rt_device *dev, const char *name);
rt_err_t rt_dma_chan_release(struct rt_dma_chan *chan);
#define RT_DMA_F_LINEAR RT_BIT(0)
#define RT_DMA_F_32BITS RT_BIT(1)
#define RT_DMA_F_NOCACHE RT_BIT(2)
#define RT_DMA_F_DEVICE RT_BIT(3)
#define RT_DMA_F_NOMAP RT_BIT(4)
#define RT_DMA_PAGE_SIZE ARCH_PAGE_SIZE
void *rt_dma_alloc(struct rt_device *dev, rt_size_t size,
rt_ubase_t *dma_handle, rt_ubase_t flags);
void rt_dma_free(struct rt_device *dev, rt_size_t size,
void *cpu_addr, rt_ubase_t dma_handle, rt_ubase_t flags);
rt_inline void *rt_dma_alloc_coherent(struct rt_device *dev, rt_size_t size,
rt_ubase_t *dma_handle)
{
return rt_dma_alloc(dev, size, dma_handle,
RT_DMA_F_NOCACHE | RT_DMA_F_LINEAR);
}
rt_inline void rt_dma_free_coherent(struct rt_device *dev, rt_size_t size,
void *cpu_addr, rt_ubase_t dma_handle)
{
rt_dma_free(dev, size, cpu_addr, dma_handle,
RT_DMA_F_NOCACHE | RT_DMA_F_LINEAR);
}
rt_err_t rt_dma_sync_out_data(struct rt_device *dev, void *data, rt_size_t size,
rt_ubase_t *dma_handle, rt_ubase_t flags);
rt_err_t rt_dma_sync_in_data(struct rt_device *dev, void *out_data, rt_size_t size,
rt_ubase_t dma_handle, rt_ubase_t flags);
rt_inline rt_bool_t rt_dma_device_is_coherent(struct rt_device *dev)
{
return rt_dm_dev_prop_read_bool(dev, "dma-coherent");
}
rt_inline void rt_dma_device_set_ops(struct rt_device *dev,
const struct rt_dma_map_ops *ops)
{
dev->dma_ops = ops;
}
struct rt_dma_pool *rt_dma_pool_install(rt_region_t *region);
rt_err_t rt_dma_pool_extract(rt_region_t *region_list, rt_size_t list_len,
rt_size_t cma_size, rt_size_t coherent_pool_size);
#endif /* __DMA_H__ */

View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef __HWTIMER_H__
#define __HWTIMER_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Timer Control Command */
typedef enum
{
HWTIMER_CTRL_FREQ_SET = RT_DEVICE_CTRL_BASE(Timer) + 0x01, /* set the count frequency */
HWTIMER_CTRL_STOP = RT_DEVICE_CTRL_BASE(Timer) + 0x02, /* stop timer */
HWTIMER_CTRL_INFO_GET = RT_DEVICE_CTRL_BASE(Timer) + 0x03, /* get a timer feature information */
HWTIMER_CTRL_MODE_SET = RT_DEVICE_CTRL_BASE(Timer) + 0x04 /* Setting the timing mode(oneshot/period) */
} rt_hwtimer_ctrl_t;
/* Timing Mode */
typedef enum
{
HWTIMER_MODE_ONESHOT = 0x01,
HWTIMER_MODE_PERIOD
} rt_hwtimer_mode_t;
/* Time Value */
typedef struct rt_hwtimerval
{
rt_int32_t sec; /* second */
rt_int32_t usec; /* microsecond */
} rt_hwtimerval_t;
#define HWTIMER_CNTMODE_UP 0x01 /* increment count mode */
#define HWTIMER_CNTMODE_DW 0x02 /* decreasing count mode */
struct rt_hwtimer_device;
struct rt_hwtimer_ops
{
void (*init)(struct rt_hwtimer_device *timer, rt_uint32_t state);
rt_err_t (*start)(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
void (*stop)(struct rt_hwtimer_device *timer);
rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);
rt_err_t (*control)(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args);
};
/* Timer Feature Information */
struct rt_hwtimer_info
{
rt_int32_t maxfreq; /* the maximum count frequency timer support */
rt_int32_t minfreq; /* the minimum count frequency timer support */
rt_uint32_t maxcnt; /* counter maximum value */
rt_uint8_t cntmode; /* count mode (inc/dec) */
};
typedef struct rt_hwtimer_device
{
struct rt_device parent;
const struct rt_hwtimer_ops *ops;
const struct rt_hwtimer_info *info;
rt_int32_t freq; /* counting frequency set by the user */
rt_int32_t overflow; /* timer overflows */
float period_sec;
rt_int32_t cycles; /* how many times will generate a timeout event after overflow */
rt_int32_t reload; /* reload cycles(using in period mode) */
rt_hwtimer_mode_t mode; /* timing mode(oneshot/period) */
} rt_hwtimer_t;
rt_err_t rt_device_hwtimer_register(rt_hwtimer_t *timer, const char *name, void *user_data);
void rt_device_hwtimer_isr(rt_hwtimer_t *timer);
#ifdef RT_USING_DM
extern void (*rt_device_hwtimer_us_delay)(rt_uint32_t us);
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-3-08 GuEe-GUI the first version
*/
#ifndef __IIO_H__
#define __IIO_H__
void *rt_iio_channel_get_by_index(struct rt_device *dev, int index, int *out_channel);
void *rt_iio_channel_get_by_name(struct rt_device *dev, const char *name, int *out_channel);
#endif /* __IIO_H__ */

View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-03-05 bernard first version.
*/
#ifndef RT_LCD_H__
#define RT_LCD_H__
/* ioctls
0x46 is 'F' */
#define FBIOGET_VSCREENINFO 0x4600
#define FBIOPUT_VSCREENINFO 0x4601
#define FBIOGET_FSCREENINFO 0x4602
#define FBIOGET_PIXELINFO 0x4603
#define FBIOGETCMAP 0x4604
#define FBIOPUTCMAP 0x4605
#define FBIOPAN_DISPLAY 0x4606
#define FBIO_CURSOR 0x4608
/* #define FBIOGET_MONITORSPEC 0x460C */
/* #define FBIOPUT_MONITORSPEC 0x460D */
/* #define FBIOSWITCH_MONIBIT 0x460E */
#define FBIOGET_CON2FBMAP 0x460F
#define FBIOPUT_CON2FBMAP 0x4610
#define FBIOBLANK 0x4611 /* arg: 0 or vesa level + 1 */
#define FBIOGET_VBLANK 0x4612
#define FBIO_ALLOC 0x4613
#define FBIO_FREE 0x4614
#define FBIOGET_GLYPH 0x4615
#define FBIOGET_HWCINFO 0x4616
#define FBIOPUT_MODEINFO 0x4617
#define FBIOGET_DISPINFO 0x4618
#define FBIO_WAITFORVSYNC 0x4620
struct fb_bitfield
{
uint32_t offset; /* beginning of bitfield */
uint32_t length; /* length of bitfield */
uint32_t msb_right; /* != 0 : Most significant bit is */
/* right */
};
struct fb_var_screeninfo
{
uint32_t xres; /* visible resolution */
uint32_t yres;
uint32_t xres_virtual; /* virtual resolution */
uint32_t yres_virtual;
uint32_t xoffset; /* offset from virtual to visible */
uint32_t yoffset; /* resolution */
uint32_t bits_per_pixel; /* guess what */
uint32_t grayscale; /* 0 = color, 1 = grayscale, */
/* >1 = FOURCC */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */
uint32_t nonstd; /* != 0 Non standard pixel format */
uint32_t activate; /* see FB_ACTIVATE_* */
uint32_t height; /* height of picture in mm */
uint32_t width; /* width of picture in mm */
uint32_t accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
uint32_t pixclock; /* pixel clock in ps (pico seconds) */
uint32_t left_margin; /* time from sync to picture */
uint32_t right_margin; /* time from picture to sync */
uint32_t upper_margin; /* time from sync to picture */
uint32_t lower_margin;
uint32_t hsync_len; /* length of horizontal sync */
uint32_t vsync_len; /* length of vertical sync */
uint32_t sync; /* see FB_SYNC_* */
uint32_t vmode; /* see FB_VMODE_* */
uint32_t rotate; /* angle we rotate counter clockwise */
uint32_t colorspace; /* colorspace for FOURCC-based modes */
uint32_t reserved[4]; /* Reserved for future compatibility */
};
struct fb_fix_screeninfo
{
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */
uint32_t smem_len; /* Length of frame buffer mem */
uint32_t type; /* see FB_TYPE_* */
uint32_t type_aux; /* Interleave for interleaved Planes */
uint32_t visual; /* see FB_VISUAL_* */
uint16_t xpanstep; /* zero if no hardware panning */
uint16_t ypanstep; /* zero if no hardware panning */
uint16_t ywrapstep; /* zero if no hardware ywrap */
uint32_t line_length; /* length of a line in bytes */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
uint32_t mmio_len; /* Length of Memory Mapped I/O */
uint32_t accel; /* Indicate to driver which */
/* specific chip/card we have */
uint16_t capabilities; /* see FB_CAP_* */
uint16_t reserved[2]; /* Reserved for future compatibility */
};
#endif

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-3-08 GuEe-GUI the first version
*/
#ifndef __LED_H__
#define __LED_H__
#include <rthw.h>
#include <rtdef.h>
struct rt_led_ops;
enum rt_led_state
{
RT_LED_S_OFF,
RT_LED_S_ON,
RT_LED_S_TOGGLE,
RT_LED_S_BLINK,
RT_LED_STATE_NR,
};
struct rt_led_device
{
struct rt_device parent;
const struct rt_led_ops *ops;
struct rt_spinlock spinlock;
void *sysdata;
void *priv;
};
struct rt_led_ops
{
rt_err_t (*set_state)(struct rt_led_device *led, enum rt_led_state state);
rt_err_t (*get_state)(struct rt_led_device *led, enum rt_led_state *out_state);
rt_err_t (*set_period)(struct rt_led_device *led, rt_uint32_t period_ms);
rt_err_t (*set_brightness)(struct rt_led_device *led, rt_uint32_t brightness);
};
rt_err_t rt_led_register(struct rt_led_device *led);
rt_err_t rt_led_unregister(struct rt_led_device *led);
rt_err_t rt_led_set_state(struct rt_led_device *led, enum rt_led_state state);
rt_err_t rt_led_get_state(struct rt_led_device *led, enum rt_led_state *out_state);
rt_err_t rt_led_set_period(struct rt_led_device *led, rt_uint32_t period_ms);
rt_err_t rt_led_set_brightness(struct rt_led_device *led, rt_uint32_t brightness);
#endif /* __LED_H__ */

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-11 zhangsz the first version
*/
#ifndef __LPTIMER_H__
#define __LPTIMER_H__
#include <rtthread.h>
struct rt_lptimer
{
struct rt_timer timer;
rt_list_t list;
};
typedef struct rt_lptimer *rt_lptimer_t;
void rt_lptimer_init(rt_lptimer_t timer,
const char *name,
void (*timeout)(void *parameter),
void *parameter,
rt_tick_t time,
rt_uint8_t flag);
rt_err_t rt_lptimer_detach(rt_lptimer_t timer);
rt_err_t rt_lptimer_start(rt_lptimer_t timer);
rt_err_t rt_lptimer_stop(rt_lptimer_t timer);
rt_err_t rt_lptimer_control(rt_lptimer_t timer, int cmd, void *arg);
rt_tick_t rt_lptimer_next_timeout_tick(void);
#endif

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-09-23 GuEe-GUI first version
*/
#ifndef __MAILBOX_H__
#define __MAILBOX_H__
#include <rtdef.h>
#include <drivers/ofw.h>
struct rt_mbox_chan;
struct rt_mbox_client;
struct rt_mbox_controller_ops;
struct rt_mbox_controller
{
rt_list_t list;
struct rt_device *dev;
const struct rt_mbox_controller_ops *ops;
rt_size_t num_chans;
struct rt_mbox_chan *chans;
};
struct rt_mbox_controller_ops
{
rt_err_t (*request)(struct rt_mbox_chan *);
void (*release)(struct rt_mbox_chan *);
rt_err_t (*send)(struct rt_mbox_chan *, const void *data);
rt_bool_t (*peek)(struct rt_mbox_chan *);
int (*ofw_parse)(struct rt_mbox_controller *, struct rt_ofw_cell_args *);
};
struct rt_mbox_chan
{
struct rt_mbox_controller *ctrl;
struct rt_mbox_client *client;
void *data;
rt_bool_t complete;
struct rt_timer timer;
struct rt_spinlock lock;
void *priv;
};
struct rt_mbox_client
{
struct rt_device *dev;
void (*rx_callback)(struct rt_mbox_client *, void *data);
void (*tx_prepare)(struct rt_mbox_client *, const void *data);
void (*tx_done)(struct rt_mbox_client *, const void *data, rt_err_t err);
};
rt_err_t rt_mbox_controller_register(struct rt_mbox_controller *ctrl);
rt_err_t rt_mbox_controller_unregister(struct rt_mbox_controller *ctrl);
rt_err_t rt_mbox_send(struct rt_mbox_chan *chan, const void *data,
rt_uint32_t timeout_ms);
void rt_mbox_send_done(struct rt_mbox_chan *chan, rt_err_t err);
rt_bool_t rt_mbox_peek(struct rt_mbox_chan *chan);
rt_err_t rt_mbox_recv(struct rt_mbox_chan *chan, void *data);
struct rt_mbox_chan *rt_mbox_request_by_index(struct rt_mbox_client *client, int index);
struct rt_mbox_chan *rt_mbox_request_by_name(struct rt_mbox_client *client, char *name);
rt_err_t rt_mbox_release(struct rt_mbox_chan *chan);
#endif /* __MAILBOX_H__ */

View File

@ -0,0 +1,146 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __MISC_H__
#define __MISC_H__
#include <rtdef.h>
#include <cpuport.h>
#ifdef ARCH_CPU_64BIT
#define RT_BITS_PER_LONG 64
#else
#define RT_BITS_PER_LONG 32
#endif
#define RT_BITS_PER_LONG_LONG 64
#define RT_DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define RT_DIV_ROUND_CLOSEST(x, divisor) \
({ \
typeof(x) __x = x; \
typeof(divisor) __d = divisor; \
(((typeof(x))-1) > 0 || \
((typeof(divisor))-1) > 0 || \
(((__x) > 0) == ((__d) > 0))) ? \
(((__x) + ((__d) / 2)) / (__d)) : \
(((__x) - ((__d) / 2)) / (__d)); \
})
#define __KEY_PLACEHOLDER_1 0,
#define ____KEY_ENABLED(__ignored, val, ...) val
#define ___KEY_ENABLED(arg1_or_junk) ____KEY_ENABLED(arg1_or_junk 1, 0)
#define __KEY_ENABLED(value) ___KEY_ENABLED(__KEY_PLACEHOLDER_##value)
#define RT_KEY_ENABLED(key) __KEY_ENABLED(key)
#define RT_FIELD_PREP(mask, val) (((rt_uint64_t)(val) << (__rt_ffsl((mask)) - 1)) & (mask))
#define RT_FIELD_GET(mask, val) (((val) & (mask)) >> (__rt_ffsl((mask)) - 1))
#define RT_BIT(n) (1UL << (n))
#define RT_BIT_ULL(n) (1ULL << (n))
#define RT_BIT_MASK(nr) (1UL << ((nr) % RT_BITS_PER_LONG))
#define RT_BIT_WORD(nr) ((nr) / RT_BITS_PER_LONG)
#define RT_BITS_PER_BYTE 8
#define RT_BITS_PER_TYPE(type) (sizeof(type) * RT_BITS_PER_BYTE)
#define RT_BITS_TO_BYTES(nr) RT_DIV_ROUND_UP(nr, RT_BITS_PER_TYPE(char))
#define RT_BITS_TO_LONGS(nr) RT_DIV_ROUND_UP(nr, RT_BITS_PER_TYPE(long))
#define RT_GENMASK(h, l) (((~0UL) << (l)) & (~0UL >> (RT_BITS_PER_LONG - 1 - (h))))
#define RT_GENMASK_ULL(h, l) (((~0ULL) << (l)) & (~0ULL >> (RT_BITS_PER_LONG_LONG - 1 - (h))))
#define RT_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define rt_offsetof(s, field) ((rt_size_t)&((s *)0)->field)
#define rt_err_ptr(err) ((void *)(rt_base_t)(err))
#define rt_ptr_err(ptr) ((rt_err_t)(rt_base_t)(ptr))
#define rt_is_err_value(ptr) ((rt_ubase_t)(void *)(ptr) >= (rt_ubase_t)-4095)
#define rt_is_err(ptr) rt_is_err_value(ptr)
#define rt_is_err_or_null(ptr) (!(ptr) || rt_is_err_value((rt_ubase_t)(ptr)))
#define rt_upper_32_bits(n) ((rt_uint32_t)(((n) >> 16) >> 16))
#define rt_lower_32_bits(n) ((rt_uint32_t)((n) & 0xffffffff))
#define rt_upper_16_bits(n) ((rt_uint16_t)((n) >> 16))
#define rt_lower_16_bits(n) ((rt_uint16_t)((n) & 0xffff))
#define rt_min(x, y) \
({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x < _y ? _x : _y; \
})
#define rt_max(x, y) \
({ \
typeof(x) _x = (x); \
typeof(y) _y = (y); \
(void) (&_x == &_y); \
_x > _y ? _x : _y; \
})
#define rt_min_t(type, x, y) \
({ \
type _x = (x); \
type _y = (y); \
_x < _y ? _x: _y; \
})
#define rt_max_t(type, x, y) \
({ \
type _x = (x); \
type _y = (y); \
_x > _y ? _x: _y; \
})
#define rt_clamp(val, lo, hi) rt_min((typeof(val))rt_max(val, lo), hi)
#define rt_do_div(n, base) \
({ \
rt_uint32_t _base = (base), _rem; \
_rem = ((rt_uint64_t)(n)) % _base; \
(n) = ((rt_uint64_t)(n)) / _base; \
if (_rem > _base / 2) \
++(n); \
_rem; \
})
#define rt_abs(x) \
({ \
long ret; \
if (sizeof(x) == sizeof(long)) \
{ \
long __x = (x); \
ret = (__x < 0) ? -__x : __x; \
} \
else \
{ \
int __x = (x); \
ret = (__x < 0) ? -__x : __x; \
} \
ret; \
})
#ifndef rt_ilog2
rt_inline int rt_ilog2(rt_ubase_t v)
{
int l = 0;
while ((1UL << l) < v)
{
l++;
}
return l;
}
#endif /* !rt_ilog2 */
#endif /* __MISC_H__ */

View File

@ -0,0 +1,230 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-07-25 weety first version
* 2024-05-24 HPMicro add HS400 support
* 2024-05-26 HPMicro add UHS-I support for SD card
*/
#ifndef __MMCSD_CARD_H__
#define __MMCSD_CARD_H__
#include <drivers/mmcsd_host.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SD_SCR_BUS_WIDTH_1 (1 << 0)
#define SD_SCR_BUS_WIDTH_4 (1 << 2)
struct rt_mmcsd_cid {
rt_uint8_t mid; /* ManufacturerID */
rt_uint8_t prv; /* Product Revision */
rt_uint16_t oid; /* OEM/Application ID */
rt_uint32_t psn; /* Product Serial Number */
rt_uint8_t pnm[5]; /* Product Name */
rt_uint8_t reserved1;/* reserved */
rt_uint16_t mdt; /* Manufacturing Date */
rt_uint8_t crc; /* CID CRC */
rt_uint8_t reserved2;/* not used, always 1 */
};
struct rt_mmcsd_csd {
rt_uint8_t csd_structure; /* CSD register version */
rt_uint8_t taac;
rt_uint8_t nsac;
rt_uint8_t tran_speed; /* max data transfer rate */
rt_uint16_t card_cmd_class; /* card command classes */
rt_uint8_t rd_blk_len; /* max read data block length */
rt_uint8_t rd_blk_part;
rt_uint8_t wr_blk_misalign;
rt_uint8_t rd_blk_misalign;
rt_uint8_t dsr_imp; /* DSR implemented */
rt_uint8_t c_size_mult; /* CSD 1.0 , device size multiplier */
rt_uint32_t c_size; /* device size */
rt_uint8_t r2w_factor;
rt_uint8_t wr_blk_len; /* max wtire data block length */
rt_uint8_t wr_blk_partial;
rt_uint8_t csd_crc;
};
struct rt_sd_scr {
rt_uint8_t sd_version;
rt_uint8_t sd_bus_widths;
};
struct rt_sdio_cccr {
rt_uint8_t sdio_version;
rt_uint8_t sd_version;
rt_uint8_t direct_cmd:1, /* Card Supports Direct Commands during data transfer
only SD mode, not used for SPI mode */
multi_block:1, /* Card Supports Multi-Block */
read_wait:1, /* Card Supports Read Wait
only SD mode, not used for SPI mode */
suspend_resume:1, /* Card supports Suspend/Resume
only SD mode, not used for SPI mode */
s4mi:1, /* generate interrupts during a 4-bit
multi-block data transfer */
e4mi:1, /* Enable the multi-block IRQ during
4-bit transfer for the SDIO card */
low_speed:1, /* Card is a Low-Speed card */
low_speed_4:1; /* 4-bit support for Low-Speed cards */
rt_uint8_t bus_width:1, /* Support SDIO bus width, 1:4bit, 0:1bit */
cd_disable:1, /* Connect[0]/Disconnect[1] the 10K-90K ohm pull-up
resistor on CD/DAT[3] (pin 1) of the card */
power_ctrl:1, /* Support Master Power Control */
high_speed:1; /* Support High-Speed */
};
/*
* SD Status
*/
union rt_sd_status {
rt_uint32_t status_words[16];
struct {
rt_uint32_t reserved[12];
rt_uint64_t : 8;
rt_uint64_t uhs_au_size: 4;
rt_uint64_t uhs_speed_grade: 4;
rt_uint64_t erase_offset: 2;
rt_uint64_t erase_timeout: 6;
rt_uint64_t erase_size: 16;
rt_uint64_t : 4;
rt_uint64_t au_size: 4;
rt_uint64_t performance_move: 8;
rt_uint64_t speed_class: 8;
rt_uint32_t size_of_protected_area;
rt_uint32_t sd_card_type: 16;
rt_uint32_t : 6;
rt_uint32_t : 7;
rt_uint32_t secured_mode: 1;
rt_uint32_t data_bus_width: 2;
};
};
/*
* SD Speed Class
*/
#define SD_SPEED_CLASS_0 0
#define SD_SPEED_CLASS_2 1
#define SD_SPEED_CLASS_4 2
#define SD_SPEED_CLASS_6 3
#define SD_SPEED_CLASS_10 4
/*
* UHS Speed Grade
*/
#define UHS_SPEED_GRADE_0 0
#define UHS_SPEED_GRADE_1 1
#define UHS_SPEED_GRADE_3 3
struct rt_sdio_cis {
rt_uint16_t manufacturer;
rt_uint16_t product;
rt_uint16_t func0_blk_size;
rt_uint32_t max_tran_speed;
};
/*
* SDIO function CIS tuple (unknown to the core)
*/
struct rt_sdio_function_tuple {
struct rt_sdio_function_tuple *next;
rt_uint8_t code;
rt_uint8_t size;
rt_uint8_t *data;
};
struct rt_sdio_function;
typedef void (rt_sdio_irq_handler_t)(struct rt_sdio_function *);
/*
* SDIO function devices
*/
struct rt_sdio_function {
struct rt_mmcsd_card *card; /* the card this device belongs to */
rt_sdio_irq_handler_t *irq_handler; /* IRQ callback */
rt_uint8_t num; /* function number */
rt_uint8_t func_code; /* Standard SDIO Function interface code */
rt_uint16_t manufacturer; /* manufacturer id */
rt_uint16_t product; /* product id */
rt_uint32_t max_blk_size; /* maximum block size */
rt_uint32_t cur_blk_size; /* current block size */
rt_uint32_t enable_timeout_val; /* max enable timeout in msec */
struct rt_sdio_function_tuple *tuples;
void *priv;
};
#define SDIO_MAX_FUNCTIONS 7
struct rt_mmc_ext_csd
{
rt_uint32_t cache_size;
rt_uint32_t enhanced_data_strobe;
};
struct rt_mmcsd_card {
struct rt_mmcsd_host *host;
rt_uint32_t rca; /* card addr */
rt_uint32_t resp_cid[4]; /* card CID register */
rt_uint32_t resp_csd[4]; /* card CSD register */
rt_uint32_t resp_scr[2]; /* card SCR register */
rt_uint16_t tacc_clks; /* data access time by ns */
rt_uint32_t tacc_ns; /* data access time by clk cycles */
rt_uint32_t max_data_rate; /* max data transfer rate */
rt_uint32_t card_capacity; /* card capacity, unit:KB */
rt_uint32_t card_blksize; /* card block size */
rt_uint32_t card_sec_cnt; /* card sector count*/
rt_uint32_t erase_size; /* erase size in sectors */
rt_uint16_t card_type;
#define CARD_TYPE_MMC 0 /* MMC card */
#define CARD_TYPE_SD 1 /* SD card */
#define CARD_TYPE_SDIO 2 /* SDIO card */
#define CARD_TYPE_SDIO_COMBO 3 /* SD combo (IO+mem) card */
rt_uint16_t flags;
#define CARD_FLAG_HIGHSPEED (1 << 0) /* SDIO bus speed 50MHz */
#define CARD_FLAG_SDHC (1 << 1) /* SDHC card */
#define CARD_FLAG_SDXC (1 << 2) /* SDXC card */
#define CARD_FLAG_HIGHSPEED_DDR (1 << 3) /* HIGH SPEED DDR */
#define CARD_FLAG_HS200 (1 << 4) /* BUS SPEED 200MHz */
#define CARD_FLAG_HS400 (1 << 5) /* BUS SPEED 400MHz */
#define CARD_FLAG_SDR50 (1 << 6) /* BUS SPEED 100MHz */
#define CARD_FLAG_SDR104 (1 << 7) /* BUS SPEED 200MHz */
#define CARD_FLAG_DDR50 (1 << 8) /* DDR50, works on 1.8V only */
struct rt_sd_scr scr;
struct rt_mmcsd_csd csd;
rt_uint32_t hs_max_data_rate; /* max data transfer rate in high speed mode */
rt_uint8_t sdio_function_num; /* total number of SDIO functions */
struct rt_sdio_cccr cccr; /* common card info */
struct rt_sdio_cis cis; /* common tuple info */
struct rt_sdio_function *sdio_function[SDIO_MAX_FUNCTIONS + 1]; /* SDIO functions (devices) */
void *blk_dev;
struct rt_mmc_ext_csd ext_csd;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-07-25 weety first version
* 2024-05-26 HPMicro add VOLTAGE_SWITCH definition
*/
#ifndef __CMD_H__
#define __CMD_H__
#ifdef __cplusplus
extern "C" {
#endif
/* class 1 */
#define GO_IDLE_STATE 0 /* bc */
#define SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
#define ALL_SEND_CID 2 /* bcr R2 */
#define SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
#define SET_DSR 4 /* bc [31:16] RCA */
#define SWITCH 6 /* ac [31:0] See below R1b */
#define SELECT_CARD 7 /* ac [31:16] RCA R1 */
#define SEND_EXT_CSD 8 /* adtc R1 */
#define SEND_CSD 9 /* ac [31:16] RCA R2 */
#define SEND_CID 10 /* ac [31:16] RCA R2 */
#define VOLTAGE_SWITCH 11 /* ac [31:0] R1 */
#define STOP_TRANSMISSION 12 /* ac R1b */
#define SEND_STATUS 13 /* ac [31:16] RCA R1 */
#define GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
#define SPI_READ_OCR 58 /* spi spi_R3 */
#define SPI_CRC_ON_OFF 59 /* spi [0:0] flag spi_R1 */
/* class 2 */
#define SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
#define READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define SEND_TUNING_BLOCK 19 /* adtc R1 */
#define SEND_TUNING_BLOCK_HS200 21 /* adtc R1*/
/* class 3 */
#define WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
/* class 4 */
#define SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
#define WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
#define WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
#define PROGRAM_CID 26 /* adtc R1 */
#define PROGRAM_CSD 27 /* adtc R1 */
/* class 6 */
#define SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
#define CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
#define SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
/* class 5 */
#define ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
#define ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
#define ERASE 38 /* ac R1b */
/* class 9 */
#define FAST_IO 39 /* ac <Complex> R4 */
#define GO_IRQ_STATE 40 /* bcr R5 */
/* class 7 */
#define LOCK_UNLOCK 42 /* adtc R1b */
/* class 8 */
#define APP_CMD 55 /* ac [31:16] RCA R1 */
#define GEN_CMD 56 /* adtc [0] RD/WR R1 */
/* SD commands type argument response */
/* class 0 */
/* This is basically the same command as for MMC with some quirks. */
#define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */
#define SD_SEND_IF_COND 8 /* bcr [11:0] See below R7 */
/* class 10 */
#define SD_SWITCH 6 /* adtc [31:0] See below R1 */
/* Application commands */
#define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */
#define SD_APP_SEND_NUM_WR_BLKS 22 /* adtc R1 */
#define SD_APP_OP_COND 41 /* bcr [31:0] OCR R3 */
#define SD_APP_SEND_SCR 51 /* adtc R1 */
#define SCR_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.01 */
#define SCR_SPEC_VER_1 1 /* Implements system specification 1.10 */
#define SCR_SPEC_VER_2 2 /* Implements system specification 2.00 */
/* SDIO commands type argument response */
#define SD_IO_SEND_OP_COND 5 /* bcr [23:0] OCR R4 */
#define SD_IO_RW_DIRECT 52 /* ac [31:0] See below R5 */
#define SD_IO_RW_EXTENDED 53 /* adtc [31:0] See below R5 */
/* CMD52 arguments */
#define SDIO_ARG_CMD52_READ (0<<31)
#define SDIO_ARG_CMD52_WRITE (1u<<31)
#define SDIO_ARG_CMD52_FUNC_SHIFT 28
#define SDIO_ARG_CMD52_FUNC_MASK 0x7
#define SDIO_ARG_CMD52_RAW_FLAG (1u<<27)
#define SDIO_ARG_CMD52_REG_SHIFT 9
#define SDIO_ARG_CMD52_REG_MASK 0x1ffff
#define SDIO_ARG_CMD52_DATA_SHIFT 0
#define SDIO_ARG_CMD52_DATA_MASK 0xff
#define SDIO_R5_DATA(resp) ((resp)[0] & 0xff)
/* CMD53 arguments */
#define SDIO_ARG_CMD53_READ (0<<31)
#define SDIO_ARG_CMD53_WRITE (1u<<31)
#define SDIO_ARG_CMD53_FUNC_SHIFT 28
#define SDIO_ARG_CMD53_FUNC_MASK 0x7
#define SDIO_ARG_CMD53_BLOCK_MODE (1u<<27)
#define SDIO_ARG_CMD53_INCREMENT (1u<<26)
#define SDIO_ARG_CMD53_REG_SHIFT 9
#define SDIO_ARG_CMD53_REG_MASK 0x1ffff
#define SDIO_ARG_CMD53_LENGTH_SHIFT 0
#define SDIO_ARG_CMD53_LENGTH_MASK 0x1ff
#define SDIO_ARG_CMD53_LENGTH_MAX 511
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,167 @@
/*
* Copyright (c) 2006-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-07-25 weety first version
* 2024-05-25 HPMicro add HS400 support
* 2024-05-26 HPMicro add UHS-I support
*/
#ifndef __HOST_H__
#define __HOST_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
struct rt_mmcsd_io_cfg
{
rt_uint32_t clock; /* clock rate */
rt_uint16_t vdd;
/* vdd stores the bit number of the selected voltage range from below. */
rt_uint8_t bus_mode; /* command output mode */
#define MMCSD_BUSMODE_OPENDRAIN 1
#define MMCSD_BUSMODE_PUSHPULL 2
rt_uint8_t chip_select; /* SPI chip select */
#define MMCSD_CS_IGNORE 0
#define MMCSD_CS_HIGH 1
#define MMCSD_CS_LOW 2
rt_uint8_t power_mode; /* power supply mode */
#define MMCSD_POWER_OFF 0
#define MMCSD_POWER_UP 1
#define MMCSD_POWER_ON 2
rt_uint8_t bus_width; /* data bus width */
#define MMCSD_BUS_WIDTH_1 0
#define MMCSD_BUS_WIDTH_4 2
#define MMCSD_BUS_WIDTH_8 3
unsigned char timing; /* timing specification used */
#define MMCSD_TIMING_LEGACY 0
#define MMCSD_TIMING_MMC_HS 1
#define MMCSD_TIMING_SD_HS 2
#define MMCSD_TIMING_UHS_SDR12 3
#define MMCSD_TIMING_UHS_SDR25 4
#define MMCSD_TIMING_UHS_SDR50 5
#define MMCSD_TIMING_UHS_SDR104 6
#define MMCSD_TIMING_UHS_DDR50 7
#define MMCSD_TIMING_MMC_DDR52 8
#define MMCSD_TIMING_MMC_HS200 9
#define MMCSD_TIMING_MMC_HS400 10
#define MMCSD_TIMING_MMC_HS400_ENH_DS 11
unsigned char drv_type; /* driver type (A, B, C, D) */
#define MMCSD_SET_DRIVER_TYPE_B 0
#define MMCSD_SET_DRIVER_TYPE_A 1
#define MMCSD_SET_DRIVER_TYPE_C 2
#define MMCSD_SET_DRIVER_TYPE_D 3
unsigned char signal_voltage;
#define MMCSD_SIGNAL_VOLTAGE_330 0
#define MMCSD_SIGNAL_VOLTAGE_180 1
#define MMCSD_SIGNAL_VOLTAGE_120 2
};
struct rt_mmcsd_host;
struct rt_mmcsd_req;
struct rt_mmcsd_host_ops
{
void (*request)(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req);
void (*set_iocfg)(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg);
rt_int32_t (*get_card_status)(struct rt_mmcsd_host *host);
void (*enable_sdio_irq)(struct rt_mmcsd_host *host, rt_int32_t en);
rt_int32_t (*execute_tuning)(struct rt_mmcsd_host *host, rt_int32_t opcode);
rt_int32_t (*switch_uhs_voltage)(struct rt_mmcsd_host *host);
};
struct rt_mmcsd_host
{
char name[RT_NAME_MAX];
struct rt_mmcsd_card *card;
const struct rt_mmcsd_host_ops *ops;
rt_uint32_t freq_min;
rt_uint32_t freq_max;
struct rt_mmcsd_io_cfg io_cfg;
rt_uint32_t valid_ocr; /* current valid OCR */
#define VDD_165_195 (1 << 7) /* VDD voltage 1.65 - 1.95 */
#define VDD_20_21 (1 << 8) /* VDD voltage 2.0 ~ 2.1 */
#define VDD_21_22 (1 << 9) /* VDD voltage 2.1 ~ 2.2 */
#define VDD_22_23 (1 << 10) /* VDD voltage 2.2 ~ 2.3 */
#define VDD_23_24 (1 << 11) /* VDD voltage 2.3 ~ 2.4 */
#define VDD_24_25 (1 << 12) /* VDD voltage 2.4 ~ 2.5 */
#define VDD_25_26 (1 << 13) /* VDD voltage 2.5 ~ 2.6 */
#define VDD_26_27 (1 << 14) /* VDD voltage 2.6 ~ 2.7 */
#define VDD_27_28 (1 << 15) /* VDD voltage 2.7 ~ 2.8 */
#define VDD_28_29 (1 << 16) /* VDD voltage 2.8 ~ 2.9 */
#define VDD_29_30 (1 << 17) /* VDD voltage 2.9 ~ 3.0 */
#define VDD_30_31 (1 << 18) /* VDD voltage 3.0 ~ 3.1 */
#define VDD_31_32 (1 << 19) /* VDD voltage 3.1 ~ 3.2 */
#define VDD_32_33 (1 << 20) /* VDD voltage 3.2 ~ 3.3 */
#define VDD_33_34 (1 << 21) /* VDD voltage 3.3 ~ 3.4 */
#define VDD_34_35 (1 << 22) /* VDD voltage 3.4 ~ 3.5 */
#define VDD_35_36 (1 << 23) /* VDD voltage 3.5 ~ 3.6 */
#define OCR_S18R (1 << 24) /* Switch to 1V8 Request */
rt_uint32_t flags; /* define device capabilities */
#define MMCSD_BUSWIDTH_4 (1 << 0)
#define MMCSD_BUSWIDTH_8 (1 << 1)
#define MMCSD_MUTBLKWRITE (1 << 2)
#define MMCSD_HOST_IS_SPI (1 << 3)
#define controller_is_spi(host) (host->flags & MMCSD_HOST_IS_SPI)
#define MMCSD_SUP_SDIO_IRQ (1 << 4) /* support signal pending SDIO IRQs */
#define MMCSD_SUP_HIGHSPEED (1 << 5) /* support high speed SDR */
#define MMCSD_SUP_DDR_3V3 (1 << 6)
#define MMCSD_SUP_DDR_1V8 (1 << 7)
#define MMCSD_SUP_DDR_1V2 (1 << 8)
#define MMCSD_SUP_HIGHSPEED_DDR (MMCSD_SUP_DDR_3V3 | MMCSD_SUP_DDR_1V8 | MMCSD_SUP_DDR_1V2)/* HIGH SPEED DDR */
#define MMCSD_SUP_HS200_1V8 (1 << 9)
#define MMCSD_SUP_HS200_1V2 (1 << 10)
#define MMCSD_SUP_HS200 (MMCSD_SUP_HS200_1V2 | MMCSD_SUP_HS200_1V8) /* hs200 sdr */
#define MMCSD_SUP_NONREMOVABLE (1 << 11)
#define controller_is_removable(host) (!(host->flags & MMCSD_SUP_NONREMOVABLE))
#define MMCSD_SUP_HS400_1V8 (1 << 12)
#define MMCSD_SUP_HS400_1V2 (1 << 13)
#define MMCSD_SUP_HS400 (MMCSD_SUP_HS400_1V2 | MMCSD_SUP_HS400_1V8) /* hs400 ddr */
#define MMCSD_SUP_ENH_DS (1 << 14)
#define MMCSD_SUP_SDR50 (1 << 15)
#define MMCSD_SUP_SDR104 (1 << 16)
#define MMCSD_SUP_DDR50 (1 << 17)
rt_uint32_t max_seg_size; /* maximum size of one dma segment */
rt_uint32_t max_dma_segs; /* maximum number of dma segments in one request */
rt_uint32_t max_blk_size; /* maximum block size */
rt_uint32_t max_blk_count; /* maximum block count */
rt_uint32_t id; /* Assigned host id */
rt_uint32_t spi_use_crc;
struct rt_mutex bus_lock;
struct rt_semaphore sem_ack;
rt_uint32_t sdio_irq_num;
struct rt_semaphore *sdio_irq_sem;
struct rt_thread *sdio_irq_thread;
void *private_data;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-12-05 Bernard the first version
* 2011-04-02 prife add mark_badblock and check_block
*/
/*
* COPYRIGHT (C) 2012, Shanghai Real Thread
*/
#ifndef __MTD_NAND_H__
#define __MTD_NAND_H__
#include <rtthread.h>
struct rt_mtd_nand_driver_ops;
#define RT_MTD_NAND_DEVICE(device) ((struct rt_mtd_nand_device*)(device))
#define RT_MTD_EOK 0 /* NO error */
#define RT_MTD_EECC 101 /* ECC error */
#define RT_MTD_EBUSY 102 /* hardware busy */
#define RT_MTD_EIO 103 /* generic IO issue */
#define RT_MTD_ENOMEM 104 /* out of memory */
#define RT_MTD_ESRC 105 /* source issue */
#define RT_MTD_EECC_CORRECT 106 /* ECC error but correct */
struct rt_mtd_nand_device
{
struct rt_device parent;
rt_uint16_t page_size; /* The Page size in the flash */
rt_uint16_t oob_size; /* Out of bank size */
rt_uint16_t oob_free; /* the free area in oob that flash driver not use */
rt_uint16_t plane_num; /* the number of plane in the NAND Flash */
rt_uint32_t pages_per_block; /* The number of page a block */
rt_uint16_t block_total;
/* Only be touched by driver */
rt_uint32_t block_start; /* The start of available block*/
rt_uint32_t block_end; /* The end of available block */
/* operations interface */
const struct rt_mtd_nand_driver_ops *ops;
void *priv;
};
typedef struct rt_mtd_nand_device* rt_mtd_nand_t;
struct rt_mtd_nand_driver_ops
{
rt_err_t (*read_id)(struct rt_mtd_nand_device *device);
rt_err_t (*read_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
rt_uint8_t *data, rt_uint32_t data_len,
rt_uint8_t *spare, rt_uint32_t spare_len);
rt_err_t (*write_page)(struct rt_mtd_nand_device *device,
rt_off_t page,
const rt_uint8_t *data, rt_uint32_t data_len,
const rt_uint8_t *spare, rt_uint32_t spare_len);
rt_err_t (*move_page)(struct rt_mtd_nand_device *device, rt_off_t src_page, rt_off_t dst_page);
rt_err_t (*erase_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
rt_err_t (*check_block)(struct rt_mtd_nand_device *device, rt_uint32_t block);
rt_err_t (*mark_badblock)(struct rt_mtd_nand_device *device, rt_uint32_t block);
};
rt_err_t rt_mtd_nand_register_device(const char *name, struct rt_mtd_nand_device *device);
rt_uint32_t rt_mtd_nand_read_id(struct rt_mtd_nand_device *device);
rt_err_t rt_mtd_nand_read(
struct rt_mtd_nand_device *device,
rt_off_t page,
rt_uint8_t *data, rt_uint32_t data_len,
rt_uint8_t *spare, rt_uint32_t spare_len);
rt_err_t rt_mtd_nand_write(
struct rt_mtd_nand_device *device,
rt_off_t page,
const rt_uint8_t *data, rt_uint32_t data_len,
const rt_uint8_t *spare, rt_uint32_t spare_len);
rt_err_t rt_mtd_nand_move_page(struct rt_mtd_nand_device *device,
rt_off_t src_page, rt_off_t dst_page);
rt_err_t rt_mtd_nand_erase_block(struct rt_mtd_nand_device *device, rt_uint32_t block);
rt_err_t rt_mtd_nand_check_block(struct rt_mtd_nand_device *device, rt_uint32_t block);
rt_err_t rt_mtd_nand_mark_badblock(struct rt_mtd_nand_device *device, rt_uint32_t block);
#endif /* MTD_NAND_H_ */

View File

@ -0,0 +1,50 @@
/*
* COPYRIGHT (C) 2011-2023, Real-Thread Information Technology Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-5-30 Bernard the first version
*/
#ifndef __MTD_NOR_H__
#define __MTD_NOR_H__
#include <rtthread.h>
struct rt_mtd_nor_driver_ops;
#define RT_MTD_NOR_DEVICE(device) ((struct rt_mtd_nor_device*)(device))
struct rt_mtd_nor_device
{
struct rt_device parent;
rt_uint32_t block_size; /* The Block size in the flash */
rt_uint32_t block_start; /* The start of available block*/
rt_uint32_t block_end; /* The end of available block */
/* operations interface */
const struct rt_mtd_nor_driver_ops* ops;
};
struct rt_mtd_nor_driver_ops
{
rt_err_t (*read_id) (struct rt_mtd_nor_device* device);
rt_ssize_t (*read) (struct rt_mtd_nor_device* device, rt_off_t offset, rt_uint8_t* data, rt_size_t length);
rt_ssize_t (*write) (struct rt_mtd_nor_device* device, rt_off_t offset, const rt_uint8_t* data, rt_size_t length);
rt_err_t (*erase_block)(struct rt_mtd_nor_device* device, rt_off_t offset, rt_size_t length);
};
rt_err_t rt_mtd_nor_register_device(const char* name, struct rt_mtd_nor_device* device);
rt_uint32_t rt_mtd_nor_read_id(struct rt_mtd_nor_device* device);
rt_ssize_t rt_mtd_nor_read(struct rt_mtd_nor_device* device,
rt_off_t offset, rt_uint8_t* data, rt_size_t length);
rt_ssize_t rt_mtd_nor_write(struct rt_mtd_nor_device* device,
rt_off_t offset, const rt_uint8_t* data, rt_size_t length);
rt_err_t rt_mtd_nor_erase_block(struct rt_mtd_nor_device* device,
rt_off_t offset, rt_size_t length);
#endif

View File

@ -0,0 +1,899 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __NVME_H__
#define __NVME_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/blk.h>
#define NVME_RSVD(offset, bytes_size) rt_uint8_t __rsvd##offset[bytes_size]
enum
{
/*
* Generic Command Status:
*/
RT_NVME_SC_SUCCESS = 0x0,
RT_NVME_SC_INVALID_OPCODE = 0x1,
RT_NVME_SC_INVALID_FIELD = 0x2,
RT_NVME_SC_CMDID_CONFLICT = 0x3,
RT_NVME_SC_DATA_XFER_ERROR = 0x4,
RT_NVME_SC_POWER_LOSS = 0x5,
RT_NVME_SC_INTERNAL = 0x6,
RT_NVME_SC_ABORT_REQ = 0x7,
RT_NVME_SC_ABORT_QUEUE = 0x8,
RT_NVME_SC_FUSED_FAIL = 0x9,
RT_NVME_SC_FUSED_MISSING = 0xa,
RT_NVME_SC_INVALID_NS = 0xb,
RT_NVME_SC_CMD_SEQ_ERROR = 0xc,
RT_NVME_SC_SGL_INVALID_LAST = 0xd,
RT_NVME_SC_SGL_INVALID_COUNT = 0xe,
RT_NVME_SC_SGL_INVALID_DATA = 0xf,
RT_NVME_SC_SGL_INVALID_METADATA = 0x10,
RT_NVME_SC_SGL_INVALID_TYPE = 0x11,
RT_NVME_SC_CMB_INVALID_USE = 0x12,
RT_NVME_SC_PRP_INVALID_OFFSET = 0x13,
RT_NVME_SC_ATOMIC_WU_EXCEEDED = 0x14,
RT_NVME_SC_OP_DENIED = 0x15,
RT_NVME_SC_SGL_INVALID_OFFSET = 0x16,
RT_NVME_SC_RESERVED = 0x17,
RT_NVME_SC_HOST_ID_INCONSIST = 0x18,
RT_NVME_SC_KA_TIMEOUT_EXPIRED = 0x19,
RT_NVME_SC_KA_TIMEOUT_INVALID = 0x1a,
RT_NVME_SC_ABORTED_PREEMPT_ABORT = 0x1b,
RT_NVME_SC_SANITIZE_FAILED = 0x1c,
RT_NVME_SC_SANITIZE_IN_PROGRESS = 0x1d,
RT_NVME_SC_SGL_INVALID_GRANULARITY = 0x1e,
RT_NVME_SC_CMD_NOT_SUP_CMB_QUEUE = 0x1f,
RT_NVME_SC_NS_WRITE_PROTECTED = 0x20,
RT_NVME_SC_CMD_INTERRUPTED = 0x21,
RT_NVME_SC_TRANSIENT_TR_ERR = 0x22,
RT_NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY = 0x24,
RT_NVME_SC_INVALID_IO_CMD_SET = 0x2c,
RT_NVME_SC_LBA_RANGE = 0x80,
RT_NVME_SC_CAP_EXCEEDED = 0x81,
RT_NVME_SC_NS_NOT_READY = 0x82,
RT_NVME_SC_RESERVATION_CONFLICT = 0x83,
RT_NVME_SC_FORMAT_IN_PROGRESS = 0x84,
/*
* Command Specific Status:
*/
RT_NVME_SC_CQ_INVALID = 0x100,
RT_NVME_SC_QID_INVALID = 0x101,
RT_NVME_SC_QUEUE_SIZE = 0x102,
RT_NVME_SC_ABORT_LIMIT = 0x103,
RT_NVME_SC_ABORT_MISSING = 0x104,
RT_NVME_SC_ASYNC_LIMIT = 0x105,
RT_NVME_SC_FIRMWARE_SLOT = 0x106,
RT_NVME_SC_FIRMWARE_IMAGE = 0x107,
RT_NVME_SC_INVALID_VECTOR = 0x108,
RT_NVME_SC_INVALID_LOG_PAGE = 0x109,
RT_NVME_SC_INVALID_FORMAT = 0x10a,
RT_NVME_SC_FW_NEEDS_CONV_RESET = 0x10b,
RT_NVME_SC_INVALID_QUEUE = 0x10c,
RT_NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d,
RT_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e,
RT_NVME_SC_FEATURE_NOT_PER_NS = 0x10f,
RT_NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x110,
RT_NVME_SC_FW_NEEDS_RESET = 0x111,
RT_NVME_SC_FW_NEEDS_MAX_TIME = 0x112,
RT_NVME_SC_FW_ACTIVATE_PROHIBITED = 0x113,
RT_NVME_SC_OVERLAPPING_RANGE = 0x114,
RT_NVME_SC_NS_INSUFFICIENT_CAP = 0x115,
RT_NVME_SC_NS_ID_UNAVAILABLE = 0x116,
RT_NVME_SC_NS_ALREADY_ATTACHED = 0x118,
RT_NVME_SC_NS_IS_PRIVATE = 0x119,
RT_NVME_SC_NS_NOT_ATTACHED = 0x11a,
RT_NVME_SC_THIN_PROV_NOT_SUPP = 0x11b,
RT_NVME_SC_CTRL_LIST_INVALID = 0x11c,
RT_NVME_SC_SELT_TEST_IN_PROGRESS = 0x11d,
RT_NVME_SC_BP_WRITE_PROHIBITED = 0x11e,
RT_NVME_SC_CTRL_ID_INVALID = 0x11f,
RT_NVME_SC_SEC_CTRL_STATE_INVALID = 0x120,
RT_NVME_SC_CTRL_RES_NUM_INVALID = 0x121,
RT_NVME_SC_RES_ID_INVALID = 0x122,
RT_NVME_SC_PMR_SAN_PROHIBITED = 0x123,
RT_NVME_SC_ANA_GROUP_ID_INVALID = 0x124,
RT_NVME_SC_ANA_ATTACH_FAILED = 0x125,
/*
* I/O Command Set Specific - NVM commands:
*/
RT_NVME_SC_BAD_ATTRIBUTES = 0x180,
RT_NVME_SC_INVALID_PI = 0x181,
RT_NVME_SC_READ_ONLY = 0x182,
RT_NVME_SC_ONCS_NOT_SUPPORTED = 0x183,
/*
* I/O Command Set Specific - Fabrics commands:
*/
RT_NVME_SC_CONNECT_FORMAT = 0x180,
RT_NVME_SC_CONNECT_CTRL_BUSY = 0x181,
RT_NVME_SC_CONNECT_INVALID_PARAM = 0x182,
RT_NVME_SC_CONNECT_RESTART_DISC = 0x183,
RT_NVME_SC_CONNECT_INVALID_HOST = 0x184,
RT_NVME_SC_DISCOVERY_RESTART = 0x190,
RT_NVME_SC_AUTH_REQUIRED = 0x191,
/*
* I/O Command Set Specific - Zoned commands:
*/
RT_NVME_SC_ZONE_BOUNDARY_ERROR = 0x1b8,
RT_NVME_SC_ZONE_FULL = 0x1b9,
RT_NVME_SC_ZONE_READ_ONLY = 0x1ba,
RT_NVME_SC_ZONE_OFFLINE = 0x1bb,
RT_NVME_SC_ZONE_INVALID_WRITE = 0x1bc,
RT_NVME_SC_ZONE_TOO_MANY_ACTIVE = 0x1bd,
RT_NVME_SC_ZONE_TOO_MANY_OPEN = 0x1be,
RT_NVME_SC_ZONE_INVALID_TRANSITION = 0x1bf,
/*
* Media and Data Integrity Errors:
*/
RT_NVME_SC_WRITE_FAULT = 0x280,
RT_NVME_SC_READ_ERROR = 0x281,
RT_NVME_SC_GUARD_CHECK = 0x282,
RT_NVME_SC_APPTAG_CHECK = 0x283,
RT_NVME_SC_REFTAG_CHECK = 0x284,
RT_NVME_SC_COMPARE_FAILED = 0x285,
RT_NVME_SC_ACCESS_DENIED = 0x286,
RT_NVME_SC_UNWRITTEN_BLOCK = 0x287,
/*
* Path-related Errors:
*/
RT_NVME_SC_INTERNAL_PATH_ERROR = 0x300,
RT_NVME_SC_ANA_PERSISTENT_LOSS = 0x301,
RT_NVME_SC_ANA_INACCESSIBLE = 0x302,
RT_NVME_SC_ANA_TRANSITION = 0x303,
RT_NVME_SC_CTRL_PATH_ERROR = 0x360,
RT_NVME_SC_HOST_PATH_ERROR = 0x370,
RT_NVME_SC_HOST_ABORTED_CMD = 0x371,
RT_NVME_SC_CRD = 0x1800,
RT_NVME_SC_MORE = 0x2000,
RT_NVME_SC_DNR = 0x4000,
};
/* Admin commands */
enum
{
RT_NVME_ADMIN_OPCODE_DELETE_SQ = 0x00,
RT_NVME_ADMIN_OPCODE_CREATE_SQ = 0x01,
RT_NVME_ADMIN_OPCODE_GET_LOG_PAGE = 0x02,
RT_NVME_ADMIN_OPCODE_DELETE_CQ = 0x04,
RT_NVME_ADMIN_OPCODE_CREATE_CQ = 0x05,
RT_NVME_ADMIN_OPCODE_IDENTIFY = 0x06,
RT_NVME_ADMIN_OPCODE_ABORT_CMD = 0x08,
RT_NVME_ADMIN_OPCODE_SET_FEATURES = 0x09,
RT_NVME_ADMIN_OPCODE_GET_FEATURES = 0x0a,
RT_NVME_ADMIN_OPCODE_ASYNC_EVENT = 0x0c,
RT_NVME_ADMIN_OPCODE_NS_MGMT = 0x0d,
RT_NVME_ADMIN_OPCODE_ACTIVATE_FW = 0x10,
RT_NVME_ADMIN_OPCODE_DOWNLOAD_FW = 0x11,
RT_NVME_ADMIN_OPCODE_DEV_SELF_TEST = 0x14,
RT_NVME_ADMIN_OPCODE_NS_ATTACH = 0x15,
RT_NVME_ADMIN_OPCODE_KEEP_ALIVE = 0x18,
RT_NVME_ADMIN_OPCODE_DIRECTIVE_SEND = 0x19,
RT_NVME_ADMIN_OPCODE_DIRECTIVE_RECV = 0x1a,
RT_NVME_ADMIN_OPCODE_VIRTUAL_MGMT = 0x1c,
RT_NVME_ADMIN_OPCODE_NVME_MI_SEND = 0x1d,
RT_NVME_ADMIN_OPCODE_NVME_MI_RECV = 0x1e,
RT_NVME_ADMIN_OPCODE_DBBUF = 0x7c,
RT_NVME_ADMIN_OPCODE_FORMAT_NVM = 0x80,
RT_NVME_ADMIN_OPCODE_SECURITY_SEND = 0x81,
RT_NVME_ADMIN_OPCODE_SECURITY_RECV = 0x82,
RT_NVME_ADMIN_OPCODE_SANITIZE_NVM = 0x84,
RT_NVME_ADMIN_OPCODE_GET_LBA_STATUS = 0x86,
RT_NVME_ADMIN_OPCODE_VENDOR_START = 0xc0,
};
/* I/O commands */
enum
{
RT_NVME_CMD_FLUSH = 0x00,
RT_NVME_CMD_WRITE = 0x01,
RT_NVME_CMD_READ = 0x02,
RT_NVME_CMD_WRITE_UNCOR = 0x04,
RT_NVME_CMD_COMPARE = 0x05,
RT_NVME_CMD_WRITE_ZEROES = 0x08,
RT_NVME_CMD_DSM = 0x09,
RT_NVME_CMD_VERIFY = 0x0c,
RT_NVME_CMD_RESV_REGISTER = 0x0d,
RT_NVME_CMD_RESV_REPORT = 0x0e,
RT_NVME_CMD_RESV_ACQUIRE = 0x11,
RT_NVME_CMD_RESV_RELEASE = 0x15,
RT_NVME_CMD_ZONE_MGMT_SEND = 0x79,
RT_NVME_CMD_ZONE_MGMT_RECV = 0x7a,
RT_NVME_CMD_ZONE_APPEND = 0x7d,
RT_NVME_CMD_VENDOR_START = 0x80,
};
enum
{
RT_NVME_PSDT_PRP = 0x0,
RT_NVME_PSDT_SGL_MPTR_CONTIGUOUS = 0x1,
RT_NVME_PSDT_SGL_MPTR_SGL = 0x2,
};
/* Commands flags */
enum
{
RT_NVME_CMD_FLAGS_FUSE_SHIFT = 0x00,
RT_NVME_CMD_FLAGS_PSDT_SHIFT = 0x06,
};
struct rt_nvme_command_common
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
rt_le32_t nsid;
rt_le32_t cmd_dw2[2];
rt_le64_t metadata;
rt_le64_t prp1;
rt_le64_t prp2;
rt_le32_t cmd_dw10[6];
};
rt_packed(struct rt_nvme_sgl_desc
{
rt_le64_t adddress;
rt_le32_t length;
rt_uint8_t reserved[3];
#define SGL_DESC_TYPE_DATA_BLOCK 0x0
#define SGL_DESC_TYPE_BIT_BUCKET 0x1
#define SGL_DESC_TYPE_SEGMENT 0x2
#define SGL_DESC_TYPE_LAST_SEGMENT 0x3
#define SGL_DESC_TYPE_KEYED_DATA_BLOCK 0x4
#define SGL_DESC_TYPE_VENDOR_SPECIFIC 0xf
rt_uint8_t sgl_identify;
});
struct rt_nvme_command_rw
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
rt_le32_t nsid;
NVME_RSVD(8, 8);
rt_le64_t metadata;
union
{
struct
{
rt_le64_t prp1;
rt_le64_t prp2;
};
struct rt_nvme_sgl_desc sgl;
};
rt_le64_t slba;
rt_le16_t length;
rt_le16_t control;
rt_le32_t dsmgmt;
rt_le32_t reftag;
rt_le16_t apptag;
rt_le16_t appmask;
};
enum
{
RT_NVME_RW_LR = 1 << 15,
RT_NVME_RW_FUA = 1 << 14,
RT_NVME_RW_APPEND_PIREMAP = 1 << 9,
RT_NVME_RW_DSM_FREQ_UNSPEC = 0,
RT_NVME_RW_DSM_FREQ_TYPICAL = 1,
RT_NVME_RW_DSM_FREQ_RARE = 2,
RT_NVME_RW_DSM_FREQ_READS = 3,
RT_NVME_RW_DSM_FREQ_WRITES = 4,
RT_NVME_RW_DSM_FREQ_RW = 5,
RT_NVME_RW_DSM_FREQ_ONCE = 6,
RT_NVME_RW_DSM_FREQ_PREFETCH = 7,
RT_NVME_RW_DSM_FREQ_TEMP = 8,
RT_NVME_RW_DSM_LATENCY_NONE = 0 << 4,
RT_NVME_RW_DSM_LATENCY_IDLE = 1 << 4,
RT_NVME_RW_DSM_LATENCY_NORM = 2 << 4,
RT_NVME_RW_DSM_LATENCY_LOW = 3 << 4,
RT_NVME_RW_DSM_SEQ_REQ = 1 << 6,
RT_NVME_RW_DSM_COMPRESSED = 1 << 7,
RT_NVME_RW_PRINFO_PRCHK_REF = 1 << 10,
RT_NVME_RW_PRINFO_PRCHK_APP = 1 << 11,
RT_NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12,
RT_NVME_RW_PRINFO_PRACT = 1 << 13,
RT_NVME_RW_DTYPE_STREAMS = 1 << 4,
RT_NVME_WZ_DEAC = 1 << 9,
};
enum
{
RT_NVME_QUEUE_PHYS_CONTIG = (1 << 0),
RT_NVME_CQ_IRQ_ENABLED = (1 << 1),
RT_NVME_SQ_PRIO_URGENT = (0 << 1),
RT_NVME_SQ_PRIO_HIGH = (1 << 1),
RT_NVME_SQ_PRIO_MEDIUM = (2 << 1),
RT_NVME_SQ_PRIO_LOW = (3 << 1),
RT_NVME_FEAT_ARBITRATION = 0x01,
RT_NVME_FEAT_POWER_MGMT = 0x02,
RT_NVME_FEAT_LBA_RANGE = 0x03,
RT_NVME_FEAT_TEMP_THRESH = 0x04,
RT_NVME_FEAT_ERR_RECOVERY = 0x05,
RT_NVME_FEAT_VOLATILE_WC = 0x06,
RT_NVME_FEAT_NUM_QUEUES = 0x07,
RT_NVME_FEAT_IRQ_COALESCE = 0x08,
RT_NVME_FEAT_IRQ_CONFIG = 0x09,
RT_NVME_FEAT_WRITE_ATOMIC = 0x0a,
RT_NVME_FEAT_ASYNC_EVENT = 0x0b,
RT_NVME_FEAT_AUTO_PST = 0x0c,
RT_NVME_FEAT_SW_PROGRESS = 0x80,
RT_NVME_FEAT_HOST_ID = 0x81,
RT_NVME_FEAT_RESV_MASK = 0x82,
RT_NVME_FEAT_RESV_PERSIST = 0x83,
RT_NVME_LOG_ERROR = 0x01,
RT_NVME_LOG_SMART = 0x02,
RT_NVME_LOG_FW_SLOT = 0x03,
RT_NVME_LOG_RESERVATION = 0x80,
RT_NVME_FWACT_REPL = (0 << 3),
RT_NVME_FWACT_REPL_ACTV = (1 << 3),
RT_NVME_FWACT_ACTV = (2 << 3),
};
struct rt_nvme_command_identify
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
rt_le32_t nsid;
NVME_RSVD(8, 16);
rt_le64_t prp1;
rt_le64_t prp2;
rt_le32_t cns;
NVME_RSVD(64, 20);
};
struct rt_nvme_command_features
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
rt_le32_t nsid;
NVME_RSVD(8, 16);
rt_le64_t prp1;
rt_le64_t prp2;
rt_le32_t fid;
rt_le32_t dword11;
NVME_RSVD(68, 16);
};
struct rt_nvme_command_create_cq
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
NVME_RSVD(4, 20);
rt_le64_t prp1;
NVME_RSVD(32, 8);
rt_le16_t cqid;
rt_le16_t qsize;
rt_le16_t cq_flags;
rt_le16_t irq_vector;
NVME_RSVD(104, 16);
};
struct rt_nvme_command_create_sq
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
NVME_RSVD(4, 20);
rt_le64_t prp1;
NVME_RSVD(32, 8);
rt_le16_t sqid;
rt_le16_t qsize;
rt_le16_t sq_flags;
rt_le16_t cqid;
NVME_RSVD(104, 16);
};
struct rt_nvme_command_delete_queue
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
NVME_RSVD(4, 36);
rt_le16_t qid;
NVME_RSVD(42, 22);
};
struct rt_nvme_command_write_zeroes
{
rt_uint8_t opcode;
rt_uint8_t flags;
rt_uint16_t cmdid;
rt_le32_t nsid;
NVME_RSVD(8, 8);
rt_le64_t metadata;
rt_le64_t prp1;
rt_le64_t prp2;
rt_le64_t slba;
rt_le16_t length;
rt_le16_t control;
rt_le32_t dsmgmt;
rt_le32_t reftag;
rt_le16_t apptag;
rt_le16_t appmask;
};
struct rt_nvme_command
{
union
{
struct rt_nvme_command_common common;
struct rt_nvme_command_rw rw;
struct rt_nvme_command_identify identify;
struct rt_nvme_command_features features;
struct rt_nvme_command_create_cq create_cq;
struct rt_nvme_command_create_sq create_sq;
struct rt_nvme_command_delete_queue delete_queue;
struct rt_nvme_command_write_zeroes write_zeroes;
};
};
struct rt_nvme_completion
{
union
{
rt_le16_t u16;
rt_le32_t u32;
rt_le64_t u64;
} result;
rt_le16_t sq_head; /* How much of this queue may be reclaimed */
rt_le16_t sq_id; /* Submission queue that generated this entry */
rt_uint16_t cmdid; /* Which command completed */
rt_le16_t status; /* Command status */
};
enum
{
RT_NVME_REG_CAP = 0x0000, /* Controller Capabilities */
RT_NVME_REG_VS = 0x0008, /* Version */
RT_NVME_REG_INTMS = 0x000c, /* Interrupt Mask Set */
RT_NVME_REG_INTMC = 0x0010, /* Interrupt Mask Clear */
RT_NVME_REG_CC = 0x0014, /* Controller Configuration */
RT_NVME_REG_CSTS = 0x001c, /* Controller Status */
RT_NVME_REG_NSSR = 0x0020, /* NVM Subsystem Reset */
RT_NVME_REG_AQA = 0x0024, /* Admin Queue Attributes */
RT_NVME_REG_ASQ = 0x0028, /* Admin SQ Base Address */
RT_NVME_REG_ACQ = 0x0030, /* Admin CQ Base Address */
RT_NVME_REG_CMBLOC = 0x0038, /* Controller Memory Buffer Location */
RT_NVME_REG_CMBSZ = 0x003c, /* Controller Memory Buffer Size */
RT_NVME_REG_BPINFO = 0x0040, /* Boot Partition Information */
RT_NVME_REG_BPRSEL = 0x0044, /* Boot Partition Read Select */
RT_NVME_REG_BPMBL = 0x0048, /* Boot Partition Memory Buffer Location */
RT_NVME_REG_CMBMSC = 0x0050, /* Controller Memory Buffer Memory Space Control */
RT_NVME_REG_CRTO = 0x0068, /* Controller Ready Timeouts */
RT_NVME_REG_PMRCAP = 0x0e00, /* Persistent Memory Capabilities */
RT_NVME_REG_PMRCTL = 0x0e04, /* Persistent Memory Region Control */
RT_NVME_REG_PMRSTS = 0x0e08, /* Persistent Memory Region Status */
RT_NVME_REG_PMREBS = 0x0e0c, /* Persistent Memory Region Elasticity Buffer Size */
RT_NVME_REG_PMRSWTP = 0x0e10, /* Persistent Memory Region Sustained Write Throughput */
RT_NVME_REG_DBS = 0x1000, /* SQ 0 Tail Doorbell */
};
#define RT_NVME_CAP_MQES(cap) ((cap) & 0xffff)
#define RT_NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff)
#define RT_NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf)
#define RT_NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
#define RT_NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
#define RT_NVME_VS(major, minor) (((major) << 16) | ((minor) << 8))
#define RT_NVME_AQ_DEPTH 32
#define RT_NVME_NR_AEN_COMMANDS 1
#define RT_NVME_AQ_BLK_MQ_DEPTH (RT_NVME_AQ_DEPTH - RT_NVME_NR_AEN_COMMANDS)
#define RT_NVME_AQ_MQ_TAG_DEPTH (RT_NVME_AQ_BLK_MQ_DEPTH - 1)
enum
{
RT_NVME_CC_ENABLE = 1 << 0,
RT_NVME_CC_CSS_NVM = 0 << 4,
RT_NVME_CC_MPS_SHIFT = 7,
RT_NVME_CC_ARB_RR = 0 << 11,
RT_NVME_CC_ARB_WRRU = 1 << 11,
RT_NVME_CC_ARB_VS = 7 << 11,
RT_NVME_CC_SHN_NONE = 0 << 14,
RT_NVME_CC_SHN_NORMAL = 1 << 14,
RT_NVME_CC_SHN_ABRUPT = 2 << 14,
RT_NVME_CC_SHN_MASK = 3 << 14,
RT_NVME_CC_IOSQES = 6 << 16,
RT_NVME_CC_IOCQES = 4 << 20,
RT_NVME_CSTS_RDY = 1 << 0,
RT_NVME_CSTS_CFS = 1 << 1,
RT_NVME_CSTS_SHST_NORMAL = 0 << 2,
RT_NVME_CSTS_SHST_OCCUR = 1 << 2,
RT_NVME_CSTS_SHST_CMPLT = 2 << 2,
RT_NVME_CSTS_SHST_MASK = 3 << 2,
};
rt_packed(struct rt_nvme_id_power_state
{
rt_le16_t mp; /* Maximum Power */
NVME_RSVD(1, 1);
rt_uint8_t mxps_nops; /* Max Power Scale, Non-Operational State */
rt_le32_t enlat; /* Entry Latency: microseconds */
rt_le32_t exlat; /* Exit Latency: microseconds */
rt_uint8_t rrt; /* Relative Read Throughput */
rt_uint8_t rrl; /* Relative Read Latency */
rt_uint8_t rwt; /* Relative Write Throughput */
rt_uint8_t rwl; /* Relative Write Latency */
rt_le16_t idlp; /* Idle Power */
rt_uint8_t ips; /* Idle Power Scale */
NVME_RSVD(19, 1);
rt_le16_t actp; /* Active Power */
rt_uint8_t apw_aps; /* Active Power Workload, Active Power Scale */
NVME_RSVD(23, 9);
});
rt_packed(struct rt_nvme_id_ctrl
{
/* Controller Capabilities and Features */
rt_le16_t vid; /* PCI Vendor ID */
rt_le16_t ssvid; /* PCI Subsystem Vendor */
char sn[20]; /* Serial Number */
char mn[40]; /* Model Number */
char fr[8]; /* Firmware Revision */
rt_uint8_t rab; /* Recommended Arbitration Burst */
rt_uint8_t ieee[3]; /* IEEE OUI Identifier */
rt_uint8_t mic; /* Controller Multi-Path I/O and Namespace Sharing Capabilities */
rt_uint8_t mdts; /* Maximum Data Transfer Size */
rt_uint16_t cntlid; /* Controller ID */
rt_uint32_t ver; /* Version */
rt_uint32_t rtd3r; /* RTD3 Resume Latency */
rt_uint32_t rtd3e; /* RTD3 Entry Latency */
rt_uint32_t oaes; /* Optional Asynchronous Events Supported */
#define RT_NVME_ID_CTRATT_ELBAS 15 /* Extended LBA Formats Supported */
#define RT_NVME_ID_CTRATT_DNVMS 14 /* Delete NVM Set */
#define RT_NVME_ID_CTRATT_DEG 13 /* Delete Endurance Group */
#define RT_NVME_ID_CTRATT_VCM 12 /* Variable Capacity Management */
#define RT_NVME_ID_CTRATT_FCM 11 /* Fixed Capacity Management */
#define RT_NVME_ID_CTRATT_MDS 10 /* Multi-Domain Subsystem */
#define RT_NVME_ID_CTRATT_UUIDL 9 /* UUID List */
#define RT_NVME_ID_CTRATT_SQA 8 /* SQ Associations */
#define RT_NVME_ID_CTRATT_NG 7 /* Namespace Granularity */
#define RT_NVME_ID_CTRATT_TBKAS 6 /* Traffic Based Keep Alive Support */
#define RT_NVME_ID_CTRATT_PLM 5 /* Predictable Latency Mode */
#define RT_NVME_ID_CTRATT_EG 4 /* Endurance Groups */
#define RT_NVME_ID_CTRATT_RRL 3 /* Read Recovery Levels */
#define RT_NVME_ID_CTRATT_NVMS 2 /* NVM Sets */
#define RT_NVME_ID_CTRATT_NOPSPM 1 /* Non-Operational Power State Permissive Mode */
#define RT_NVME_ID_CTRATT_HIS 0 /* Host Identifier Support */
rt_uint32_t ctratt; /* Controller Attributes */
rt_uint16_t rrls; /* Read Recovery Levels Supported */
NVME_RSVD(102, 9);
rt_uint8_t cntrltype; /* Controller Type */
rt_uint8_t fguid[16]; /* FRU Globally Unique Identifier */
rt_uint16_t crdt1; /* Command Retry Delay Time 1 */
rt_uint16_t crdt2; /* Command Retry Delay Time 2 */
rt_uint16_t crdt3; /* Command Retry Delay Time 3 */
NVME_RSVD(134, 119);
#define RT_NVME_ID_NVMSR_NVMEE 1 /* NVMe Enclosure */
#define RT_NVME_ID_NVMSR_NVMESD 0 /* NVMe Storage Device */
rt_uint8_t nvmsr; /* NVM Subsystem Report */
#define RT_NVME_ID_VWCI_VWCRV 7 /* VPD Write Cycles Remaining Valid */
#define RT_NVME_ID_VWCI_VWCR 0 /* VPD Write Cycles Remaining */
rt_uint8_t vwci; /* VPD Write Cycle Information */
#define RT_NVME_ID_MEC_PCIEME 1 /* PCIe Port Management Endpoint */
#define RT_NVME_ID_MEC_SMBUSME 0 /* SMBus/I2C Port Management Endpoint */
rt_uint8_t mec; /* Management Endpoint Capabilities */
/* Admin Command Set Attributes & Optional Controller Capabilities */
rt_le16_t oacs; /* Optional Admin Command Support */
rt_uint8_t acl; /* Abort Command Limit */
rt_uint8_t aerl; /* Asynchronous Event Request Limit */
#define RT_NVME_ID_FRMW_SMUD 5 /* Support Multiple Update Detection */
#define RT_NVME_ID_FRMW_FAWR 4 /* Firmware Activation Without Reset */
#define RT_NVME_ID_FRMW_NOFS 1 /* Number Of Firmware Slots */
#define RT_NVME_ID_FRMW_FFSRO 0 /* First Firmware Slot Read Only */
rt_uint8_t frmw; /* Firmware Updates */
rt_uint8_t lpa; /* Log Page Attributes */
rt_uint8_t elpe; /* Error Log Page Entries */
rt_uint8_t npss; /* Number of Power States Support */
rt_uint8_t avscc; /* Admin Vendor Specific Command Configuration */
rt_uint8_t apsta; /* Autonomous Power State Transition Attributes */
rt_le16_t wctemp; /* Warning Composite Temperature Threshold */
rt_le16_t cctemp; /* Critical Composite Temperature Threshold */
rt_uint16_t mtfa; /* Maximum Time for Firmware Activation */
rt_uint32_t hmpre; /* Host Memory Buffer Preferred Size */
rt_uint32_t hmmin; /* Host Memory Buffer Minimum Size */
rt_uint8_t tnvmcap[16]; /* Total NVM Capacity */
rt_uint8_t unvmcap[16]; /* Unallocated NVM Capacity */
#define RT_NVME_ID_RPMBS_ASZ 24 /* Access Size */
#define RT_NVME_ID_RPMBS_TSZ 16 /* Total Size */
#define RT_NVME_ID_RPMBS_AM 3 /* Authentication Method */
#define RT_NVME_ID_RPMBS_NORPMBU 2 /* Number of RPMB Units */
rt_uint32_t rpmbs; /* Replay Protected Memory Block Support */
rt_uint16_t edstt; /* Extended Device Self-test Time */
rt_uint8_t dsto; /* Device Self-test Options */
rt_uint8_t fwug; /* Firmware Update Granularity */
rt_uint16_t kas; /* Keep Alive Support */
rt_uint16_t hctma; /* Host Controlled Thermal Management Attributes */
rt_uint16_t mntmt; /* Minimum Thermal Management Temperature */
rt_uint16_t mxtmt; /* Maximum Thermal Management Temperature */
#define RT_NVME_ID_SANICAP_NODMMAS 30 /* No-Deallocate Modifies Media After Sanitize */
#define RT_NVME_ID_SANICAP_NDI 29 /* No-Deallocate Inhibited */
#define RT_NVME_ID_SANICAP_OWS 2 /* Overwrite Support */
#define RT_NVME_ID_SANICAP_BES 1 /* Block Erase Support */
#define RT_NVME_ID_SANICAP_CES 0 /* Crypto Erase Support */
rt_uint32_t sanicap; /* Sanitize Capabilities */
rt_uint32_t hmminds; /* Host Memory Buffer Minimum Descriptor Entry Size */
rt_uint16_t hmmaxd; /* Host Memory Maximum Descriptors Entries */
rt_uint16_t nsetidmax; /* NVM Set Identifier Maximum */
rt_uint16_t endgidmax; /* Endurance Group Identifier Maximum */
rt_uint8_t anatt; /* ANA Transition Time */
rt_uint8_t anacap; /* Asymmetric Namespace Access Capabilities */
rt_uint32_t anagrpmax; /* ANA Group Identifier Maximum */
rt_uint32_t nanagrpid; /* Number of ANA Group Identifiers */
rt_uint32_t pels; /* Persistent Event Log Size */
rt_uint16_t dmid; /* Domain Identifier */
NVME_RSVD(358, 10);
rt_uint8_t megcap[16]; /* Max Endurance Group Capacity */
NVME_RSVD(384, 128);
/* NVM Command Set Attributes */
rt_uint8_t sqes; /* Submission Queue Entry Size */
rt_uint8_t cqes; /* Completion Queue Entry Size */
rt_le16_t maxcmd; /* Maximum Outstanding Commands */
rt_le32_t nn; /* Number of Namespaces */
rt_le16_t oncs; /* Optional NVM Command Support */
rt_le16_t fuses; /* Fused Operation Support */
rt_uint8_t fna; /* Format NVM Attributes */
rt_uint8_t vwc; /* Volatile Write Cache */
rt_le16_t awun; /* Atomic Write Unit Normal */
rt_le16_t awupf; /* Atomic Write Unit Power Fail */
rt_uint8_t nvscc; /* I/O Command Set Vendor Specific Command Configuration */
rt_uint8_t nwpc; /* Namespace Write Protection Capabilities */
rt_le16_t acwu; /* Atomic Compare & Write Unit */
rt_le16_t cdfs; /* Copy Descriptor Formats Supported */
#define RT_NVME_ID_SGL_SUPPORT_MASK 0x3
rt_le32_t sgls; /* SGL Support */
rt_uint32_t mnan; /* Maximum Number of Allowed Namespaces */
char maxdna[16]; /* Maximum Domain Namespace Attachments */
rt_le32_t maxcna; /* Maximum I/O Controller Namespace Attachments */
NVME_RSVD(564, 204);
rt_uint8_t subnqn[256]; /* NVM Subsystem NVMe Qualified Name */
NVME_RSVD(1024, 768);
rt_le32_t ioccsz; /* I/O Queue Command Capsule Supported Size */
rt_le32_t iorcsz; /* I/O Queue Response Capsule Supported Size */
rt_le16_t icdoff; /* In Capsule Data Offset */
rt_uint8_t ctrattr; /* Fabrics Controller Attributes */
rt_uint8_t msdbd; /* Maximum SGL Data Block Descriptors */
rt_le16_t ofcs; /* Optional Fabric Commands Support */
rt_uint8_t dctype;
NVME_RSVD(1807, 241);
/* Power State Descriptors */
struct rt_nvme_id_power_state psd[32];
/* Vendor Specific */
rt_uint8_t vs[1024];
});
enum
{
RT_NVME_CTRL_CMIC_MULTI_PORT = 1 << 0,
RT_NVME_CTRL_CMIC_MULTI_CTRL = 1 << 1,
RT_NVME_CTRL_CMIC_ANA = 1 << 3,
RT_NVME_CTRL_ONCS_COMPARE = 1 << 0,
RT_NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1,
RT_NVME_CTRL_ONCS_DSM = 1 << 2,
RT_NVME_CTRL_ONCS_WRITE_ZEROES = 1 << 3,
RT_NVME_CTRL_ONCS_RESERVATIONS = 1 << 5,
RT_NVME_CTRL_ONCS_TIMESTAMP = 1 << 6,
RT_NVME_CTRL_VWC_PRESENT = 1 << 0,
RT_NVME_CTRL_OACS_SEC_SUPP = 1 << 0,
RT_NVME_CTRL_OACS_NS_MNGT_SUPP = 1 << 3,
RT_NVME_CTRL_OACS_DIRECTIVES = 1 << 5,
RT_NVME_CTRL_OACS_DBBUF_SUPP = 1 << 8,
RT_NVME_CTRL_LPA_CMD_EFFECTS_LOG = 1 << 1,
RT_NVME_CTRL_CTRATT_128_ID = 1 << 0,
RT_NVME_CTRL_CTRATT_NON_OP_PSP = 1 << 1,
RT_NVME_CTRL_CTRATT_NVM_SETS = 1 << 2,
RT_NVME_CTRL_CTRATT_READ_RECV_LVLS = 1 << 3,
RT_NVME_CTRL_CTRATT_ENDURANCE_GROUPS = 1 << 4,
RT_NVME_CTRL_CTRATT_PREDICTABLE_LAT = 1 << 5,
RT_NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY = 1 << 7,
RT_NVME_CTRL_CTRATT_UUID_LIST = 1 << 9,
};
struct rt_nvme_lba_format
{
rt_le16_t ms; /* Metadata size */
rt_uint8_t ds; /* Data size */
rt_uint8_t rp; /* Relative performance */
};
rt_packed(struct rt_nvme_id_ns
{
rt_le64_t nsze; /* Namespace size */
rt_le64_t ncap; /* Namespace capacity */
rt_le64_t nuse; /* Namespace utilization */
rt_uint8_t nsfeat; /* Namespace features */
rt_uint8_t nlbaf; /* Number of lba formats */
rt_uint8_t flbas; /* Formatted lba size */
rt_uint8_t mc; /* Metadata capabilities */
rt_uint8_t dpc; /* End-to-end data protection capabilities */
rt_uint8_t dps; /* End-to-end data protection type settings */
rt_uint8_t nmic; /* Namespace Multi-path I/O and Namespace Sharing Capabilities */
rt_uint8_t rescap; /* Reservation Capabilities */
rt_uint8_t fpi; /* Format Progress Indicator */
rt_uint8_t dlfeat; /* Deallocate Logical Block Features */
rt_le16_t nawun; /* Namespace Atomic Write Unit Normal */
rt_le16_t nawupf; /* Namespace Atomic Write Unit Power Fail */
rt_le16_t nacwu; /* Namespace Atomic Compare & Write Unit */
rt_le16_t nabsn; /* Namespace Atomic Boundary Size Normal */
rt_le16_t nabo; /* Namespace Atomic Boundary Offset */
rt_le16_t nabspf; /* Namespace Atomic Boundary Size Power Fail */
rt_uint16_t noiob; /* Namespace Optimal IO Boundary */
rt_le64_t nvmcap[2]; /* NVMe Capacity */
rt_uint16_t npwg; /* Namespace Preferred Write Granularity */
rt_uint16_t npwa; /* Namespace Preferred Write Alignment */
rt_uint16_t npdg; /* Namespace Preferred Deallocate Granularity */
rt_uint16_t npda; /* Namespace Preferred Deallocate Alignment */
rt_uint16_t nows; /* Namespace Optimal Write Size */
NVME_RSVD(118, 18);
rt_uint32_t anagrpid; /* ANA Group Identifier */
NVME_RSVD(139, 3);
rt_uint8_t nsattr; /* Namespace Attributes */
rt_uint16_t nvmsetid; /* NVMe Set Identifier */
rt_uint16_t endgid; /* Endurance Group Identifier */
rt_uint8_t nguid[16]; /* Namespace Globally Unique Identifier */
rt_uint8_t eui64[8]; /* IEEE Extended Unique Identifier */
/* Logical Block Address Format */
struct rt_nvme_lba_format lbaf[16];
NVME_RSVD(171, 192);
/* Vendor specific */
rt_uint8_t vs[3712];
});
enum
{
RT_NVME_NS_FEAT_THIN = 1 << 0,
RT_NVME_NS_FLBAS_LBA_MASK = 0xf,
RT_NVME_NS_FLBAS_LBA_UMASK = 0x60,
RT_NVME_NS_FLBAS_LBA_SHIFT = 1,
RT_NVME_NS_FLBAS_META_EXT = 0x10,
RT_NVME_LBAF_RP_BEST = 0,
RT_NVME_LBAF_RP_BETTER = 1,
RT_NVME_LBAF_RP_GOOD = 2,
RT_NVME_LBAF_RP_DEGRADED = 3,
RT_NVME_NS_DPC_PI_LAST = 1 << 4,
RT_NVME_NS_DPC_PI_FIRST = 1 << 3,
RT_NVME_NS_DPC_PI_TYPE3 = 1 << 2,
RT_NVME_NS_DPC_PI_TYPE2 = 1 << 1,
RT_NVME_NS_DPC_PI_TYPE1 = 1 << 0,
RT_NVME_NS_DPS_PI_FIRST = 1 << 3,
RT_NVME_NS_DPS_PI_MASK = 0x7,
RT_NVME_NS_DPS_PI_TYPE1 = 1,
RT_NVME_NS_DPS_PI_TYPE2 = 2,
RT_NVME_NS_DPS_PI_TYPE3 = 3,
};
struct rt_nvme_ops;
struct rt_nvme_controller;
/*
* An NVM Express queue. Each device has at least two (one for admin commands
* and one for I/O commands).
*/
struct rt_nvme_queue
{
struct rt_nvme_controller *nvme;
struct rt_nvme_command *sq_cmds;
struct rt_nvme_completion *cq_entry;
rt_ubase_t sq_cmds_phy;
rt_ubase_t cq_entry_phy;
rt_uint32_t *doorbell;
rt_uint16_t qid;
rt_uint16_t depth;
rt_uint16_t sq_head;
rt_uint16_t sq_tail;
rt_uint16_t cq_head;
rt_uint16_t cq_phase;
rt_err_t err;
struct rt_nvme_command *cmd;
struct rt_completion done;
struct rt_spinlock lock;
};
struct rt_nvme_controller
{
rt_list_t list;
struct rt_device *dev;
int nvme_id;
char name[RT_NAME_MAX];
void *regs;
rt_uint64_t cap;
rt_uint32_t page_shift;
rt_uint32_t page_size;
rt_uint32_t queue_depth;
rt_uint32_t io_queue_max;
rt_uint32_t ctrl_config;
rt_uint32_t max_transfer_shift:8;
rt_uint32_t volatile_write_cache:8;
rt_uint32_t write_zeroes:1;
rt_uint32_t sgl_mode:2;
rt_uint32_t doorbell_stride;
rt_uint32_t *doorbell_tbl;
const struct rt_nvme_ops *ops;
#define RT_USING_NVME_QUEUE (1 + (RT_USING_NVME_IO_QUEUE * RT_CPUS_NR))
int irqs_nr;
int irqs[RT_USING_NVME_QUEUE];
union
{
struct
{
struct rt_nvme_queue admin_queue;
struct rt_nvme_queue io_queues[RT_USING_NVME_IO_QUEUE * RT_CPUS_NR];
};
struct rt_nvme_queue queue[RT_USING_NVME_QUEUE];
};
volatile rt_atomic_t cmdid;
volatile rt_atomic_t ioqid[RT_CPUS_NR];
rt_list_t ns_nodes;
};
struct rt_nvme_device
{
struct rt_blk_disk parent;
struct rt_nvme_controller *ctrl;
rt_list_t list;
rt_uint32_t nsid;
rt_uint32_t lba_shift;
struct rt_nvme_id_ns id;
};
#define rt_disk_to_nvme_device(disk) rt_container_of(disk, struct rt_nvme_device, parent)
struct rt_nvme_ops
{
const char *name;
/* Controller-specific NVM Express queue setup */
rt_err_t (*setup_queue)(struct rt_nvme_queue *queue);
/* Controller-specific NVM Express queue cleanup */
rt_err_t (*cleanup_queue)(struct rt_nvme_queue *queue);
/* Controller-specific NVM Express command submission */
rt_err_t (*submit_cmd)(struct rt_nvme_queue *queue, struct rt_nvme_command *cmd);
/* Controller-specific NVM Express command completion */
void (*complete_cmd)(struct rt_nvme_queue *queue, struct rt_nvme_command *cmd);
};
rt_err_t rt_nvme_controller_register(struct rt_nvme_controller *nvme);
rt_err_t rt_nvme_controller_unregister(struct rt_nvme_controller *nvme);
#endif /* __NVME_H__ */

View File

@ -0,0 +1,443 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __OFW_H__
#define __OFW_H__
#include <rtthread.h>
#include <ref.h>
#include <bitmap.h>
#include <libfdt/libfdt.h>
typedef rt_uint32_t rt_phandle;
struct rt_ofw_prop
{
const char *name;
int length;
void *value;
struct rt_ofw_prop *next;
};
struct rt_ofw_node
{
const char *name;
/* full_name is 'path/tag' or 'path/tag@reg' */
const char *full_name;
/* phandles range from 1 to 2^32-2 (0xfffffffe) */
rt_phandle phandle;
struct rt_device *dev;
struct rt_ofw_prop *props;
struct rt_ofw_node *parent;
struct rt_ofw_node *child;
struct rt_ofw_node *sibling;
struct rt_ref ref;
#define RT_OFW_F_SYSTEM 0 /* node is system node */
#define RT_OFW_F_READLY 1 /* node has driver */
#define RT_OFW_F_PLATFORM 2 /* node is platform device */
#define RT_OFW_F_OVERLAY 3 /* node is from overlay */
rt_bitmap_t flags;
/* RT-Thread object prototype */
void *rt_data;
};
#define RT_OFW_MAX_CELL_ARGS 16
struct rt_ofw_cell_args
{
void *data;
int args_count;
rt_uint32_t args[RT_OFW_MAX_CELL_ARGS];
};
struct rt_ofw_node_id
{
/* The name string should consist name property (deprecated) */
char name[32];
/*
* The type string should consist device_type property, such as pci, memory
* serial. Because it's deprecated in <devicetree-basics>, we can use other
* name (like "ttyS" or "ttyAMA" ...) to config with /chosen.
*/
char type[32];
/*
* The compatible string should consist only of lowercase letters, digits
* and dashes, and should start with a letter. A single comma is typically
* only used following a vendor prefix. Underscores should not be used.
*/
char compatible[128];
const void *data;
};
struct rt_ofw_stub
{
const struct rt_ofw_node_id *ids;
rt_err_t (*handler)(struct rt_ofw_node *np, const struct rt_ofw_node_id *id);
};
#define RT_OFW_SYMBOL(_class, _level) \
rt_section(".rt_ofw_data." #_class "." #_level)
#define RT_OFW_SYMBOL_TYPE_RANGE(_class, _type, _start, _end) \
static const rt_used RT_OFW_SYMBOL(_class, 0) _type _start; \
static const rt_used RT_OFW_SYMBOL(_class, end) _type _end; \
#define RT_OFW_STUB_EXPORT(_name, _ids, _class, _handler, ...) \
static const struct rt_ofw_stub __rt_ofw_##_name \
rt_used RT_OFW_SYMBOL(_class, __VA_ARGS__ _) = \
{ \
.ids = _ids, \
.handler = _handler, \
}
#define RT_OFW_STUB_RANGE_EXPORT(_class, _start, _end) \
RT_OFW_SYMBOL_TYPE_RANGE(_class, struct rt_ofw_stub, _start = {}, _end = {})
#define rt_ofw_data(np) ((struct rt_ofw_node *)np)->rt_data
rt_inline rt_bool_t rt_ofw_node_test_flag(const struct rt_ofw_node *np, int flag)
{
return rt_bitmap_test_bit((rt_bitmap_t *)&np->flags, flag);
}
rt_inline void rt_ofw_node_set_flag(struct rt_ofw_node *np, int flag)
{
rt_bitmap_set_bit(&np->flags, flag);
}
rt_inline rt_bool_t rt_ofw_node_test_and_set_flag(struct rt_ofw_node *np, int flag)
{
rt_bool_t res = rt_ofw_node_test_flag(np, flag);
rt_ofw_node_set_flag(np, flag);
return res;
}
rt_inline void rt_ofw_node_clear_flag(struct rt_ofw_node *np, int flag)
{
rt_bitmap_clear_bit(&np->flags, flag);
}
rt_err_t rt_ofw_node_destroy(struct rt_ofw_node *np);
struct rt_ofw_node *rt_ofw_node_get(struct rt_ofw_node *np);
void rt_ofw_node_put(struct rt_ofw_node *np);
rt_bool_t rt_ofw_node_tag_equ(const struct rt_ofw_node *np, const char *tag);
rt_bool_t rt_ofw_node_tag_prefix(const struct rt_ofw_node *np, const char *prefix);
rt_inline const char *rt_ofw_node_name(const struct rt_ofw_node *np)
{
return np ? np->name : "<no-node>";
}
rt_inline const char *rt_ofw_node_full_name(const struct rt_ofw_node *np)
{
return np ? np->full_name : "<no-node>";
}
rt_bool_t rt_ofw_machine_is_compatible(const char *compatible);
rt_bool_t rt_ofw_node_is_available(const struct rt_ofw_node *np);
rt_bool_t rt_ofw_node_is_compatible(const struct rt_ofw_node *np, const char *compatible);
struct rt_ofw_node_id *rt_ofw_prop_match(struct rt_ofw_prop *prop, const struct rt_ofw_node_id *ids);
struct rt_ofw_node_id *rt_ofw_node_match(struct rt_ofw_node *np, const struct rt_ofw_node_id *ids);
struct rt_ofw_node *rt_ofw_find_node_by_tag(struct rt_ofw_node *from, const char *tag);
struct rt_ofw_node *rt_ofw_find_node_by_prop_r(struct rt_ofw_node *from, const char *propname,
const struct rt_ofw_prop **out_prop);
rt_inline struct rt_ofw_node *rt_ofw_find_node_by_prop(struct rt_ofw_node *from, const char *propname)
{
return rt_ofw_find_node_by_prop_r(from, propname, RT_NULL);
}
struct rt_ofw_node *rt_ofw_find_node_by_name(struct rt_ofw_node *from, const char *name);
struct rt_ofw_node *rt_ofw_find_node_by_type(struct rt_ofw_node *from, const char *type);
struct rt_ofw_node *rt_ofw_find_node_by_compatible(struct rt_ofw_node *from, const char *compatible);
struct rt_ofw_node *rt_ofw_find_node_by_ids_r(struct rt_ofw_node *from, const struct rt_ofw_node_id *ids,
const struct rt_ofw_node_id **out_id);
struct rt_ofw_node *rt_ofw_find_node_by_path(const char *path);
struct rt_ofw_node *rt_ofw_find_node_by_phandle(rt_phandle phandle);
rt_inline struct rt_ofw_node *rt_ofw_find_node_by_ids(struct rt_ofw_node *from, const struct rt_ofw_node_id *ids)
{
return rt_ofw_find_node_by_ids_r(from, ids, RT_NULL);
}
struct rt_ofw_node *rt_ofw_get_parent(const struct rt_ofw_node *np);
struct rt_ofw_node *rt_ofw_get_child_by_tag(const struct rt_ofw_node *parent, const char *tag);
struct rt_ofw_node *rt_ofw_get_child_by_compatible(const struct rt_ofw_node *parent, const char *compatible);
int rt_ofw_get_child_count(const struct rt_ofw_node *np);
int rt_ofw_get_available_child_count(const struct rt_ofw_node *np);
struct rt_ofw_node *rt_ofw_get_next_node(struct rt_ofw_node *prev);
struct rt_ofw_node *rt_ofw_get_next_parent(struct rt_ofw_node *prev);
struct rt_ofw_node *rt_ofw_get_next_child(const struct rt_ofw_node *parent, struct rt_ofw_node *prev);
struct rt_ofw_node *rt_ofw_get_next_available_child(const struct rt_ofw_node *parent, struct rt_ofw_node *prev);
struct rt_ofw_node *rt_ofw_get_cpu_node(int cpu, int *thread, rt_bool_t (*match_cpu_hwid)(int cpu, rt_uint64_t hwid));
struct rt_ofw_node *rt_ofw_get_next_cpu_node(struct rt_ofw_node *prev);
struct rt_ofw_node *rt_ofw_get_cpu_state_node(struct rt_ofw_node *cpu_np, int index);
rt_uint64_t rt_ofw_get_cpu_id(struct rt_ofw_node *cpu_np);
rt_uint64_t rt_ofw_get_cpu_hwid(struct rt_ofw_node *cpu_np, unsigned int thread);
struct rt_ofw_node *rt_ofw_get_alias_node(const char *tag, int id);
int rt_ofw_get_alias_id(struct rt_ofw_node *np, const char *tag);
int rt_ofw_get_alias_last_id(const char *tag);
rt_err_t rt_ofw_map_id(struct rt_ofw_node *np, rt_uint32_t id, const char *map_name, const char *map_mask_name,
struct rt_ofw_node **ref_np, rt_uint32_t *out_id);
struct rt_ofw_node *rt_ofw_append_child(struct rt_ofw_node *parent, const char *full_name);
rt_err_t rt_ofw_append_prop(struct rt_ofw_node *np, const char *name, int length, void *value);
struct rt_ofw_node *rt_ofw_parse_phandle(const struct rt_ofw_node *np, const char *phandle_name, int index);
rt_err_t rt_ofw_parse_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name,
int index, struct rt_ofw_cell_args *out_args);
int rt_ofw_count_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name);
const char *rt_ofw_get_prop_fuzzy_name(const struct rt_ofw_node *np, const char *name);
struct rt_ofw_prop *rt_ofw_get_prop(const struct rt_ofw_node *np, const char *name, rt_ssize_t *out_length);
rt_inline const void *rt_ofw_prop_read_raw(const struct rt_ofw_node *np, const char *name, rt_ssize_t *out_length)
{
struct rt_ofw_prop *prop = rt_ofw_get_prop(np, name, out_length);
return prop ? prop->value : RT_NULL;
}
int rt_ofw_prop_read_u8_array_index(const struct rt_ofw_node *np, const char *propname,
int index, int nr, rt_uint8_t *out_values);
int rt_ofw_prop_read_u16_array_index(const struct rt_ofw_node *np, const char *propname,
int index, int nr, rt_uint16_t *out_values);
int rt_ofw_prop_read_u32_array_index(const struct rt_ofw_node *np, const char *propname,
int index, int nr, rt_uint32_t *out_values);
int rt_ofw_prop_read_u64_array_index(const struct rt_ofw_node *np, const char *propname,
int index, int nr, rt_uint64_t *out_values);
int rt_ofw_prop_read_string_array_index(const struct rt_ofw_node *np, const char *propname,
int index, int nr, const char **out_strings);
int rt_ofw_prop_count_of_size(const struct rt_ofw_node *np, const char *propname, int size);
int rt_ofw_prop_index_of_string(const struct rt_ofw_node *np, const char *propname, const char *string);
const fdt32_t *rt_ofw_prop_next_u32(struct rt_ofw_prop *prop, const fdt32_t *cur, rt_uint32_t *out_value);
const char *rt_ofw_prop_next_string(struct rt_ofw_prop *prop, const char *cur);
rt_inline rt_err_t rt_ofw_prop_read_u8_index(const struct rt_ofw_node *np, const char *propname,
int index, rt_uint8_t *out_value)
{
int nr = rt_ofw_prop_read_u8_array_index(np, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_ofw_prop_read_u16_index(const struct rt_ofw_node *np, const char *propname,
int index, rt_uint16_t *out_value)
{
int nr = rt_ofw_prop_read_u16_array_index(np, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_ofw_prop_read_u32_index(const struct rt_ofw_node *np, const char *propname,
int index, rt_uint32_t *out_value)
{
int nr = rt_ofw_prop_read_u32_array_index(np, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_ofw_prop_read_u64_index(const struct rt_ofw_node *np, const char *propname,
int index, rt_uint64_t *out_value)
{
int nr = rt_ofw_prop_read_u64_array_index(np, propname, index, 1, out_value);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_ofw_prop_read_string_index(const struct rt_ofw_node *np, const char *propname,
int index, const char **out_string)
{
int nr = rt_ofw_prop_read_string_array_index(np, propname, index, 1, out_string);
return nr > 0 ? RT_EOK : (rt_err_t)nr;
}
rt_inline rt_err_t rt_ofw_prop_read_u8(const struct rt_ofw_node *np, const char *propname,
rt_uint8_t *out_value)
{
return rt_ofw_prop_read_u8_index(np, propname, 0, out_value);
}
rt_inline rt_err_t rt_ofw_prop_read_u16(const struct rt_ofw_node *np, const char *propname,
rt_uint16_t *out_value)
{
return rt_ofw_prop_read_u16_index(np, propname, 0, out_value);
}
rt_inline rt_err_t rt_ofw_prop_read_u32(const struct rt_ofw_node *np, const char *propname,
rt_uint32_t *out_value)
{
return rt_ofw_prop_read_u32_index(np, propname, 0, out_value);
}
rt_inline rt_err_t rt_ofw_prop_read_s32(const struct rt_ofw_node *np, const char *propname,
rt_int32_t *out_value)
{
return rt_ofw_prop_read_u32_index(np, propname, 0, (rt_uint32_t *)out_value);
}
rt_inline rt_err_t rt_ofw_prop_read_u64(const struct rt_ofw_node *np, const char *propname,
rt_uint64_t *out_value)
{
return rt_ofw_prop_read_u64_index(np, propname, 0, out_value);
}
rt_inline rt_err_t rt_ofw_prop_read_string(const struct rt_ofw_node *np, const char *propname,
const char **out_string)
{
return rt_ofw_prop_read_string_index(np, propname, 0, out_string);
}
rt_inline rt_bool_t rt_ofw_prop_read_bool(const struct rt_ofw_node *np, const char *propname)
{
return rt_ofw_get_prop(np, propname, RT_NULL) ? RT_TRUE : RT_FALSE;
}
rt_inline int rt_ofw_prop_count_of_u8(const struct rt_ofw_node *np, const char *propname)
{
return rt_ofw_prop_count_of_size(np, propname, sizeof(rt_uint8_t));
}
rt_inline int rt_ofw_prop_count_of_u16(const struct rt_ofw_node *np, const char *propname)
{
return rt_ofw_prop_count_of_size(np, propname, sizeof(rt_uint16_t));
}
rt_inline int rt_ofw_prop_count_of_u32(const struct rt_ofw_node *np, const char *propname)
{
return rt_ofw_prop_count_of_size(np, propname, sizeof(rt_uint32_t));
}
rt_inline int rt_ofw_prop_count_of_u64(const struct rt_ofw_node *np, const char *propname)
{
return rt_ofw_prop_count_of_size(np, propname, sizeof(rt_uint64_t));
}
rt_inline const char *rt_ofw_node_type(const struct rt_ofw_node *np)
{
return rt_ofw_prop_read_raw(np, "device_type", RT_NULL);
}
rt_inline rt_bool_t rt_ofw_node_is_type(const struct rt_ofw_node *np, const char *type)
{
const char *get_type = rt_ofw_node_type(np);
return np && get_type && type && !rt_strcmp(get_type, type);
}
#define rt_ofw_foreach_node_by_tag(np, name) \
for (np = rt_ofw_find_node_by_tag(RT_NULL, name); np; \
np = rt_ofw_find_node_by_tag(np, name))
#define rt_ofw_foreach_node_by_prop(np, prop_name) \
for (np = rt_ofw_find_node_by_prop(RT_NULL, prop_name); \
np; np = rt_ofw_find_node_by_prop(np, prop_name))
#define rt_ofw_foreach_node_by_prop_r(np, prop_name, prop) \
for (np = rt_ofw_find_node_by_prop_r(RT_NULL, prop_name, prop); \
np; np = rt_ofw_find_node_by_prop_r(np, prop_name, prop))
#define rt_ofw_foreach_node_by_name(np, name) \
for (np = rt_ofw_find_node_by_name(RT_NULL, name); np; \
np = rt_ofw_find_node_by_name(np, name))
#define rt_ofw_foreach_node_by_type(np, type) \
for (np = rt_ofw_find_node_by_type(RT_NULL, type); np; \
np = rt_ofw_find_node_by_type(np, type))
#define rt_ofw_foreach_node_by_compatible(np, compatible) \
for (np = rt_ofw_find_node_by_compatible(RT_NULL, compatible); np; \
np = rt_ofw_find_node_by_compatible(np, compatible))
#define rt_ofw_foreach_node_by_ids_r(np, id, ids) \
for (np = rt_ofw_find_node_by_ids_r(RT_NULL, ids, id); \
np; np = rt_ofw_find_node_by_ids_r(np, ids, id))
#define rt_ofw_foreach_node_by_ids(np, ids) \
for (np = rt_ofw_find_node_by_ids(RT_NULL, ids); np; \
np = rt_ofw_find_node_by_ids(np, ids))
#define rt_ofw_foreach_nodes(from, np) \
for (np = rt_ofw_get_next_node(from); \
np; np = rt_ofw_get_next_node(np))
#define rt_ofw_foreach_allnodes(np) \
rt_ofw_foreach_nodes(RT_NULL, np)
#define rt_ofw_foreach_parent_node(np) \
for (np = rt_ofw_get_next_parent(rt_ofw_node_get(np)); \
np; np = rt_ofw_get_next_parent(np))
#define rt_ofw_foreach_child_node(parent, child) \
for (child = rt_ofw_get_next_child(parent, RT_NULL); \
child; child = rt_ofw_get_next_child(parent, child))
#define rt_ofw_foreach_available_child_node(parent, child) \
for (child = rt_ofw_get_next_available_child(parent, RT_NULL); child; \
child = rt_ofw_get_next_available_child(parent, child))
#define rt_ofw_foreach_cpu_node(cpu_np) \
for (cpu_np = rt_ofw_get_next_cpu_node(RT_NULL); \
cpu_np; cpu_np = rt_ofw_get_next_cpu_node(cpu_np))
#define rt_ofw_foreach_prop(np, prop) \
for (prop = np->props; prop; prop = prop->next)
#define rt_ofw_foreach_prop_u32(np, propname, prop, p, u) \
for (prop = rt_ofw_get_prop(np, propname, RT_NULL), \
p = rt_ofw_prop_next_u32(prop, RT_NULL, &u); p; \
p = rt_ofw_prop_next_u32(prop, p, &u))
#define rt_ofw_foreach_prop_string(np, propname, prop, s) \
for (prop = rt_ofw_get_prop(np, propname, RT_NULL), \
s = rt_ofw_prop_next_string(prop, RT_NULL); s; \
s = rt_ofw_prop_next_string(prop, s))
#define rt_ofw_foreach_stub(stub, stub_start, stub_end) \
for (stub = stub_start; stub <= stub_end; ++stub)
struct rt_ofw_stub *rt_ofw_stub_probe_range(struct rt_ofw_node *np,
const struct rt_ofw_stub *stub_start, const struct rt_ofw_stub *stub_end);
struct rt_object *rt_ofw_parse_object(struct rt_ofw_node *np, const char *obj_name, const char *cells_name);
rt_err_t rt_ofw_console_setup(void);
const char *rt_ofw_bootargs_select(const char *key, int index);
#ifdef RT_USING_CONSOLE
void rt_ofw_node_dump_dts(struct rt_ofw_node *np, rt_bool_t sibling_too);
#endif
#endif /* __OFW_H__ */

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __OFW_FDT_H__
#define __OFW_FDT_H__
#include <mm_page.h>
#include <drivers/ofw.h>
struct rt_fdt_earlycon
{
union { rt_ubase_t mmio, port; };
union { rt_ubase_t size, width; };
void *fdt;
char options[32];
long nodeoffset;
void *data;
void (*console_putc)(void *data, char c);
#define FDT_EARLYCON_KICK_UPDATE 0
#define FDT_EARLYCON_KICK_COMPLETED 1
void (*console_kick)(struct rt_fdt_earlycon *earlycon, int why);
long msg_idx;
char msg[RT_FDT_EARLYCON_MSG_SIZE * 1024];
};
struct rt_fdt_earlycon_id
{
char *name;
char *type;
char *compatible;
rt_err_t (*setup)(struct rt_fdt_earlycon *earlycon, const char *options);
};
#define RT_FDT_EARLYCON_EXPORT(_name, _type, _compatible, _setup) \
static const struct rt_fdt_earlycon_id __rt_fdt_##_name##_earlycon \
rt_used RT_OFW_SYMBOL(earlycon, _) = \
{ \
.name = #_name, \
.type = _type, \
.compatible = _compatible, \
.setup = _setup, \
}
const char *rt_fdt_node_name(const char *full_name);
rt_uint64_t rt_fdt_read_number(const fdt32_t *cell, int size);
rt_uint64_t rt_fdt_next_cell(const fdt32_t **cellptr, int size);
rt_uint64_t rt_fdt_translate_address(void *fdt, int nodeoffset, rt_uint64_t address);
rt_bool_t rt_fdt_device_is_available(void *fdt, int nodeoffset);
rt_err_t rt_fdt_commit_memregion_early(rt_region_t *region, rt_bool_t is_reserved);
rt_err_t rt_fdt_commit_memregion_request(rt_region_t **out_region, rt_size_t *out_nr, rt_bool_t is_reserved);
rt_err_t rt_fdt_prefetch(void *fdt);
rt_err_t rt_fdt_scan_root(void);
rt_err_t rt_fdt_scan_memory(void);
rt_err_t rt_fdt_scan_initrd(rt_uint64_t *ranges);
rt_err_t rt_fdt_model_dump(void);
rt_err_t rt_fdt_boot_dump(void);
void rt_fdt_earlycon_output(const char *str);
void rt_fdt_earlycon_kick(int why);
rt_err_t rt_fdt_scan_chosen_stdout(void);
rt_err_t rt_fdt_bootargs_select(const char *key, int index, const char **out_result);
rt_err_t rt_fdt_unflatten(void);
struct rt_ofw_node *rt_fdt_unflatten_single(void *fdt);
#endif /* __OFW_FDT_H__ */

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __OFW_IO_H__
#define __OFW_IO_H__
#include <ioremap.h>
#include <drivers/ofw.h>
int rt_ofw_bus_addr_cells(struct rt_ofw_node *np);
int rt_ofw_bus_size_cells(struct rt_ofw_node *np);
int rt_ofw_io_addr_cells(struct rt_ofw_node *np);
int rt_ofw_io_size_cells(struct rt_ofw_node *np);
int rt_ofw_get_address_count(struct rt_ofw_node *np);
rt_err_t rt_ofw_get_address(struct rt_ofw_node *np, int index, rt_uint64_t *out_address, rt_uint64_t *out_size);
rt_err_t rt_ofw_get_address_by_name(struct rt_ofw_node *np, const char *name,
rt_uint64_t *out_address, rt_uint64_t *out_size);
int rt_ofw_get_address_array(struct rt_ofw_node *np, int nr, rt_uint64_t *out_regs);
rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_type, rt_uint64_t address);
rt_uint64_t rt_ofw_reverse_address(struct rt_ofw_node *np, const char *range_type, rt_uint64_t address);
rt_inline rt_uint64_t rt_ofw_translate_dma2cpu(struct rt_ofw_node *np, rt_uint64_t address)
{
rt_uint64_t bus_addr, cpu_addr;
bus_addr = rt_ofw_reverse_address(np, "dma-ranges", address);
cpu_addr = rt_ofw_translate_address(np, "ranges", bus_addr);
return cpu_addr != ~0ULL ? cpu_addr : address;
}
rt_inline rt_uint64_t rt_ofw_translate_cpu2dma(struct rt_ofw_node *np, rt_uint64_t address)
{
rt_uint64_t bus_addr, dma_addr;
bus_addr = rt_ofw_reverse_address(np, "ranges", address);
dma_addr = rt_ofw_translate_address(np, "dma-ranges", bus_addr);
return dma_addr != ~0ULL ? dma_addr : address;
}
void *rt_ofw_iomap(struct rt_ofw_node *np, int index);
void *rt_ofw_iomap_by_name(struct rt_ofw_node *np, const char *name);
#endif /* __OFW_IO_H__ */

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __OFW_IRQ_H__
#define __OFW_IRQ_H__
#include <drivers/ofw.h>
int rt_ofw_irq_cells(struct rt_ofw_node *np);
rt_err_t rt_ofw_parse_irq_map(struct rt_ofw_node *np, struct rt_ofw_cell_args *irq_args);
rt_err_t rt_ofw_parse_irq_cells(struct rt_ofw_node *np, int index, struct rt_ofw_cell_args *out_irq_args);
struct rt_ofw_node *rt_ofw_find_irq_parent(struct rt_ofw_node *np, int *out_interrupt_cells);
int rt_ofw_map_irq(struct rt_ofw_cell_args *irq_args);
int rt_ofw_get_irq_count(struct rt_ofw_node *np);
int rt_ofw_get_irq(struct rt_ofw_node *np, int index);
int rt_ofw_get_irq_by_name(struct rt_ofw_node *np, const char *name);
#endif /* __OFW_IRQ_H__ */

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __OFW_RAW_H__
#define __OFW_RAW_H__
#include <libfdt/libfdt.h>
#define FDT_SIZE_KB 1024
#define FDT_SIZE_MB (1024 * FDT_SIZE_KB)
#define FDT_SIZE_MAX (2 * FDT_SIZE_MB)
#define FDT_PADDING_SIZE (1 * FDT_SIZE_KB)
typedef uint8_t fdt8_t;
static inline uint8_t fdt8_to_cpu(fdt8_t x)
{
return (uint8_t)x;
}
int fdt_add_subnode_possible(void *fdt, int parentoffset, const char *name);
int fdt_add_mem_rsv_possible(void *fdt, size_t addr, size_t size);
#define fdt_setprop_cstring(fdt, nodeoffset, name, str) \
fdt_setprop((fdt), (nodeoffset), (name), (str), sizeof(str))
#define fdt_prop_cells_ops(ops, fdt, nodeoffset, prop, ...) \
({ \
int ret = 0; \
uint32_t tmp[] = { __VA_ARGS__ }; \
for (int i = 0; i < sizeof(tmp) / sizeof(tmp[0]); ++i) \
{ \
tmp[i] = cpu_to_fdt32(tmp[i]); \
} \
ret += ops(fdt, nodeoffset, prop, tmp, sizeof(tmp)); \
ret; \
})
#define fdt_setprop_cells(fdt, nodeoffset, prop, ...) \
fdt_prop_cells_ops(fdt_setprop, fdt, nodeoffset, prop, __VA_ARGS__)
#define fdt_appendprop_cells(fdt, nodeoffset, prop, ...) \
fdt_prop_cells_ops(fdt_appendprop, fdt, nodeoffset, prop, __VA_ARGS__)
int fdt_setprop_uxx(void *fdt, int nodeoffset, const char *name, uint64_t val, bool is_u64);
int fdt_getprop_u8(void *fdt, int nodeoffset, const char *name, uint8_t *out_value, int *lenp);
int fdt_getprop_s8(void *fdt, int nodeoffset, const char *name, int8_t *out_value, int *lenp);
int fdt_getprop_u16(void *fdt, int nodeoffset, const char *name, uint16_t *out_value, int *lenp);
int fdt_getprop_s16(void *fdt, int nodeoffset, const char *name, int16_t *out_value, int *lenp);
int fdt_getprop_u32(void *fdt, int nodeoffset, const char *name, uint32_t *out_value, int *lenp);
int fdt_getprop_s32(void *fdt, int nodeoffset, const char *name, int32_t *out_value, int *lenp);
int fdt_io_addr_cells(void *fdt, int nodeoffset);
int fdt_io_size_cells(void *fdt, int nodeoffset);
int fdt_install_initrd(void *fdt, char *os_name, size_t initrd_addr, size_t initrd_size);
#endif /* __OFW_RAW_H__ */

View File

@ -0,0 +1,604 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __PCI_H__
#define __PCI_H__
#include <rtdef.h>
#include <bitmap.h>
#include <ioremap.h>
#include <drivers/ofw.h>
#include <drivers/pic.h>
#include <drivers/core/dm.h>
#include <drivers/core/driver.h>
#include "../../pci/pci_ids.h"
#include "../../pci/pci_regs.h"
#define RT_PCI_INTX_PIN_MAX 4
#define RT_PCI_BAR_NR_MAX 6
#define RT_PCI_DEVICE_MAX 32
#define RT_PCI_FUNCTION_MAX 8
#define RT_PCI_FIND_CAP_TTL 48
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
* in a single byte as follows:
*
* 7:3 = slot
* 2:0 = function
*/
#define RT_PCI_DEVID(bus, devfn) ((((rt_uint16_t)(bus)) << 8) | (devfn))
#define RT_PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define RT_PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define RT_PCI_FUNC(devfn) ((devfn) & 0x07)
#define PCIE_LINK_STATE_L0S RT_BIT(0)
#define PCIE_LINK_STATE_L1 RT_BIT(1)
#define PCIE_LINK_STATE_CLKPM RT_BIT(2)
#define PCIE_LINK_STATE_L1_1 RT_BIT(3)
#define PCIE_LINK_STATE_L1_2 RT_BIT(4)
#define PCIE_LINK_STATE_L1_1_PCIPM RT_BIT(5)
#define PCIE_LINK_STATE_L1_2_PCIPM RT_BIT(6)
#define PCIE_LINK_STATE_ALL \
( \
PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | \
PCIE_LINK_STATE_CLKPM | \
PCIE_LINK_STATE_L1_1 | PCIE_LINK_STATE_L1_2 | \
PCIE_LINK_STATE_L1_1_PCIPM | PCIE_LINK_STATE_L1_2_PCIPM \
)
struct rt_pci_bus_region
{
rt_uint64_t phy_addr;
rt_uint64_t cpu_addr;
rt_uint64_t size;
rt_uint64_t bus_start;
#define PCI_BUS_REGION_F_NONE 0xffffffff /* PCI no memory */
#define PCI_BUS_REGION_F_MEM 0x00000000 /* PCI memory space */
#define PCI_BUS_REGION_F_IO 0x00000001 /* PCI IO space */
#define PCI_BUS_REGION_F_PREFETCH 0x00000008 /* Prefetchable PCI memory */
rt_ubase_t flags;
};
struct rt_pci_bus_resource
{
rt_ubase_t base;
rt_size_t size;
rt_ubase_t flags;
};
/*
* PCI topology:
*
* +-----+-----+ +-------------+ PCI Bus 0 +------------+ PCI Bus 1
* | RAM | CPU |---------| Host Bridge |--------+-----| PCI Bridge |-----+
* +-----+-----+ +-------------+ | +------------+ | +-------------+
* | +----| End Point 2 |
* +-------------+ +-------------+ | +-------------+ | +-------------+
* | End Point 5 |----+ | End Point 0 |-------+ | End Point 3 |----+
* +-------------+ | +-------------+ | +-------------+ |
* | | |
* +-------------+ | +-------------+ | +-------------+ | +-------------+
* | End Point 6 |----+----| ISA Bridge |-------+-----| End Point 1 | +----| End Point 4 |
* +-------------+ +-------------+ | +-------------+ +-------------+
* |
* +------+ +----------------+ |
* | Port |---------| CardBus Bridge |----+
* +------+ +----------------+
*/
struct rt_pci_bus;
struct rt_pci_device_id
{
#define PCI_ANY_ID (~0)
#define RT_PCI_DEVICE_ID(vend, dev) \
.vendor = (vend), \
.device = (dev), \
.subsystem_vendor = PCI_ANY_ID, \
.subsystem_device = PCI_ANY_ID
#define RT_PCI_DEVICE_CLASS(dev_class, dev_class_mask) \
.vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
.subsystem_vendor = PCI_ANY_ID, \
.subsystem_device = PCI_ANY_ID, \
.class = (dev_class), .class_mask = (dev_class_mask),
rt_uint32_t vendor, device; /* Vendor and device ID or PCI_ANY_ID */
rt_uint32_t subsystem_vendor; /* Subsystem ID's or PCI_ANY_ID */
rt_uint32_t subsystem_device; /* Subsystem ID's or PCI_ANY_ID */
rt_uint32_t class, class_mask; /* (class, subclass, prog-if) triplet */
const void *data;
};
struct rt_pci_device
{
struct rt_device parent;
const char *name;
rt_list_t list;
struct rt_pci_bus *bus;
struct rt_pci_bus *subbus; /* In PCI-to-PCI bridge, 'End Point' or 'Port' is NULL */
const struct rt_pci_device_id *id;
rt_uint32_t devfn; /* Encoded device & function index */
rt_uint16_t vendor;
rt_uint16_t device;
rt_uint16_t subsystem_vendor;
rt_uint16_t subsystem_device;
rt_uint32_t class; /* 3 bytes: (base, sub, prog-if) */
rt_uint8_t revision;
rt_uint8_t hdr_type;
rt_uint8_t max_latency;
rt_uint8_t min_grantl;
rt_uint8_t int_pin;
rt_uint8_t int_line;
rt_uint16_t exp_flags;
rt_uint32_t cfg_size;
void *sysdata;
int irq;
rt_uint8_t pin;
struct rt_pic *intx_pic;
struct rt_pci_bus_resource resource[RT_PCI_BAR_NR_MAX];
rt_uint8_t pme_cap;
rt_uint8_t msi_cap;
rt_uint8_t msix_cap;
rt_uint8_t pcie_cap;
rt_uint8_t busmaster:1; /* Is the bus master */
rt_uint8_t multi_function:1; /* Multi-function device */
rt_uint8_t ari_enabled:1; /* Alternative Routing-ID Interpretation */
rt_uint8_t no_msi:1; /* May not use MSI */
rt_uint8_t no_64bit_msi:1; /* May only use 32-bit MSIs */
rt_uint8_t msi_enabled:1; /* MSI enable */
rt_uint8_t msix_enabled:1; /* MSIx enable */
rt_uint8_t broken_intx_masking:1; /* INTx masking can't be used */
rt_uint8_t pme_support:5; /* Bitmask of states from which PME# can be generated */
#ifdef RT_PCI_MSI
void *msix_base;
struct rt_pic *msi_pic;
rt_list_t msi_desc_nodes;
struct rt_spinlock msi_lock;
#endif
};
struct rt_pci_host_bridge
{
struct rt_device parent;
rt_uint32_t domain;
struct rt_pci_bus *root_bus;
const struct rt_pci_ops *ops;
const struct rt_pci_ops *child_ops;
rt_uint32_t bus_range[2];
rt_size_t bus_regions_nr;
struct rt_pci_bus_region *bus_regions;
rt_size_t dma_regions_nr;
struct rt_pci_bus_region *dma_regions;
rt_uint8_t (*irq_slot)(struct rt_pci_device *pdev, rt_uint8_t *pinp);
int (*irq_map)(struct rt_pci_device *pdev, rt_uint8_t slot, rt_uint8_t pin);
void *sysdata;
rt_uint8_t priv[0];
};
#define rt_device_to_pci_host_bridge(dev) rt_container_of(dev, struct rt_pci_host_bridge, parent)
struct rt_pci_ops
{
rt_err_t (*add)(struct rt_pci_bus *bus);
rt_err_t (*remove)(struct rt_pci_bus *bus);
void *(*map)(struct rt_pci_bus *bus, rt_uint32_t devfn, int reg);
rt_err_t (*read)(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
rt_err_t (*write)(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
};
struct rt_pci_bus
{
rt_list_t list;
rt_list_t children_nodes;
rt_list_t devices_nodes;
struct rt_pci_bus *parent;
union
{
/* In PCI-to-PCI bridge, parent is not NULL */
struct rt_pci_device *self;
/* In Host bridge, this is Root bus ('PCI Bus 0') */
struct rt_pci_host_bridge *host_bridge;
};
const struct rt_pci_ops *ops;
char name[48];
char number;
struct rt_spinlock lock;
void *sysdata;
};
struct rt_pci_driver
{
struct rt_driver parent;
const char *name;
const struct rt_pci_device_id *ids;
rt_err_t (*probe)(struct rt_pci_device *pdev);
rt_err_t (*remove)(struct rt_pci_device *pdev);
rt_err_t (*shutdown)(struct rt_pci_device *pdev);
};
struct rt_pci_msix_entry
{
int irq;
int index;
};
enum rt_pci_power
{
RT_PCI_D0,
RT_PCI_D1,
RT_PCI_D2,
RT_PCI_D3HOT,
RT_PCI_D3COLD,
RT_PCI_PME_MAX,
};
void rt_pci_pme_init(struct rt_pci_device *pdev);
void rt_pci_pme_active(struct rt_pci_device *pdev, rt_bool_t enable);
rt_err_t rt_pci_enable_wake(struct rt_pci_device *pci_dev,
enum rt_pci_power state, rt_bool_t enable);
rt_inline rt_bool_t rt_pci_pme_capable(struct rt_pci_device *pdev,
enum rt_pci_power state)
{
if (!pdev->pme_cap)
{
return RT_FALSE;
}
return !!(pdev->pme_support & (1 << state));
}
void rt_pci_msi_init(struct rt_pci_device *pdev);
void rt_pci_msix_init(struct rt_pci_device *pdev);
void rt_pci_set_master(struct rt_pci_device *pdev);
void rt_pci_clear_master(struct rt_pci_device *pdev);
struct rt_pci_host_bridge *rt_pci_host_bridge_alloc(rt_size_t priv_size);
rt_err_t rt_pci_host_bridge_free(struct rt_pci_host_bridge *);
rt_err_t rt_pci_host_bridge_init(struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_host_bridge_probe(struct rt_pci_host_bridge *host_bridge);
struct rt_pci_device *rt_pci_alloc_device(struct rt_pci_bus *bus);
struct rt_pci_device *rt_pci_scan_single_device(struct rt_pci_bus *bus, rt_uint32_t devfn);
rt_err_t rt_pci_setup_device(struct rt_pci_device *pdev);
rt_size_t rt_pci_scan_slot(struct rt_pci_bus *bus, rt_uint32_t devfn);
rt_uint32_t rt_pci_scan_child_buses(struct rt_pci_bus *bus, rt_size_t buses);
rt_uint32_t rt_pci_scan_child_bus(struct rt_pci_bus *bus);
rt_err_t rt_pci_host_bridge_register(struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_scan_root_bus_bridge(struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_host_bridge_remove(struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_bus_remove(struct rt_pci_bus *bus);
rt_err_t rt_pci_device_remove(struct rt_pci_device *pdev);
rt_uint32_t rt_pci_domain(struct rt_pci_device *pdev);
rt_uint8_t rt_pci_bus_find_capability(struct rt_pci_bus *bus, rt_uint32_t devfn, int cap);
rt_uint8_t rt_pci_find_capability(struct rt_pci_device *pdev, int cap);
rt_uint8_t rt_pci_find_next_capability(struct rt_pci_device *pdev, rt_uint8_t pos, int cap);
rt_uint16_t rt_pci_find_ext_capability(struct rt_pci_device *pdev, int cap);
rt_uint16_t rt_pci_find_ext_next_capability(struct rt_pci_device *pdev, rt_uint16_t pos, int cap);
struct rt_pci_bus *rt_pci_find_root_bus(struct rt_pci_bus *bus);
struct rt_pci_host_bridge *rt_pci_find_host_bridge(struct rt_pci_bus *bus);
rt_inline rt_uint16_t rt_pci_dev_id(struct rt_pci_device *pdev)
{
return RT_PCI_DEVID(pdev->bus->number, pdev->devfn);
}
rt_inline rt_bool_t rt_pci_is_root_bus(struct rt_pci_bus *bus)
{
return bus->parent ? RT_FALSE : RT_TRUE;
}
rt_inline rt_bool_t rt_pci_is_bridge(struct rt_pci_device *pdev)
{
return pdev->hdr_type == PCIM_HDRTYPE_BRIDGE ||
pdev->hdr_type == PCIM_HDRTYPE_CARDBUS;
}
rt_inline rt_bool_t rt_pci_is_pcie(struct rt_pci_device *pdev)
{
return !!pdev->pcie_cap;
}
#define rt_pci_foreach_bridge(pdev, bus) \
rt_list_for_each_entry(pdev, &bus->devices_nodes, list) \
if (rt_pci_is_bridge(pdev))
rt_err_t rt_pci_bus_read_config_u8(struct rt_pci_bus *bus,
rt_uint32_t devfn, int pos, rt_uint8_t *value);
rt_err_t rt_pci_bus_read_config_u16(struct rt_pci_bus *bus,
rt_uint32_t devfn, int pos, rt_uint16_t *value);
rt_err_t rt_pci_bus_read_config_u32(struct rt_pci_bus *bus,
rt_uint32_t devfn, int pos, rt_uint32_t *value);
rt_err_t rt_pci_bus_write_config_u8(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, rt_uint8_t value);
rt_err_t rt_pci_bus_write_config_u16(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, rt_uint16_t value);
rt_err_t rt_pci_bus_write_config_u32(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, rt_uint32_t value);
rt_err_t rt_pci_bus_read_config_uxx(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
rt_err_t rt_pci_bus_write_config_uxx(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
rt_err_t rt_pci_bus_read_config_generic_u32(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t *value);
rt_err_t rt_pci_bus_write_config_generic_u32(struct rt_pci_bus *bus,
rt_uint32_t devfn, int reg, int width, rt_uint32_t value);
rt_inline rt_err_t rt_pci_read_config_u8(const struct rt_pci_device *pdev,
int reg, rt_uint8_t *value)
{
return rt_pci_bus_read_config_u8(pdev->bus, pdev->devfn, reg, value);
}
rt_inline rt_err_t rt_pci_read_config_u16(const struct rt_pci_device *pdev,
int reg, rt_uint16_t *value)
{
return rt_pci_bus_read_config_u16(pdev->bus, pdev->devfn, reg, value);
}
rt_inline rt_err_t rt_pci_read_config_u32(const struct rt_pci_device *pdev,
int reg, rt_uint32_t *value)
{
return rt_pci_bus_read_config_u32(pdev->bus, pdev->devfn, reg, value);
}
rt_inline rt_err_t rt_pci_write_config_u8(const struct rt_pci_device *pdev,
int reg, rt_uint8_t value)
{
return rt_pci_bus_write_config_u8(pdev->bus, pdev->devfn, reg, value);
}
rt_inline rt_err_t rt_pci_write_config_u16(const struct rt_pci_device *pdev,
int reg, rt_uint16_t value)
{
return rt_pci_bus_write_config_u16(pdev->bus, pdev->devfn, reg, value);
}
rt_inline rt_err_t rt_pci_write_config_u32(const struct rt_pci_device *pdev,
int reg, rt_uint32_t value)
{
return rt_pci_bus_write_config_u32(pdev->bus, pdev->devfn, reg, value);
}
#ifdef RT_USING_OFW
int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev,
rt_uint8_t slot, rt_uint8_t pin);
rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
struct rt_pci_host_bridge *host_bridge);
rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus);
rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus);
rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev);
rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev);
#else
rt_inline rt_err_t rt_pci_ofw_host_bridge_init(struct rt_ofw_node *dev_np,
struct rt_pci_host_bridge *host_bridge)
{
return RT_EOK;
}
rt_inline rt_err_t rt_pci_ofw_bus_init(struct rt_pci_bus *bus)
{
return RT_EOK;
}
rt_inline rt_err_t rt_pci_ofw_bus_free(struct rt_pci_bus *bus)
{
return RT_EOK;
}
rt_inline rt_err_t rt_pci_ofw_device_init(struct rt_pci_device *pdev)
{
return RT_EOK;
}
rt_inline rt_err_t rt_pci_ofw_device_free(struct rt_pci_device *pdev)
{
return RT_EOK;
}
rt_inline int rt_pci_ofw_irq_parse_and_map(struct rt_pci_device *pdev,
rt_uint8_t slot, rt_uint8_t pin)
{
return -1;
}
rt_inline rt_err_t rt_pci_ofw_parse_ranges(struct rt_ofw_node *dev_np,
struct rt_pci_host_bridge *host_bridge)
{
return -RT_ENOSYS;
}
#endif /* RT_USING_OFW */
rt_inline void *rt_pci_iomap(struct rt_pci_device *pdev, int bar_idx)
{
struct rt_pci_bus_resource *res = &pdev->resource[bar_idx];
RT_ASSERT(bar_idx < RT_ARRAY_SIZE(pdev->resource));
return rt_ioremap((void *)res->base, res->size);
}
rt_uint8_t rt_pci_irq_intx(struct rt_pci_device *pdev, rt_uint8_t pin);
rt_uint8_t rt_pci_irq_slot(struct rt_pci_device *pdev, rt_uint8_t *pinp);
void rt_pci_assign_irq(struct rt_pci_device *pdev);
void rt_pci_intx(struct rt_pci_device *pdev, rt_bool_t enable);
rt_bool_t rt_pci_check_and_mask_intx(struct rt_pci_device *pdev);
rt_bool_t rt_pci_check_and_unmask_intx(struct rt_pci_device *pdev);
void rt_pci_irq_mask(struct rt_pci_device *pdev);
void rt_pci_irq_unmask(struct rt_pci_device *pdev);
#define RT_PCI_IRQ_F_LEGACY RT_BIT(0) /* Allow legacy interrupts */
#define RT_PCI_IRQ_F_MSI RT_BIT(1) /* Allow MSI interrupts */
#define RT_PCI_IRQ_F_MSIX RT_BIT(2) /* Allow MSI-X interrupts */
#define RT_PCI_IRQ_F_AFFINITY RT_BIT(3) /* Auto-assign affinity */
#define RT_PCI_IRQ_F_ALL_TYPES (RT_PCI_IRQ_F_LEGACY | RT_PCI_IRQ_F_MSI | RT_PCI_IRQ_F_MSIX)
#ifdef RT_PCI_MSI
rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max,
rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities)));
void rt_pci_free_vector(struct rt_pci_device *pdev);
rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev);
rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev);
rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev,
int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities)));
rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev);
rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev);
rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev,
struct rt_pci_msix_entry *entries, int min, int max,
RT_IRQ_AFFINITY_DECLARE((*affinities)));
#else
rt_inline rt_ssize_t rt_pci_alloc_vector(struct rt_pci_device *pdev, int min, int max,
rt_uint32_t flags, RT_IRQ_AFFINITY_DECLARE((*affinities)))
{
return -RT_ENOSYS;
}
rt_inline void rt_pci_free_vector(struct rt_pci_device *pdev)
{
return;
}
rt_inline rt_ssize_t rt_pci_msi_vector_count(struct rt_pci_device *pdev)
{
return 0;
}
rt_inline rt_err_t rt_pci_msi_disable(struct rt_pci_device *pdev)
{
return RT_EOK;
}
rt_inline rt_ssize_t rt_pci_msi_enable_range_affinity(struct rt_pci_device *pdev,
int min, int max, RT_IRQ_AFFINITY_DECLARE((*affinities)))
{
return -RT_ENOSYS;
}
rt_inline rt_ssize_t rt_pci_msix_vector_count(struct rt_pci_device *pdev)
{
return 0;
}
rt_inline rt_err_t rt_pci_msix_disable(struct rt_pci_device *pdev)
{
return RT_EOK;
}
rt_inline rt_ssize_t rt_pci_msix_enable_range_affinity(struct rt_pci_device *pdev,
struct rt_pci_msix_entry *entries, int min, int max,
RT_IRQ_AFFINITY_DECLARE((*affinities)))
{
return -RT_ENOSYS;
}
#endif /* RT_PCI_MSI */
rt_inline void rt_pci_msix_entry_index_linear(struct rt_pci_msix_entry *entries,
rt_size_t nvectors)
{
for (int i = 0; i < nvectors; ++i)
{
entries[i].index = i;
}
}
rt_inline rt_ssize_t rt_pci_msi_enable_range(struct rt_pci_device *pdev,
int min, int max)
{
return rt_pci_msi_enable_range_affinity(pdev, min, max, RT_NULL);
}
rt_inline rt_err_t rt_pci_msi_enable(struct rt_pci_device *pdev)
{
rt_ssize_t res = rt_pci_msi_enable_range(pdev, 1, 1);
return res == 1 ? res : RT_EOK;
}
rt_inline rt_ssize_t rt_pci_msix_enable_range(struct rt_pci_device *pdev,
struct rt_pci_msix_entry *entries, int min, int max)
{
return rt_pci_msix_enable_range_affinity(pdev, entries, min, max, RT_NULL);
}
rt_inline rt_ssize_t rt_pci_msix_enable(struct rt_pci_device *pdev,
struct rt_pci_msix_entry *entries, int count)
{
return rt_pci_msix_enable_range(pdev, entries, count, count);
}
rt_err_t rt_pci_region_setup(struct rt_pci_host_bridge *host_bridge);
struct rt_pci_bus_region *rt_pci_region_alloc(struct rt_pci_host_bridge *host_bridge,
void **out_addr, rt_size_t size, rt_ubase_t flags, rt_bool_t mem64);
rt_err_t rt_pci_device_alloc_resource(struct rt_pci_host_bridge *host_bridge,
struct rt_pci_device *pdev);
void rt_pci_enum_device(struct rt_pci_bus *bus,
rt_bool_t (callback(struct rt_pci_device *, void *)), void *data);
const struct rt_pci_device_id *rt_pci_match_id(struct rt_pci_device *pdev,
const struct rt_pci_device_id *id);
const struct rt_pci_device_id *rt_pci_match_ids(struct rt_pci_device *pdev,
const struct rt_pci_device_id *ids);
rt_err_t rt_pci_driver_register(struct rt_pci_driver *pdrv);
rt_err_t rt_pci_device_register(struct rt_pci_device *pdev);
struct rt_pci_bus_resource *rt_pci_find_bar(struct rt_pci_device* pdev,rt_ubase_t flags,int index);
#define RT_PCI_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, pci, BUILIN)
extern struct rt_spinlock rt_pci_lock;
#endif /* __PCI_H__ */

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __PCI_ENDPOINT_H__
#define __PCI_ENDPOINT_H__
#include <drivers/pci.h>
enum rt_pci_ep_pin
{
RT_PCI_EP_PIN_UNKNOWN,
RT_PCI_EP_PIN_INTA,
RT_PCI_EP_PIN_INTB,
RT_PCI_EP_PIN_INTC,
RT_PCI_EP_PIN_INTD,
};
enum rt_pci_ep_irq
{
RT_PCI_EP_IRQ_UNKNOWN,
RT_PCI_EP_IRQ_LEGACY,
RT_PCI_EP_IRQ_MSI,
RT_PCI_EP_IRQ_MSIX,
};
struct rt_pci_ep_header
{
rt_uint16_t vendor;
rt_uint16_t device;
rt_uint8_t revision;
rt_uint8_t progif;
rt_uint8_t subclass;
rt_uint8_t class_code;
rt_uint8_t cache_line_size;
rt_uint16_t subsystem_vendor;
rt_uint16_t subsystem_device;
enum rt_pci_ep_pin intx;
};
struct rt_pci_ep_bar
{
/* To PCI Bus */
struct rt_pci_bus_resource bus;
/* To CPU */
rt_ubase_t cpu_addr;
};
/*
* Type of MSI-X table, For more format detail,
* please read `components/drivers/include/drivers/pci_msi.h`
*/
struct rt_pci_ep_msix_tbl
{
union
{
rt_uint64_t msg_addr;
struct
{
rt_uint32_t msg_addr_upper;
rt_uint32_t msg_addr_lower;
};
};
rt_uint32_t msg_data;
rt_uint32_t vector_ctrl;
};
struct rt_pci_ep_ops;
struct rt_pci_ep_mem;
struct rt_pci_ep
{
rt_list_t list;
const char *name;
struct rt_ref ref;
const struct rt_device *rc_dev;
const struct rt_pci_ep_ops *ops;
rt_size_t mems_nr;
struct rt_pci_ep_mem *mems;
rt_uint8_t max_functions;
RT_BITMAP_DECLARE(functions_map, 8);
rt_list_t epf_nodes;
struct rt_mutex lock;
void *priv;
};
struct rt_pci_ep_mem
{
rt_ubase_t cpu_addr;
rt_size_t size;
rt_size_t page_size;
rt_bitmap_t *map;
rt_size_t bits;
};
struct rt_pci_epf
{
rt_list_t list;
const char *name;
struct rt_pci_ep_header *header;
struct rt_pci_ep_bar bar[PCI_STD_NUM_BARS];
rt_uint8_t msi_interrupts;
rt_uint16_t msix_interrupts;
rt_uint8_t func_no;
struct rt_pci_ep *ep;
};
struct rt_pci_ep_ops
{
rt_err_t (*write_header)(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_header *hdr);
rt_err_t (*set_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_bar *bar, int bar_idx);
rt_err_t (*clear_bar)(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_bar *bar, int bar_idx);
rt_err_t (*map_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no,
rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size);
rt_err_t (*unmap_addr)(struct rt_pci_ep *ep, rt_uint8_t func_no, rt_ubase_t addr);
rt_err_t (*set_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned irq_nr);
rt_err_t (*get_msi)(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned *out_irq_nr);
rt_err_t (*set_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned irq_nr, int bar_idx, rt_off_t offset);
rt_err_t (*get_msix)(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned *out_irq_nr);
rt_err_t (*raise_irq)(struct rt_pci_ep *ep, rt_uint8_t func_no,
enum rt_pci_ep_irq type, unsigned irq);
rt_err_t (*start)(struct rt_pci_ep *ep);
rt_err_t (*stop)(struct rt_pci_ep *ep);
};
rt_err_t rt_pci_ep_write_header(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_header *hdr);
rt_err_t rt_pci_ep_set_bar(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_bar *bar, int bar_idx);
rt_err_t rt_pci_ep_clear_bar(struct rt_pci_ep *ep, rt_uint8_t func_no,
struct rt_pci_ep_bar *bar, int bar_idx);
rt_err_t rt_pci_ep_map_addr(struct rt_pci_ep *ep, rt_uint8_t func_no,
rt_ubase_t addr, rt_uint64_t pci_addr, rt_size_t size);
rt_err_t rt_pci_ep_unmap_addr(struct rt_pci_ep *ep, rt_uint8_t func_no,
rt_ubase_t addr);
rt_err_t rt_pci_ep_set_msi(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned irq_nr);
rt_err_t rt_pci_ep_get_msi(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned *out_irq_nr);
rt_err_t rt_pci_ep_set_msix(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned irq_nr, int bar_idx, rt_off_t offset);
rt_err_t rt_pci_ep_get_msix(struct rt_pci_ep *ep, rt_uint8_t func_no,
unsigned *out_irq_nr);
rt_err_t rt_pci_ep_raise_irq(struct rt_pci_ep *ep, rt_uint8_t func_no,
enum rt_pci_ep_irq type, unsigned irq);
rt_err_t rt_pci_ep_start(struct rt_pci_ep *ep);
rt_err_t rt_pci_ep_stop(struct rt_pci_ep *ep);
rt_err_t rt_pci_ep_register(struct rt_pci_ep *ep);
rt_err_t rt_pci_ep_unregister(struct rt_pci_ep *ep);
rt_err_t rt_pci_ep_mem_array_init(struct rt_pci_ep *ep,
struct rt_pci_ep_mem *mems, rt_size_t mems_nr);
rt_err_t rt_pci_ep_mem_init(struct rt_pci_ep *ep,
rt_ubase_t cpu_addr, rt_size_t size, rt_size_t page_size);
void *rt_pci_ep_mem_alloc(struct rt_pci_ep *ep,
rt_ubase_t *out_cpu_addr, rt_size_t size);
void rt_pci_ep_mem_free(struct rt_pci_ep *ep,
void *vaddr, rt_ubase_t cpu_addr, rt_size_t size);
rt_err_t rt_pci_ep_add_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf);
rt_err_t rt_pci_ep_remove_epf(struct rt_pci_ep *ep, struct rt_pci_epf *epf);
struct rt_pci_ep *rt_pci_ep_get(const char *name);
void rt_pci_ep_put(struct rt_pci_ep *ep);
#endif /* __PCI_ENDPOINT_H__ */

View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-25 GuEe-GUI first version
*/
#ifndef __PCI_MSI_H__
#define __PCI_MSI_H__
#include <drivers/pci.h>
/*
* MSI Format:
* T0: 32-bit Address
* T1: 64-bit Address
* T2: 32-bit Address with Per-Vector Masking
* T3: 64-bit Address with Per-Vector Masking
*
* 31 16 15 8 7 0
* +---------------------------+-----------------+---------------+
* | Message Control | Next Capability | Capability ID | DW0
* | | Pointer | (05h) |
* +---------------------------+-----------------+---------------+
* | Message Address [31:0] | DW1
* +-------------------------------------------------------------+
* | Message Address [63:32] | DW2 (T1: only 64-bit)
* +---------------------------+---------------------------------+
* | Reserved | Message Data | DW3
* +---------------------------+---------------------------------+
* | Mask Bits | DW4 (T2/T3: only with Per-Vector Masking)
* +-------------------------------------------------------------+
* | Pending Bits | DW5 (T2/T3: only with Per-Vector Masking)
* +-------------------------------------------------------------+
*
* MSI Message Control:
*
* 15 9 8 7 6 4 3 1 0
* +----------------------+---+---+---------------+----------+---+
* | Reserved | | | | | |
* +----------------------+---+---+---------------+----------+---+
* ^ ^ ^ ^ ^
* | | | | |
* | | | | +---- MSI Enable (RW)
* | | | +----------- Multiple Message Capable (RO, log2n, [n <= 5])
* | | +------------------------- Multiple Message Enable (RW, log2n, [n <= 5])
* | +----------------------------------- 64-bit Address Capable
* +--------------------------------------- Per-Vector Masking Capable
*/
struct rt_pci_msi_conf
{
rt_uint32_t mask;
rt_uint8_t mask_pos;
int default_irq;
struct
{
rt_uint8_t is_masking:1;
rt_uint8_t is_64bit:1;
rt_uint8_t multi_msg_max:3; /* log2 num of messages allocated */
rt_uint8_t multi_msg_use:3; /* log2 num of messages supported */
} cap;
};
/*
* MSI-X Format:
*
* 31 16 15 8 7 0
* +---------------------------+-----------------+---------------+
* | Message Control | Next Capability | Capability ID | DW0
* | | Pointer | (11h) |
* +---------------------------+-----------------+---+-----------+
* | MSI-X Table Offset | Table BIR | DW1 (BIR: BAR Index Register)
* +-------------------------------------------------+-----------+ |
* | Pending Bit Array (PBA) Offset | PBA BIR | DW2 --------+ |
* +-------------------------------------------------+-----------+ | |
* | |
* MSI-X Message Control: | |
* | |
* 15 14 13 11 10 0 | |
* +---+---+----------+------------------------------------------+ | |
* | | | Reserved | Table Size in N-1 (RO) | | |
* +---+---+----------+------------------------------------------+ | |
* ^ ^ | |
* | | | |
* | +---- Function Mask (RW) | |
* +-------- MSI-X Enable (RW) | |
* | |
* MSI-X Table (BAR[Table BIR] + MSI-X Table Offset): | |
* | |
* DW3 DW2 DW1 DW0 | |
* +----------------+--------------+---------------+---------------+ <---------|-+
* | Vector Control | Message Data | Upper Address | Lower Address | Entry 0 |
* +----------------+--------------+---------------+---------------+ |
* | Vector Control | Message Data | Upper Address | Lower Address | Entry 1 |
* +----------------+--------------+---------------+---------------+ |
* | ...... | ...... | ...... | ...... | |
* +----------------+--------------+---------------+---------------+ |
* | Vector Control | Message Data | Upper Address | Lower Address | Entry N-1 |
* +----------------+--------------+---------------+---------------+ |
* ^ |
* | |
* +---- Bit 0 is vector Mask Bit (R/W) |
* |
* MSI-X Pending Bit Array (BAR[PBA BIR] + Pending Bit Array Offset): |
* |
* DW1 DW0 |
* +-------------------------------+ <-----------------------------------------+
* | Pending Bits 0 - 63 | QW 0
* +-------------------------------+
* | Pending Bits 64 - 127 | QW 1
* +-------------------------------+
* | ...... |
* +-------------------------------+
* | Pending Bits | QW (N-1)/64
* +-------------------------------+
*/
struct rt_pci_msix_conf
{
int index;
rt_uint32_t msg_ctrl;
void *table_base;
};
struct rt_pci_msi_msg
{
rt_uint32_t address_lo;
rt_uint32_t address_hi;
rt_uint32_t data;
};
struct rt_pci_msi_desc
{
rt_list_t list;
int irq;
rt_size_t vector_used;
rt_size_t vector_count;
union
{
/* For MSI-X */
rt_bitmap_t *affinity;
/* For MSI */
rt_bitmap_t **affinities;
};
struct rt_pci_device *pdev;
struct rt_pci_msi_msg msg;
void *write_msi_msg_data;
void (*write_msi_msg)(struct rt_pci_msi_desc *, void *);
rt_bool_t is_msix;
union
{
struct rt_pci_msi_conf msi;
struct rt_pci_msix_conf msix;
};
void *priv;
};
#define rt_pci_msi_first_desc(pdev) \
(rt_list_isempty(&(pdev)->msi_desc_nodes) ? RT_NULL : \
rt_list_first_entry(&(pdev)->msi_desc_nodes, struct rt_pci_msi_desc, list))
#define rt_pci_msi_for_each_desc(pdev, desc) \
rt_list_for_each_entry(desc, &(pdev)->msi_desc_nodes, list)
#define rt_pci_msix_table_size(flags) ((flags & PCIM_MSIXCTRL_TABLE_SIZE) + 1)
rt_err_t rt_pci_msi_setup_irqs(struct rt_pci_device *pdev, int nvec, int type);
void rt_pci_msi_shutdown(struct rt_pci_device *pdev);
void rt_pci_msix_shutdown(struct rt_pci_device *pdev);
void rt_pci_msi_free_irqs(struct rt_pci_device *pdev);
void rt_pci_msi_write_msg(struct rt_pci_msi_desc *desc, struct rt_pci_msi_msg *msg);
void rt_pci_msi_mask_irq(struct rt_pic_irq *pirq);
void rt_pci_msi_unmask_irq(struct rt_pic_irq *pirq);
#endif /* __PCI_MSI_H__ */

View File

@ -0,0 +1,225 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-10-14 wangqiang the first version
* 2022-08-17 xjy198903 add 1000M definition
* 2024-10-08 zhujiale add phy v2.0
*/
#ifndef __NET_PHY_H__
#define __NET_PHY_H__
#include <rtthread.h>
#include <drivers/core/driver.h>
#ifdef RT_USING_PHY_V2
#include <ofw.h>
#include <mdio.h>
#include <general_phy.h>
#define RT_PHY_FIXED_ID 0xa5a55a5a
#define RT_PHY_NCSI_ID 0xbeefcafe
/* Indicates what features are supported by the interface. */
#define RT_SUPPORTED_10baseT_Half (1 << 0)
#define RT_SUPPORTED_10baseT_Full (1 << 1)
#define RT_SUPPORTED_100baseT_Half (1 << 2)
#define RT_SUPPORTED_100baseT_Full (1 << 3)
#define RT_SUPPORTED_1000baseT_Half (1 << 4)
#define RT_SUPPORTED_1000baseT_Full (1 << 5)
#define RT_SUPPORTED_Autoneg (1 << 6)
#define RT_SUPPORTED_TP (1 << 7)
#define RT_SUPPORTED_AUI (1 << 8)
#define RT_SUPPORTED_MII (1 << 9)
#define RT_SUPPORTED_FIBRE (1 << 10)
#define RT_SUPPORTED_BNC (1 << 11)
#define RT_SUPPORTED_10000baseT_Full (1 << 12)
#define RT_SUPPORTED_Pause (1 << 13)
#define RT_SUPPORTED_Asym_Pause (1 << 14)
#define RT_SUPPORTED_2500baseX_Full (1 << 15)
#define RT_SUPPORTED_Backplane (1 << 16)
#define RT_SUPPORTED_1000baseKX_Full (1 << 17)
#define RT_SUPPORTED_10000baseKX4_Full (1 << 18)
#define RT_SUPPORTED_10000baseKR_Full (1 << 19)
#define RT_SUPPORTED_10000baseR_FEC (1 << 20)
#define RT_SUPPORTED_1000baseX_Half (1 << 21)
#define RT_SUPPORTED_1000baseX_Full (1 << 22)
#define RT_PHY_FLAG_BROKEN_RESET (1 << 0) /* soft reset not supported */
#define RT_PHY_DEFAULT_FEATURES (RT_SUPPORTED_Autoneg | RT_SUPPORTED_TP | RT_SUPPORTED_MII)
#define RT_PHY_10BT_FEATURES (RT_SUPPORTED_10baseT_Half | RT_SUPPORTED_10baseT_Full)
#define RT_PHY_100BT_FEATURES (RT_SUPPORTED_100baseT_Half | RT_SUPPORTED_100baseT_Full)
#define RT_PHY_1000BT_FEATURES (RT_SUPPORTED_1000baseT_Half | RT_SUPPORTED_1000baseT_Full)
#define RT_PHY_BASIC_FEATURES (RT_PHY_10BT_FEATURES | RT_PHY_100BT_FEATURES | RT_PHY_DEFAULT_FEATURES)
#define RT_PHY_GBIT_FEATURES (RT_PHY_BASIC_FEATURES | RT_PHY_1000BT_FEATURES)
#define RT_PHY_10G_FEATURES (RT_PHY_GBIT_FEATURES | RT_SUPPORTED_10000baseT_Full)
struct rt_phy_device
{
struct rt_device parent;
struct mii_bus *bus;
struct rt_phy_driver *drv;
rt_uint32_t phy_id;
rt_uint32_t mmds;
int speed;
int duplex;
int link;
int port;
rt_uint32_t advertising;
rt_uint32_t supported;
rt_bool_t autoneg;
int pause;
rt_ubase_t addr;
rt_bool_t is_c45;
rt_uint32_t flags;
rt_phy_interface interface;
#ifdef RT_USING_OFW
struct rt_ofw_node *node;
#endif
void *priv;
};
struct rt_phy_driver
{
struct rt_driver parent;
char name[RT_NAME_MAX];
rt_uint64_t uid;
rt_uint64_t mask;
rt_uint64_t mmds;
rt_uint32_t features;
int (*probe)(struct rt_phy_device *phydev);
int (*config)(struct rt_phy_device *phydev);
int (*startup)(struct rt_phy_device *phydev);
int (*shutdown)(struct rt_phy_device *phydev);
int (*read)(struct rt_phy_device *phydev, int addr, int devad, int reg);
int (*write)(struct rt_phy_device *phydev, int addr, int devad, int reg,
rt_uint16_t val);
int (*read_mmd)(struct rt_phy_device *phydev, int devad, int reg);
int (*write_mmd)(struct rt_phy_device *phydev, int devad, int reg,
rt_uint16_t val);
/* driver private data */
void *data;
};
int rt_phy_read(struct rt_phy_device *phydev, int devad, int regnum);
int rt_phy_write(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val);
int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum);
int rt_phy_write_mmd(struct rt_phy_device *phydev, int devad, int regnum, rt_uint16_t val);
int rt_phy_reset(struct rt_phy_device *phydev);
int rt_phy_startup(struct rt_phy_device *phydev);
int rt_phy_config(struct rt_phy_device *phydev);
int rt_phy_shutdown(struct rt_phy_device *phydev);
int rt_phy_read_mmd(struct rt_phy_device *phydev, int devad, int regnum);
int rt_phy_set_supported(struct rt_phy_device *phydev, rt_uint32_t max_speed);
void rt_phy_mmd_start_indirect(struct rt_phy_device *phydev, int devad, int regnum);
rt_err_t rt_phy_device_register(struct rt_phy_device *pdev);
rt_err_t rt_phy_driver_register(struct rt_phy_driver *pdrv);
rt_err_t rt_ofw_get_phyid(struct rt_ofw_node *np,rt_uint32_t *id);
struct rt_phy_device *rt_phy_device_create(struct mii_bus *bus, int addr, rt_uint32_t phy_id, rt_bool_t is_c45);
struct rt_phy_device *rt_phy_find_by_mask(struct mii_bus *bus, unsigned int phy_mask);
struct rt_phy_device *rt_ofw_create_phy(struct mii_bus *bus, struct rt_ofw_node *np, int phyaddr);
struct rt_phy_device *rt_phy_get_device(struct mii_bus *bus, struct rt_ofw_node *np, int addr, rt_phy_interface interface);
#define RT_PHY_DEVICE_REGISTER(phy_dev) \
static int rt_##phy_dev##_register(void) \
{ \
rt_phy_device_register(&phy_dev); \
return 0; \
} \
INIT_PREV_EXPORT(rt_##phy_dev##_register);
#define RT_PHY_DRIVER_REGISTER(phy_drv) \
static int rt_##phy_drv##_register(void) \
{ \
rt_phy_driver_register(&phy_drv); \
return 0; \
} \
INIT_PREV_EXPORT(rt_##phy_drv##_register);
#endif
#ifdef RT_USING_PHY
#ifdef __cplusplus
extern "C"
{
#endif
struct rt_mdio_bus_ops
{
rt_bool_t (*init)(void *bus, rt_uint32_t src_clock_hz);
rt_size_t (*read)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
rt_size_t (*write)(void *bus, rt_uint32_t addr, rt_uint32_t reg, void *data, rt_uint32_t size);
rt_bool_t (*uninit)(void *bus);
};
struct rt_mdio_bus
{
void *hw_obj;
char *name;
struct rt_mdio_bus_ops *ops;
};
typedef struct rt_mdio_bus rt_mdio_t;
/* Defines the PHY link speed. This is align with the speed for MAC. */
#define PHY_SPEED_10M 0U /* PHY 10M speed. */
#define PHY_SPEED_100M 1U /* PHY 100M speed. */
#define PHY_SPEED_1000M 2U /* PHY 1000M speed. */
/* Defines the PHY link duplex. */
#define PHY_HALF_DUPLEX 0U /* PHY half duplex. */
#define PHY_FULL_DUPLEX 1U /* PHY full duplex. */
/*! @brief Defines the PHY loopback mode. */
#define PHY_LOCAL_LOOP 0U /* PHY local loopback. */
#define PHY_REMOTE_LOOP 1U /* PHY remote loopback. */
#define PHY_STATUS_OK 0U
#define PHY_STATUS_FAIL 1U
#define PHY_STATUS_TIMEOUT 2U
typedef struct rt_phy_msg
{
rt_uint32_t reg;
rt_uint32_t value;
}rt_phy_msg_t;
typedef struct rt_phy_device
{
struct rt_device parent;
struct rt_mdio_bus *bus;
rt_uint32_t addr;
struct rt_phy_ops *ops;
}rt_phy_t;
typedef rt_int32_t rt_phy_status;
struct rt_phy_ops
{
rt_phy_status (*init)(void *object, rt_uint32_t phy_addr, rt_uint32_t src_clock_hz);
rt_phy_status (*read)(rt_phy_t *phy, rt_uint32_t reg, rt_uint32_t *data);
rt_phy_status (*write)(rt_phy_t *phy, rt_uint32_t reg, rt_uint32_t data);
rt_phy_status (*loopback)(rt_phy_t *phy, rt_uint32_t mode, rt_uint32_t speed, rt_bool_t enable);
rt_phy_status (*get_link_status)(rt_phy_t *phy, rt_bool_t *status);
rt_phy_status (*get_link_speed_duplex)(rt_phy_t *phy, rt_uint32_t *speed, rt_uint32_t *duplex);
};
rt_err_t rt_hw_phy_register(struct rt_phy_device *phy, const char *name);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-10-24 GuEe-GUI first version
*/
#ifndef __PHYE_H__
#define __PHYE_H__
#include <rtthread.h>
#include <drivers/ofw.h>
enum rt_phye_mode
{
RT_PHYE_MODE_INVALID,
RT_PHYE_MODE_USB_HOST,
RT_PHYE_MODE_USB_HOST_LS,
RT_PHYE_MODE_USB_HOST_FS,
RT_PHYE_MODE_USB_HOST_HS,
RT_PHYE_MODE_USB_HOST_SS,
RT_PHYE_MODE_USB_DEVICE,
RT_PHYE_MODE_USB_DEVICE_LS,
RT_PHYE_MODE_USB_DEVICE_FS,
RT_PHYE_MODE_USB_DEVICE_HS,
RT_PHYE_MODE_USB_DEVICE_SS,
RT_PHYE_MODE_USB_OTG,
RT_PHYE_MODE_UFS_HS_A,
RT_PHYE_MODE_UFS_HS_B,
RT_PHYE_MODE_PCIE,
RT_PHYE_MODE_ETHERNET,
RT_PHYE_MODE_MIPI_DPHY,
RT_PHYE_MODE_SATA,
RT_PHYE_MODE_LVDS,
RT_PHYE_MODE_DP,
RT_PHYE_MODE_MAX,
/* PCIe */
RT_PHYE_MODE_PCIE_RC = RT_PHYE_MODE_MAX,
RT_PHYE_MODE_PCIE_EP,
RT_PHYE_MODE_PCIE_BIFURCATION,
};
struct rt_phye_ops;
struct rt_phye
{
struct rt_device *dev;
const struct rt_phye_ops *ops;
int init_count;
int power_count;
struct rt_spinlock lock;
};
struct rt_phye_ops
{
rt_err_t (*init)(struct rt_phye *phye);
rt_err_t (*exit)(struct rt_phye *phye);
rt_err_t (*reset)(struct rt_phye *phye);
rt_err_t (*power_on)(struct rt_phye *phye);
rt_err_t (*power_off)(struct rt_phye *phye);
rt_err_t (*set_mode)(struct rt_phye *phye, enum rt_phye_mode mode, int submode);
rt_err_t (*ofw_parse)(struct rt_phye *phye, struct rt_ofw_cell_args *phye_args);
};
rt_err_t rt_phye_register(struct rt_phye *phye);
rt_err_t rt_phye_unregister(struct rt_phye *phye);
rt_err_t rt_phye_init(struct rt_phye *phye);
rt_err_t rt_phye_exit(struct rt_phye *phye);
rt_err_t rt_phye_reset(struct rt_phye *phye);
rt_err_t rt_phye_power_on(struct rt_phye *phye);
rt_err_t rt_phye_power_off(struct rt_phye *phye);
rt_err_t rt_phye_set_mode(struct rt_phye *phye, enum rt_phye_mode mode, int submode);
rt_inline rt_err_t rt_phye_set_mode_simple(struct rt_phye *phye, enum rt_phye_mode mode)
{
return rt_phye_set_mode(phye, mode, RT_PHYE_MODE_INVALID);
}
struct rt_phye *rt_phye_get_by_index(struct rt_device *dev, int index);
struct rt_phye *rt_phye_get_by_name(struct rt_device *dev, const char *id);
void rt_phye_put(struct rt_phye *phye);
#endif /* __PHYE_H__ */

View File

@ -0,0 +1,217 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-08-24 GuEe-GUI first version
*/
#ifndef __PIC_H__
#define __PIC_H__
#include <rthw.h>
#include <bitmap.h>
#include <drivers/ofw.h>
#include <drivers/core/dm.h>
struct rt_pci_msi_desc;
struct rt_pci_msi_msg;
struct rt_pic_ops;
struct rt_pic_irq;
struct rt_pic
{
/*
* Other IC is not implemented with PIC but rt_device/object, we need to
* identify with this object:
*
* struct rt_ic_XYZ_device
* {
* struct rt_device parent;
* struct rt_pic pic;
* ...
* };
*/
struct rt_object parent;
rt_list_t list;
const struct rt_pic_ops *ops;
void *priv_data;
void *user_data;
int irq_start;
rt_size_t irq_nr;
struct rt_pic_irq *pirqs;
};
struct rt_pic_ops
{
const char *name;
rt_err_t (*irq_init)(struct rt_pic *pic);
rt_err_t (*irq_finit)(struct rt_pic *pic);
void (*irq_enable)(struct rt_pic_irq *pirq);
void (*irq_disable)(struct rt_pic_irq *pirq);
void (*irq_ack)(struct rt_pic_irq *pirq);
void (*irq_mask)(struct rt_pic_irq *pirq);
void (*irq_unmask)(struct rt_pic_irq *pirq);
void (*irq_eoi)(struct rt_pic_irq *pirq);
rt_err_t (*irq_set_priority)(struct rt_pic_irq *pirq, rt_uint32_t priority);
rt_err_t (*irq_set_affinity)(struct rt_pic_irq *pirq, rt_bitmap_t *affinity);
rt_err_t (*irq_set_triger_mode)(struct rt_pic_irq *pirq, rt_uint32_t mode);
void (*irq_send_ipi)(struct rt_pic_irq *pirq, rt_bitmap_t *cpumask);
void (*irq_compose_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg);
void (*irq_write_msi_msg)(struct rt_pic_irq *pirq, struct rt_pci_msi_msg *msg);
int (*irq_alloc_msi)(struct rt_pic *pic, struct rt_pci_msi_desc *msi_desc);
void (*irq_free_msi)(struct rt_pic *pic, int irq);
#define RT_IRQ_STATE_PENDING 0
#define RT_IRQ_STATE_ACTIVE 1
#define RT_IRQ_STATE_MASKED 2
rt_err_t (*irq_set_state)(struct rt_pic *pic, int hwirq, int type, rt_bool_t state);
rt_err_t (*irq_get_state)(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state);
int (*irq_map)(struct rt_pic *pic, int hwirq, rt_uint32_t mode);
rt_err_t (*irq_parse)(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq);
#define RT_PIC_F_IRQ_ROUTING RT_BIT(0) /* Routing ISR when cascade */
rt_ubase_t flags;
};
struct rt_pic_isr
{
rt_list_t list;
#define RT_IRQ_F_NONE 0
int flags;
struct rt_irq_desc action;
};
#define RT_IRQ_AFFINITY_DECLARE(name) RT_BITMAP_DECLARE(name, RT_CPUS_NR)
#define RT_IRQ_AFFINITY_SET(affinity, cpuid) rt_bitmap_set_bit(affinity, cpuid)
#define RT_IRQ_AFFINITY_CLEAR(affinity, cpuid) rt_bitmap_clear_bit(affinity, cpuid)
#ifdef RT_USING_PIC_STATISTICS
struct rt_pic_irq_statistics
{
rt_ubase_t max_irq_time_ns;
rt_ubase_t min_irq_time_ns;
rt_ubase_t sum_irq_time_ns;
};
#endif
struct rt_pic_irq
{
int irq;
int hwirq;
#define RT_IRQ_MODE_NONE 0
#define RT_IRQ_MODE_EDGE_RISING 1
#define RT_IRQ_MODE_EDGE_FALLING 2
#define RT_IRQ_MODE_EDGE_BOTH (RT_IRQ_MODE_EDGE_FALLING | RT_IRQ_MODE_EDGE_RISING)
#define RT_IRQ_MODE_LEVEL_HIGH 4
#define RT_IRQ_MODE_LEVEL_LOW 8
#define RT_IRQ_MODE_LEVEL_MASK (RT_IRQ_MODE_LEVEL_LOW | RT_IRQ_MODE_LEVEL_HIGH)
#define RT_IRQ_MODE_MASK 0xf
rt_uint32_t mode;
rt_uint32_t priority;
RT_IRQ_AFFINITY_DECLARE(affinity);
rt_list_t list;
rt_list_t children_nodes;
struct rt_pci_msi_desc *msi_desc;
struct rt_pic_isr isr;
struct rt_spinlock rw_lock;
struct rt_pic *pic;
struct rt_pic_irq *parent;
#ifdef RT_USING_PIC_STATISTICS
struct rt_pic_irq_statistics stat;
#endif
};
void rt_pic_default_name(struct rt_pic *pic);
struct rt_pic *rt_pic_dynamic_cast(void *ptr);
rt_err_t rt_pic_linear_irq(struct rt_pic *pic, rt_size_t irq_nr);
rt_err_t rt_pic_cancel_irq(struct rt_pic *pic);
int rt_pic_config_ipi(struct rt_pic *pic, int ipi_index, int hwirq);
int rt_pic_config_irq(struct rt_pic *pic, int irq_index, int hwirq);
rt_inline struct rt_pic_irq *rt_pic_find_irq(struct rt_pic *pic, int irq_index)
{
/* This is a quickly interface */
RT_ASSERT(pic != RT_NULL);
RT_ASSERT(pic->pirqs != RT_NULL);
RT_ASSERT(irq_index < pic->irq_nr);
return &pic->pirqs[irq_index];
}
struct rt_pic_irq *rt_pic_find_ipi(struct rt_pic *pic, int ipi_index);
struct rt_pic_irq *rt_pic_find_pirq(struct rt_pic *pic, int irq);
rt_err_t rt_pic_cascade(struct rt_pic_irq *pirq, int parent_irq);
rt_err_t rt_pic_uncascade(struct rt_pic_irq *pirq);
rt_err_t rt_pic_attach_irq(int irq, rt_isr_handler_t handler, void *uid, const char *name, int flags);
rt_err_t rt_pic_detach_irq(int irq, void *uid);
rt_err_t rt_pic_add_traps(rt_bool_t (*handler)(void *), void *data);
rt_err_t rt_pic_do_traps(void);
rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq);
/* User-implemented extensions */
rt_err_t rt_pic_user_extends(struct rt_pic *pic);
rt_err_t rt_pic_irq_init(void);
rt_err_t rt_pic_irq_finit(void);
void rt_pic_irq_enable(int irq);
void rt_pic_irq_disable(int irq);
void rt_pic_irq_ack(int irq);
void rt_pic_irq_mask(int irq);
void rt_pic_irq_unmask(int irq);
void rt_pic_irq_eoi(int irq);
rt_err_t rt_pic_irq_set_priority(int irq, rt_uint32_t priority);
rt_uint32_t rt_pic_irq_get_priority(int irq);
rt_err_t rt_pic_irq_set_affinity(int irq, rt_bitmap_t *affinity);
rt_err_t rt_pic_irq_get_affinity(int irq, rt_bitmap_t *out_affinity);
rt_err_t rt_pic_irq_set_triger_mode(int irq, rt_uint32_t mode);
rt_uint32_t rt_pic_irq_get_triger_mode(int irq);
void rt_pic_irq_send_ipi(int irq, rt_bitmap_t *cpumask);
rt_err_t rt_pic_irq_set_state_raw(struct rt_pic *pic, int hwirq, int type, rt_bool_t state);
rt_err_t rt_pic_irq_get_state_raw(struct rt_pic *pic, int hwirq, int type, rt_bool_t *out_state);
rt_err_t rt_pic_irq_set_state(int irq, int type, rt_bool_t state);
rt_err_t rt_pic_irq_get_state(int irq, int type, rt_bool_t *out_state);
void rt_pic_irq_parent_enable(struct rt_pic_irq *pirq);
void rt_pic_irq_parent_disable(struct rt_pic_irq *pirq);
void rt_pic_irq_parent_ack(struct rt_pic_irq *pirq);
void rt_pic_irq_parent_mask(struct rt_pic_irq *pirq);
void rt_pic_irq_parent_unmask(struct rt_pic_irq *pirq);
void rt_pic_irq_parent_eoi(struct rt_pic_irq *pirq);
rt_err_t rt_pic_irq_parent_set_priority(struct rt_pic_irq *pirq, rt_uint32_t priority);
rt_err_t rt_pic_irq_parent_set_affinity(struct rt_pic_irq *pirq, rt_bitmap_t *affinity);
rt_err_t rt_pic_irq_parent_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode);
#define RT_PIC_OFW_DECLARE(name, ids, handler) RT_OFW_STUB_EXPORT(name, ids, pic, handler)
rt_err_t rt_pic_init(void);
#endif /* __PIC_H__ */

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-04-12 ErikChan the first version
* 2023-10-13 zmshahaha distinguish ofw and none-ofw situation
*/
#ifndef __PLATFORM_H__
#define __PLATFORM_H__
#include <drivers/ofw.h>
#include <drivers/core/driver.h>
struct rt_platform_device
{
struct rt_device parent;
int dev_id;
const char *name;
const struct rt_ofw_node_id *id;
void *priv;
};
struct rt_platform_driver
{
struct rt_driver parent;
const char *name;
const struct rt_ofw_node_id *ids;
rt_err_t (*probe)(struct rt_platform_device *pdev);
rt_err_t (*remove)(struct rt_platform_device *pdev);
rt_err_t (*shutdown)(struct rt_platform_device *pdev);
};
struct rt_platform_device *rt_platform_device_alloc(const char *name);
rt_err_t rt_platform_driver_register(struct rt_platform_driver *pdrv);
rt_err_t rt_platform_device_register(struct rt_platform_device *pdev);
rt_err_t rt_platform_ofw_device_probe_child(struct rt_ofw_node *np);
rt_err_t rt_platform_ofw_request(struct rt_ofw_node *np);
rt_err_t rt_platform_ofw_free(struct rt_platform_device *pdev);
#define RT_PLATFORM_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, platform, BUILIN)
#endif /* __PLATFORM_H__ */

View File

@ -0,0 +1,231 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-06-02 Bernard the first version
* 2018-08-02 Tanek split run and sleep modes, support custom mode
* 2019-04-28 Zero-Free improve PM mode and device ops interface
* 2020-11-23 zhangsz update pm mode select
* 2020-11-27 zhangsz update pm 2.0
* 2024-07-04 wdfk-prog The device is registered and uninstalled by linked list
*/
#ifndef __PM_H__
#define __PM_H__
#include <stdint.h>
#include <rtthread.h>
#include <drivers/lptimer.h>
/* All modes used for rt_pm_request() and rt_pm_release() */
enum
{
/* sleep modes */
PM_SLEEP_MODE_NONE = 0,
PM_SLEEP_MODE_IDLE,
PM_SLEEP_MODE_LIGHT,
PM_SLEEP_MODE_DEEP,
PM_SLEEP_MODE_STANDBY,
PM_SLEEP_MODE_SHUTDOWN,
PM_SLEEP_MODE_MAX,
};
enum
{
/* run modes*/
PM_RUN_MODE_HIGH_SPEED = 0,
PM_RUN_MODE_NORMAL_SPEED,
PM_RUN_MODE_MEDIUM_SPEED,
PM_RUN_MODE_LOW_SPEED,
PM_RUN_MODE_MAX,
};
enum
{
RT_PM_FREQUENCY_PENDING = 0x01,
};
/* The name of all modes used in the msh command "pm_dump" */
#define PM_SLEEP_MODE_NAMES \
{ \
"None Mode", \
"Idle Mode", \
"LightSleep Mode", \
"DeepSleep Mode", \
"Standby Mode", \
"Shutdown Mode", \
}
#define PM_RUN_MODE_NAMES \
{ \
"High Speed", \
"Normal Speed", \
"Medium Speed", \
"Low Mode", \
}
#ifndef PM_USING_CUSTOM_CONFIG
/**
* Modules used for
* pm_module_request(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
* pm_module_release(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
* pm_module_release_all(PM_BOARD_ID, PM_SLEEP_MODE_IDLE)
*/
enum pm_module_id {
PM_NONE_ID = 0,
PM_POWER_ID,
PM_BOARD_ID,
PM_BSP_ID,
PM_MAIN_ID,
PM_PMS_ID,
PM_PMC_ID,
PM_TASK_ID,
PM_SPI_ID,
PM_I2C_ID,
PM_UART_ID,
PM_CAN_ID,
PM_ETH_ID,
PM_SENSOR_ID,
PM_LCD_ID,
PM_KEY_ID,
PM_TP_ID,
PM_MODULE_MAX_ID, /* enum must! */
};
#else
#include <pm_cfg.h>
#endif /* PM_USING_CUSTOM_CONFIG */
#ifndef RT_PM_DEFAULT_SLEEP_MODE
#define RT_PM_DEFAULT_SLEEP_MODE PM_SLEEP_MODE_NONE
#endif
#ifndef RT_PM_DEFAULT_DEEPSLEEP_MODE
#define RT_PM_DEFAULT_DEEPSLEEP_MODE PM_SLEEP_MODE_DEEP
#endif
#ifndef RT_PM_DEFAULT_RUN_MODE
#define RT_PM_DEFAULT_RUN_MODE PM_RUN_MODE_NORMAL_SPEED
#endif
/**
* device control flag to request or release power
*/
#define RT_PM_DEVICE_CTRL_RELEASE (RT_DEVICE_CTRL_BASE(PM) + 0x00)
#define RT_PM_DEVICE_CTRL_REQUEST (RT_DEVICE_CTRL_BASE(PM) + 0x01)
struct rt_pm;
/**
* low power mode operations
*/
struct rt_pm_ops
{
void (*sleep)(struct rt_pm *pm, rt_uint8_t mode);
void (*run)(struct rt_pm *pm, rt_uint8_t mode);
void (*timer_start)(struct rt_pm *pm, rt_uint32_t timeout);
void (*timer_stop)(struct rt_pm *pm);
rt_tick_t (*timer_get_tick)(struct rt_pm *pm);
};
struct rt_device_pm_ops
{
rt_err_t (*suspend)(const struct rt_device *device, rt_uint8_t mode);
void (*resume)(const struct rt_device *device, rt_uint8_t mode);
rt_err_t (*frequency_change)(const struct rt_device *device, rt_uint8_t mode);
};
struct rt_device_pm
{
const struct rt_device *device;
const struct rt_device_pm_ops *ops;
rt_slist_t list;
};
struct rt_pm_module
{
rt_uint8_t req_status;
rt_bool_t busy_flag;
rt_uint32_t timeout;
rt_uint32_t start_time;
};
/**
* power management
*/
struct rt_pm
{
struct rt_device parent;
/* modes */
rt_uint8_t modes[PM_SLEEP_MODE_MAX];
rt_uint8_t sleep_mode; /* current sleep mode */
rt_uint8_t run_mode; /* current running mode */
/* modules request status*/
struct rt_pm_module module_status[PM_MODULE_MAX_ID];
/* sleep request table */
rt_uint32_t sleep_status[PM_SLEEP_MODE_MAX - 1][(PM_MODULE_MAX_ID + 31) / 32];
/* the list of device, which has PM feature */
rt_slist_t device_list;
struct rt_device_pm *device_pm;
/* if the mode has timer, the corresponding bit is 1*/
rt_uint8_t timer_mask;
rt_uint8_t flags;
const struct rt_pm_ops *ops;
};
enum
{
RT_PM_ENTER_SLEEP = 0,
RT_PM_EXIT_SLEEP,
};
struct rt_pm_notify
{
void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data);
void *data;
};
rt_err_t rt_pm_request(rt_uint8_t sleep_mode);
rt_err_t rt_pm_release(rt_uint8_t sleep_mode);
rt_err_t rt_pm_release_all(rt_uint8_t sleep_mode);
rt_err_t rt_pm_run_enter(rt_uint8_t run_mode);
void rt_pm_device_register(struct rt_device *device, const struct rt_device_pm_ops *ops);
void rt_pm_device_unregister(struct rt_device *device);
void rt_pm_notify_set(void (*notify)(rt_uint8_t event, rt_uint8_t mode, void *data), void *data);
void rt_pm_default_set(rt_uint8_t sleep_mode);
void rt_system_pm_init(const struct rt_pm_ops *ops,
rt_uint8_t timer_mask,
void *user_data);
rt_err_t rt_pm_module_request(uint8_t module_id, rt_uint8_t sleep_mode);
rt_err_t rt_pm_module_release(uint8_t module_id, rt_uint8_t sleep_mode);
rt_err_t rt_pm_module_release_all(uint8_t module_id, rt_uint8_t sleep_mode);
void rt_pm_module_delay_sleep(rt_uint8_t module_id, rt_tick_t timeout);
rt_uint32_t rt_pm_module_get_status(void);
rt_uint8_t rt_pm_get_sleep_mode(void);
struct rt_pm *rt_pm_get_handle(void);
/* sleep : request or release */
rt_err_t rt_pm_sleep_request(rt_uint16_t module_id, rt_uint8_t mode);
rt_err_t rt_pm_sleep_release(rt_uint16_t module_id, rt_uint8_t mode);
rt_err_t rt_pm_sleep_none_request(rt_uint16_t module_id);
rt_err_t rt_pm_sleep_none_release(rt_uint16_t module_id);
rt_err_t rt_pm_sleep_idle_request(rt_uint16_t module_id);
rt_err_t rt_pm_sleep_idle_release(rt_uint16_t module_id);
rt_err_t rt_pm_sleep_light_request(rt_uint16_t module_id);
rt_err_t rt_pm_sleep_light_release(rt_uint16_t module_id);
#endif /* __PM_H__ */

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-08 balanceTWK the first version
*/
#ifndef __PULSE_ENCODER_H__
#define __PULSE_ENCODER_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* pulse_encoder control command */
#define PULSE_ENCODER_CMD_GET_TYPE (128 + 0) /* get a pulse_encoder type information */
#define PULSE_ENCODER_CMD_ENABLE (128 + 1) /* enable pulse_encoder */
#define PULSE_ENCODER_CMD_DISABLE (128 + 2) /* disable pulse_encoder */
#define PULSE_ENCODER_CMD_CLEAR_COUNT (128 + 3) /* clear pulse_encoder count */
/* pulse_encoder type */
enum rt_pulse_encoder_type
{
UNKNOWN_PULSE_ENCODER_TYPE = 0x00, /* Unknown pulse_encoder type */
SINGLE_PHASE_PULSE_ENCODER, /* single phase pulse_encoder */
AB_PHASE_PULSE_ENCODER /* two phase pulse_encoder */
};
struct rt_pulse_encoder_device;
struct rt_pulse_encoder_ops
{
rt_err_t (*init)(struct rt_pulse_encoder_device *pulse_encoder);
rt_int32_t (*get_count)(struct rt_pulse_encoder_device *pulse_encoder);
rt_err_t (*clear_count)(struct rt_pulse_encoder_device *pulse_encoder);
rt_err_t (*control)(struct rt_pulse_encoder_device *pulse_encoder, rt_uint32_t cmd, void *args);
};
struct rt_pulse_encoder_device
{
struct rt_device parent;
const struct rt_pulse_encoder_ops *ops;
enum rt_pulse_encoder_type type;
};
rt_err_t rt_device_pulse_encoder_register(struct rt_pulse_encoder_device *pulse_encoder, const char *name, void *user_data);
#ifdef __cplusplus
}
#endif
#endif /* __PULSE_ENCODER_H__ */

View File

@ -0,0 +1,153 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-09-23 GuEe-GUI first version
*/
#ifndef __REGULATOR_H__
#define __REGULATOR_H__
#include <ref.h>
#include <rthw.h>
#include <rtthread.h>
#include <drivers/misc.h>
#define RT_REGULATOR_UVOLT_INVALID (((int)(RT_UINT32_MAX >> 1)))
struct rt_regulator_param
{
const char *name;
int min_uvolt; /* In uV */
int max_uvolt; /* In uV */
int min_uamp; /* In uA */
int max_uamp; /* In uA */
int ramp_delay; /* In uV/usec */
int enable_delay; /* In usec */
int off_on_delay; /* In usec */
rt_uint32_t enable_active_high:1;
rt_uint32_t boot_on:1; /* Is enabled on boot */
rt_uint32_t always_on:1; /* Must be enabled */
rt_uint32_t soft_start:1; /* Ramp voltage slowly */
rt_uint32_t pull_down:1; /* Pull down resistor when regulator off */
rt_uint32_t over_current_protection:1; /* Auto disable on over current */
};
struct rt_regulator_ops;
struct rt_regulator_node
{
rt_list_t list;
rt_list_t children_nodes;
struct rt_device *dev;
struct rt_regulator_node *parent;
const char *supply_name;
const struct rt_regulator_ops *ops;
struct rt_ref ref;
rt_atomic_t enabled_count;
const struct rt_regulator_param *param;
rt_list_t notifier_nodes;
void *priv;
};
/*
* NOTE: Power regulator control is dangerous work. We don't want non-internal
* consumer could access the power regulator tree without regulator's API. So
* we defined the `rt_regulator` member in core instead of here.
*/
struct rt_regulator;
#define RT_REGULATOR_MODE_INVALID 0
#define RT_REGULATOR_MODE_FAST RT_BIT(0)
#define RT_REGULATOR_MODE_NORMAL RT_BIT(1)
#define RT_REGULATOR_MODE_IDLE RT_BIT(2)
#define RT_REGULATOR_MODE_STANDBY RT_BIT(3)
struct rt_regulator_ops
{
rt_err_t (*enable)(struct rt_regulator_node *reg);
rt_err_t (*disable)(struct rt_regulator_node *reg);
rt_bool_t (*is_enabled)(struct rt_regulator_node *reg);
rt_err_t (*set_voltage)(struct rt_regulator_node *reg, int min_uvolt, int max_uvolt);
int (*get_voltage)(struct rt_regulator_node *reg);
rt_err_t (*set_mode)(struct rt_regulator_node *reg, rt_uint32_t mode);
rt_int32_t (*get_mode)(struct rt_regulator_node *reg);
rt_err_t (*set_ramp_delay)(struct rt_regulator_node *reg, int ramp);
rt_uint32_t (*enable_time)(struct rt_regulator_node *reg);
};
struct rt_regulator_notifier;
#define RT_REGULATOR_MSG_ENABLE RT_BIT(0)
#define RT_REGULATOR_MSG_DISABLE RT_BIT(1)
#define RT_REGULATOR_MSG_VOLTAGE_CHANGE RT_BIT(2)
#define RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR RT_BIT(3)
union rt_regulator_notifier_args
{
struct
{
int old_uvolt;
int min_uvolt;
int max_uvolt;
};
};
typedef rt_err_t (*rt_regulator_notifier_callback)(struct rt_regulator_notifier *notifier,
rt_ubase_t msg, void *data);
struct rt_regulator_notifier
{
rt_list_t list;
struct rt_regulator *regulator;
rt_regulator_notifier_callback callback;
void *priv;
};
rt_err_t rt_regulator_register(struct rt_regulator_node *reg_np);
rt_err_t rt_regulator_unregister(struct rt_regulator_node *reg_np);
rt_err_t rt_regulator_notifier_register(struct rt_regulator *reg,
struct rt_regulator_notifier *notifier);
rt_err_t rt_regulator_notifier_unregister(struct rt_regulator *reg,
struct rt_regulator_notifier *notifier);
struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id);
void rt_regulator_put(struct rt_regulator *reg);
rt_err_t rt_regulator_enable(struct rt_regulator *reg);
rt_err_t rt_regulator_disable(struct rt_regulator *reg);
rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg);
rt_bool_t rt_regulator_is_supported_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt);
rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt);
int rt_regulator_get_voltage(struct rt_regulator *reg);
rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode);
rt_int32_t rt_regulator_get_mode(struct rt_regulator *reg);
rt_inline rt_err_t rt_regulator_set_voltage_triplet(struct rt_regulator *reg,
int min_uvolt, int target_uvolt, int max_uvolt)
{
if (!rt_regulator_set_voltage(reg, target_uvolt, max_uvolt))
{
return RT_EOK;
}
return rt_regulator_set_voltage(reg, min_uvolt, max_uvolt);
}
#endif /* __REGULATOR_H__ */

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#ifndef __RESET_H__
#define __RESET_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/ofw.h>
#define RT_RESET_CONTROLLER_OBJ_NAME "RSTC"
struct rt_reset_control_ops;
struct rt_reset_controller
{
struct rt_object parent;
rt_list_t rstc_nodes;
const char *name;
const struct rt_reset_control_ops *ops;
struct rt_ofw_node *ofw_node;
void *priv;
struct rt_spinlock spinlock;
};
struct rt_reset_control
{
rt_list_t list;
struct rt_reset_controller *rstcer;
int id;
const char *con_id;
rt_bool_t is_array;
void *priv;
};
struct rt_reset_control_ops
{
/*
* rt_ofw_cell_args return:
* args[0] = rstc.id
*/
rt_err_t (*ofw_parse)(struct rt_reset_control *rstc, struct rt_ofw_cell_args *args);
/* API */
rt_err_t (*reset)(struct rt_reset_control *rstc);
rt_err_t (*assert)(struct rt_reset_control *rstc);
rt_err_t (*deassert)(struct rt_reset_control *rstc);
int (*status)(struct rt_reset_control *rstc);
};
rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer);
rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer);
rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc);
rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc);
rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc);
int rt_reset_control_status(struct rt_reset_control *rstc);
rt_ssize_t rt_reset_control_get_count(struct rt_device *dev);
struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev);
struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index);
struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name);
void rt_reset_control_put(struct rt_reset_control *rstc);
struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np);
struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index);
struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name);
#endif /* __RESET_H__ */

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-10-13 flybreak the first version
*/
#ifndef __RT_DEV_BUS_H__
#define __RT_DEV_BUS_H__
#include <rtthread.h>
rt_device_t rt_device_bus_create(char *name, int attach_size);
rt_err_t rt_device_bus_destroy(rt_device_t dev);
#endif /* __RT_BUS_H__ */

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-08-13 balanceTWK first version.
*/
#ifndef __RT_INPUT_CAPTURE_H__
#define __RT_INPUT_CAPTURE_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* capture control command */
#define INPUTCAPTURE_CMD_CLEAR_BUF (128 + 0) /* clear capture buf */
#define INPUTCAPTURE_CMD_SET_WATERMARK (128 + 1) /* Set the callback threshold */
struct rt_inputcapture_data
{
rt_uint32_t pulsewidth_us;
rt_bool_t is_high;
};
struct rt_inputcapture_device
{
struct rt_device parent;
const struct rt_inputcapture_ops *ops;
struct rt_ringbuffer *ringbuff;
rt_size_t watermark;
};
/**
* capture operators
*/
struct rt_inputcapture_ops
{
rt_err_t (*init)(struct rt_inputcapture_device *inputcapture);
rt_err_t (*open)(struct rt_inputcapture_device *inputcapture);
rt_err_t (*close)(struct rt_inputcapture_device *inputcapture);
rt_err_t (*get_pulsewidth)(struct rt_inputcapture_device *inputcapture, rt_uint32_t *pulsewidth_us);
};
void rt_hw_inputcapture_isr(struct rt_inputcapture_device *inputcapture, rt_bool_t level);
rt_err_t rt_device_inputcapture_register(struct rt_inputcapture_device *inputcapture,
const char *name,
void *data);
#ifdef __cplusplus
}
#endif
#endif /* __RT_INPUT_CAPTURE_H__ */

View File

@ -0,0 +1,461 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __SCSI_H__
#define __SCSI_H__
#include <rthw.h>
#include <rtthread.h>
#include <drivers/byteorder.h>
#define RT_SCSI_LUN_SHIFT 5
rt_packed(struct rt_scsi_unknow
{
rt_uint8_t opcode;
});
rt_packed(struct rt_scsi_test_unit_ready
{
rt_uint8_t opcode;
rt_uint8_t reserved[4];
rt_uint8_t control;
rt_uint8_t pad[6]; /* To be ATAPI compatible */
});
rt_packed(struct rt_scsi_inquiry
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-2 Reserved, 1 Obsolete Formerly CMDDT, 0 EVPD */
rt_uint8_t page; /* Page code if EVPD=1 */
rt_uint8_t reserved;
rt_uint8_t alloc_length;
rt_uint8_t control;
rt_uint8_t pad[6]; /* To be ATAPI compatible */
});
rt_packed(struct rt_scsi_inquiry_data
{
#define RT_SCSI_DEVTYPE_MASK 31
rt_uint8_t devtype;
#define RT_SCSI_REMOVABLE_BIT 7
rt_uint8_t rmb;
rt_uint8_t reserved[2];
rt_uint8_t length;
rt_uint8_t reserved1[3];
char vendor[8];
char prodid[16];
char prodrev[4];
});
rt_packed(struct rt_scsi_request_sense
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-2 Reserved, 1 Obsolete, 0 SP */
rt_uint8_t reserved[2];
rt_uint8_t alloc_length;
rt_uint8_t control;
rt_uint8_t pad[6]; /* To be ATAPI compatible */
});
rt_packed(struct rt_scsi_request_sense_data
{
rt_uint8_t error_code; /* 7 Valid, 6-0 Err. code */
rt_uint8_t segment_number;
rt_uint8_t sense_key; /* 7 FileMark, 6 EndOfMedia, 5 ILI, 4-0 sense key */
rt_be32_t information;
rt_uint8_t additional_sense_length;
rt_be32_t cmd_specific_info;
rt_uint8_t additional_sense_code;
rt_uint8_t additional_sense_code_qualifier;
rt_uint8_t field_replaceable_unit_code;
rt_uint8_t sense_key_specific[3];
});
rt_packed(struct rt_scsi_read_capacity10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-1 Reserved, 0 Obsolete */
rt_be32_t logical_block_addr; /* only if PMI=1 */
rt_uint8_t reserved[2];
rt_uint8_t pmi;
rt_uint8_t control;
rt_be16_t pad; /* To be ATAPI compatible */
});
rt_packed(struct rt_scsi_read_capacity10_data
{
rt_be32_t last_block;
rt_be32_t block_size;
});
rt_packed(struct rt_scsi_read_capacity16
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 Reserved, 4-0 SERVICE ACTION 0x10 */
rt_be64_t logical_block_addr; /* only if PMI=1 */
rt_be32_t alloc_len;
rt_uint8_t pmi;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_read_capacity16_data
{
rt_be64_t last_block;
rt_be32_t block_size;
rt_uint8_t pad[20];
});
rt_packed(struct rt_scsi_read10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */
rt_be32_t lba;
rt_uint8_t reserved;
rt_be16_t size;
rt_uint8_t reserved2;
rt_be16_t pad;
});
rt_packed(struct rt_scsi_read12
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 Obsolete */
rt_be32_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_read16
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 RDPROTECT, 4 DPO, 3 FUA, 2 RARC, 1 Obsolete, 0 DLD2 */
rt_be64_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_write10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */
rt_be32_t lba;
rt_uint8_t reserved;
rt_be16_t size;
rt_uint8_t reserved2;
rt_be16_t pad;
});
rt_packed(struct rt_scsi_write12
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 Obsolete */
rt_be32_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_write16
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 WRPROTECT, 4 DPO, 3 FUA, 2 Reserved, 1 Obsolete, 0 DLD2 */
rt_be64_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_synchronize_cache10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */
rt_be32_t lba;
rt_uint8_t reserved;
rt_be16_t size;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_synchronize_cache16
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-3 Reserved, 2 Obsolete, 1 IMMED, 0 Obsolete */
rt_be64_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
#define RT_SCSI_UNMAP_SHIFT 3
rt_packed(struct rt_scsi_write_same10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 Obsolete */
rt_be32_t lba;
rt_uint8_t reserved;
rt_be16_t size;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_write_same16
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 WRPROTECT, 4 ANCHOR, 3 UNMAP, 2 Obsolete, 1 Obsolete, 0 NDOB */
rt_be64_t lba;
rt_be32_t size;
rt_uint8_t reserved;
rt_uint8_t control;
});
#define RT_SCSI_PF_SHIFT 4
#define RT_SCSI_RTD_SHIFT 1
#define RT_SCSI_SP_SHIFT 0
rt_packed(struct rt_scsi_mode_select6
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 Reserved, 4 PF, 3-2 Reserved, 1 RTD, 0 SP */
rt_uint8_t reserved[2];
rt_uint8_t param_list_len;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_mode_select10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 Reserved, 4 PF, 3-1 Reserved, 0 SP */
rt_uint8_t reserved[5];
rt_be16_t param_list_len;
rt_uint8_t control;
});
struct rt_scsi_mode_select_data
{
rt_uint32_t length;
rt_uint16_t block_descriptor_length;
rt_uint8_t medium_type;
rt_uint8_t device_specific;
rt_uint8_t header_length;
rt_uint8_t longlba:1;
};
#define RT_SCSI_DBD_SHIFT 3
#define RT_SCSI_LLBAA_SHIFT 4
#define RT_SCSI_PC_SHIFT 6
#define RT_SCSI_PAGE_CODE_SHIFT 0
rt_packed(struct rt_scsi_mode_sense6
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-4 Reserved, 3 DBD, 2-0 Reserved */
rt_uint8_t page_control_code;
rt_uint8_t subpage_code;
rt_uint8_t allocation_len;
rt_uint8_t control;
});
rt_packed(struct rt_scsi_mode_sense10
{
rt_uint8_t opcode;
rt_uint8_t config; /* 7-5 Reserved, 4 LLBAA, 3 DBD, 2-0 Reserved */
rt_uint8_t page_control_code;
rt_uint8_t subpage_code;
rt_uint8_t reserved[3];
rt_be16_t allocation_len;
rt_uint8_t control;
});
#define RT_SCSI_CMD_TEST_UNIT_READY 0x00
#define RT_SCSI_CMD_REQUEST_SENSE 0x03
#define RT_SCSI_CMD_INQUIRY 0x12
#define RT_SCSI_CMD_MODE_SELECT 0x15
#define RT_SCSI_CMD_MODE_SENSE 0x1a
#define RT_SCSI_CMD_READ_CAPACITY10 0x25
#define RT_SCSI_CMD_READ10 0x28
#define RT_SCSI_CMD_WRITE10 0x2a
#define RT_SCSI_CMD_SYNCHRONIZE_CACHE10 0x35
#define RT_SCSI_CMD_WRITE_SAME10 0x41
#define RT_SCSI_CMD_MODE_SELECT10 0x55
#define RT_SCSI_CMD_MODE_SENSE10 0x5a
#define RT_SCSI_CMD_READ16 0x88
#define RT_SCSI_CMD_WRITE16 0x8a
#define RT_SCSI_CMD_SYNCHRONIZE_CACHE16 0x91
#define RT_SCSI_CMD_WRITE_SAME16 0x93
#define RT_SCSI_CMD_READ_CAPACITY16 0x9e
#define RT_SCSI_CMD_READ12 0xa8
#define RT_SCSI_CMD_WRITE12 0xaa
struct rt_scsi_cmd
{
union
{
struct rt_scsi_unknow unknow;
struct rt_scsi_test_unit_ready test_unit_ready;
struct rt_scsi_inquiry inquiry;
struct rt_scsi_request_sense request_sense;
struct rt_scsi_read_capacity10 read_capacity10;
struct rt_scsi_read_capacity16 read_capacity16;
struct rt_scsi_read10 read10;
struct rt_scsi_read12 read12;
struct rt_scsi_read16 read16;
struct rt_scsi_write10 write10;
struct rt_scsi_write12 write12;
struct rt_scsi_write16 write16;
struct rt_scsi_synchronize_cache10 synchronize_cache10;
struct rt_scsi_synchronize_cache16 synchronize_cache16;
struct rt_scsi_write_same10 write_same10;
struct rt_scsi_write_same16 write_same16;
struct rt_scsi_mode_select6 mode_select6;
struct rt_scsi_mode_select10 mode_select10;
struct rt_scsi_mode_sense6 mode_sense6;
struct rt_scsi_mode_sense10 mode_sense10;
} op;
rt_size_t op_size;
union
{
struct
{
struct rt_scsi_inquiry_data inquiry;
struct rt_scsi_request_sense_data request_sense;
struct rt_scsi_read_capacity10_data read_capacity10;
struct rt_scsi_read_capacity16_data read_capacity16;
};
struct
{
void *ptr;
rt_size_t size;
};
} data;
};
enum
{
SCSI_DEVICE_TYPE_DIRECT = 0x00, /* DiskPeripheral (GenDisk) */
SCSI_DEVICE_TYPE_SEQUENTIAL = 0x01, /* TapePeripheral */
SCSI_DEVICE_TYPE_PRINTER = 0x02, /* PrinterPeripheral (GenPrinter) */
SCSI_DEVICE_TYPE_PROCESSOR = 0x03, /* OtherPeripheral */
SCSI_DEVICE_TYPE_WRITE_ONCE_READ_MULTIPLE = 0x04, /* WormPeripheral (GenWorm) */
SCSI_DEVICE_TYPE_CDROM = 0x05, /* CdRomPeripheral (GenCdRom) */
SCSI_DEVICE_TYPE_SCANNER = 0x06, /* ScannerPeripheral (GenScanner) */
SCSI_DEVICE_TYPE_OPTICAL = 0x07, /* OpticalDiskPeripheral (GenOptical) */
SCSI_DEVICE_TYPE_MEDIUM_CHANGER = 0x08, /* MediumChangerPeripheral (ScsiChanger) */
SCSI_DEVICE_TYPE_COMMUNICATION = 0x09, /* CommunicationsPeripheral (ScsiNet) */
SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS10 = 0x0a, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */
SCSI_DEVICE_TYPE_ASC_PREPRESS_GRAPHICS11 = 0x0b, /* ASCPrePressGraphicsPeripheral (ScsiASCIT8) */
SCSI_DEVICE_TYPE_ARRAY = 0x0c, /* ArrayPeripheral (ScsiArray) */
SCSI_DEVICE_TYPE_ENCLOSURE = 0x0d, /* EnclosurePeripheral (ScsiEnclosure) */
SCSI_DEVICE_TYPE_RBC = 0x0e, /* RBCPeripheral (ScsiRBC) */
SCSI_DEVICE_TYPE_CARDREADER = 0x0f, /* CardReaderPeripheral (ScsiCardReader) */
SCSI_DEVICE_TYPE_BRIDGE = 0x10, /* BridgePeripheral (ScsiBridge) */
SCSI_DEVICE_TYPE_OTHER = 0x11, /* OtherPeripheral (ScsiOther) */
SCSI_DEVICE_TYPE_MAX,
};
struct rt_scsi_ops;
struct rt_scsi_host
{
struct rt_device *dev;
const struct rt_scsi_ops *ops;
rt_size_t max_id;
rt_size_t max_lun;
rt_list_t lun_nodes;
};
struct rt_scsi_device
{
struct rt_scsi_host *host;
rt_list_t list;
rt_size_t id;
rt_size_t lun;
rt_uint32_t devtype;
rt_uint32_t removable;
rt_size_t last_block;
rt_size_t block_size;
void *priv;
};
struct rt_scsi_ops
{
rt_err_t (*reset)(struct rt_scsi_device *sdev);
rt_err_t (*transfer)(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd);
};
rt_err_t rt_scsi_host_register(struct rt_scsi_host *scsi);
rt_err_t rt_scsi_host_unregister(struct rt_scsi_host *scsi);
rt_inline rt_bool_t rt_scsi_cmd_is_write(struct rt_scsi_cmd *cmd)
{
return cmd->op.write10.opcode == RT_SCSI_CMD_WRITE10 ||
cmd->op.write12.opcode == RT_SCSI_CMD_WRITE16 ||
cmd->op.write16.opcode == RT_SCSI_CMD_WRITE12;
}
rt_err_t rt_scsi_request_sense(struct rt_scsi_device *sdev,
struct rt_scsi_request_sense_data *out_data);
rt_err_t rt_scsi_test_unit_ready(struct rt_scsi_device *sdev);
rt_err_t rt_scsi_inquiry(struct rt_scsi_device *sdev,
struct rt_scsi_inquiry_data *out_data);
rt_err_t rt_scsi_read_capacity10(struct rt_scsi_device *sdev,
struct rt_scsi_read_capacity10_data *out_data);
rt_err_t rt_scsi_read_capacity16(struct rt_scsi_device *sdev,
struct rt_scsi_read_capacity16_data *out_data);
rt_err_t rt_scsi_read10(struct rt_scsi_device *sdev,
rt_off_t lba, void *buffer, rt_size_t size);
rt_err_t rt_scsi_read12(struct rt_scsi_device *sdev,
rt_off_t lba, void *buffer, rt_size_t size);
rt_err_t rt_scsi_read16(struct rt_scsi_device *sdev,
rt_off_t lba, void *buffer, rt_size_t size);
rt_err_t rt_scsi_write10(struct rt_scsi_device *sdev,
rt_off_t lba, const void *buffer, rt_size_t size);
rt_err_t rt_scsi_write12(struct rt_scsi_device *sdev,
rt_off_t lba, const void *buffer, rt_size_t size);
rt_err_t rt_scsi_write16(struct rt_scsi_device *sdev,
rt_off_t lba, const void *buffer, rt_size_t size);
rt_err_t rt_scsi_synchronize_cache10(struct rt_scsi_device *sdev,
rt_off_t lba, rt_size_t size);
rt_err_t rt_scsi_synchronize_cache16(struct rt_scsi_device *sdev,
rt_off_t lba, rt_size_t size);
rt_err_t rt_scsi_write_same10(struct rt_scsi_device *sdev,
rt_off_t lba, rt_size_t size);
rt_err_t rt_scsi_write_same16(struct rt_scsi_device *sdev,
rt_off_t lba, rt_size_t size);
rt_err_t rt_scsi_mode_select6(struct rt_scsi_device *sdev,
rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size,
struct rt_scsi_mode_select_data *data);
rt_err_t rt_scsi_mode_select10(struct rt_scsi_device *sdev,
rt_uint8_t pf, rt_uint8_t sp, void *buffer, rt_size_t size,
struct rt_scsi_mode_select_data *data);
rt_err_t rt_scsi_mode_sense6(struct rt_scsi_device *sdev,
rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size,
struct rt_scsi_mode_select_data *data);
rt_err_t rt_scsi_mode_sense10(struct rt_scsi_device *sdev,
rt_uint8_t dbd, rt_uint8_t modepage, rt_uint8_t subpage, void *buffer, rt_size_t size,
struct rt_scsi_mode_select_data *data);
#endif /* __SCSI_H__ */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-02-26 weety first version
*/
#ifndef __SDIO_FUNC_IDS_H__
#define __SDIO_FUNC_IDS_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Standard SDIO Function Interfaces */
#define SDIO_FUNC_CODE_NONE 0x00 /* Not a SDIO standard interface */
#define SDIO_FUNC_CODE_UART 0x01 /* SDIO Standard UART */
#define SDIO_FUNC_CODE_BT_A 0x02 /* SDIO Type-A for Bluetooth standard interface */
#define SDIO_FUNC_CODE_BT_B 0x03 /* SDIO Type-B for Bluetooth standard interface */
#define SDIO_FUNC_CODE_GPS 0x04 /* SDIO GPS standard interface */
#define SDIO_FUNC_CODE_CAMERA 0x05 /* SDIO Camera standard interface */
#define SDIO_FUNC_CODE_PHS 0x06 /* SDIO PHS standard interface */
#define SDIO_FUNC_CODE_WLAN 0x07 /* SDIO WLAN interface */
#define SDIO_FUNC_CODE_ATA 0x08 /* Embedded SDIO-ATA standard interface */
/* manufacturer id, product io */
#define SDIO_MANUFACTURER_ID_MARVELL 0x02df
#define SDIO_PRODUCT_ID_MARVELL_88W8686 0x9103
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,263 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-01-31 flybreak first version
*/
#ifndef __SENSOR_H__
#define __SENSOR_H__
#include <rtthread.h>
#include "dev_pin.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_RTC
#define rt_sensor_get_ts() time(RT_NULL) /* API for the sensor to get the timestamp */
#else
#define rt_sensor_get_ts() rt_tick_get() /* API for the sensor to get the timestamp */
#endif
#define RT_PIN_NONE 0xFFFF /* RT PIN NONE */
#define RT_DEVICE_FLAG_FIFO_RX 0x200 /* Flag to use when the sensor is open by fifo mode */
#define RT_SENSOR_MODULE_MAX (3) /* The maximum number of members of a sensor module */
/* Sensor types */
#define RT_SENSOR_CLASS_NONE (0)
#define RT_SENSOR_CLASS_ACCE (1) /* Accelerometer */
#define RT_SENSOR_CLASS_GYRO (2) /* Gyroscope */
#define RT_SENSOR_CLASS_MAG (3) /* Magnetometer */
#define RT_SENSOR_CLASS_TEMP (4) /* Temperature */
#define RT_SENSOR_CLASS_HUMI (5) /* Relative Humidity */
#define RT_SENSOR_CLASS_BARO (6) /* Barometer */
#define RT_SENSOR_CLASS_LIGHT (7) /* Ambient light */
#define RT_SENSOR_CLASS_PROXIMITY (8) /* Proximity */
#define RT_SENSOR_CLASS_HR (9) /* Heart Rate */
#define RT_SENSOR_CLASS_TVOC (10) /* TVOC Level */
#define RT_SENSOR_CLASS_NOISE (11) /* Noise Loudness */
#define RT_SENSOR_CLASS_STEP (12) /* Step sensor */
#define RT_SENSOR_CLASS_FORCE (13) /* Force sensor */
#define RT_SENSOR_CLASS_DUST (14) /* Dust sensor */
#define RT_SENSOR_CLASS_ECO2 (15) /* eCO2 sensor */
#define RT_SENSOR_CLASS_GNSS (16) /* GPS/GNSS sensor */
#define RT_SENSOR_CLASS_TOF (17) /* TOF sensor */
#define RT_SENSOR_CLASS_SPO2 (18) /* SpO2 sensor */
#define RT_SENSOR_CLASS_IAQ (19) /* IAQ sensor. */
#define RT_SENSOR_CLASS_ETOH (20) /* EtOH sensor. */
#define RT_SENSOR_CLASS_BP (21) /* Blood Pressure */
#define RT_SENSOR_CLASS_VOLTAGE (22) /* Voltage sensor */
#define RT_SENSOR_CLASS_CURRENT (23) /* Current sensor */
#define RT_SENSOR_CLASS_POWER (24) /* Power sensor */
/* Sensor vendor types */
#define RT_SENSOR_VENDOR_UNKNOWN (0)
#define RT_SENSOR_VENDOR_STM (1) /* STMicroelectronics */
#define RT_SENSOR_VENDOR_BOSCH (2) /* Bosch */
#define RT_SENSOR_VENDOR_INVENSENSE (3) /* Invensense */
#define RT_SENSOR_VENDOR_SEMTECH (4) /* Semtech */
#define RT_SENSOR_VENDOR_GOERTEK (5) /* Goertek */
#define RT_SENSOR_VENDOR_MIRAMEMS (6) /* MiraMEMS */
#define RT_SENSOR_VENDOR_DALLAS (7) /* Dallas */
#define RT_SENSOR_VENDOR_ASAIR (8) /* Aosong */
#define RT_SENSOR_VENDOR_SHARP (9) /* Sharp */
#define RT_SENSOR_VENDOR_SENSIRION (10) /* Sensirion */
#define RT_SENSOR_VENDOR_TI (11) /* Texas Instruments */
#define RT_SENSOR_VENDOR_PLANTOWER (12) /* Plantower */
#define RT_SENSOR_VENDOR_AMS (13) /* ams AG */
#define RT_SENSOR_VENDOR_MAXIM (14) /* Maxim Integrated */
#define RT_SENSOR_VENDOR_MELEXIS (15) /* Melexis */
/* Sensor unit types */
#define RT_SENSOR_UNIT_NONE (0)
#define RT_SENSOR_UNIT_MG (1) /* Accelerometer unit: mG */
#define RT_SENSOR_UNIT_MDPS (2) /* Gyroscope unit: mdps */
#define RT_SENSOR_UNIT_MGAUSS (3) /* Magnetometer unit: mGauss */
#define RT_SENSOR_UNIT_LUX (4) /* Ambient light unit: lux */
#define RT_SENSOR_UNIT_CM (5) /* Distance unit: cm */
#define RT_SENSOR_UNIT_PA (6) /* Barometer unit: pa */
#define RT_SENSOR_UNIT_PERMILLAGE (7) /* Relative Humidity unit: permillage */
#define RT_SENSOR_UNIT_DCELSIUS (8) /* Temperature unit: dCelsius */
#define RT_SENSOR_UNIT_HZ (9) /* Frequency unit: HZ */
#define RT_SENSOR_UNIT_ONE (10) /* Dimensionless quantity unit: 1 */
#define RT_SENSOR_UNIT_BPM (11) /* Heart rate unit: bpm */
#define RT_SENSOR_UNIT_MM (12) /* Distance unit: mm */
#define RT_SENSOR_UNIT_MN (13) /* Force unit: mN */
#define RT_SENSOR_UNIT_PPM (14) /* Concentration unit: ppm */
#define RT_SENSOR_UNIT_PPB (15) /* Concentration unit: ppb */
#define RT_SENSOR_UNIT_DMS (16) /* Coordinates unit: DMS */
#define RT_SENSOR_UNIT_DD (17) /* Coordinates unit: DD */
#define RT_SENSOR_UNIT_MGM3 (18) /* Concentration unit: mg/m3 */
#define RT_SENSOR_UNIT_MMHG (19) /* Blood Pressure unit: mmHg */
#define RT_SENSOR_UNIT_MV (20) /* Voltage unit: mV */
#define RT_SENSOR_UNIT_MA (21) /* Current unit: mA */
#define RT_SENSOR_UNIT_MW (22) /* Power unit: mW */
/* Sensor communication interface types */
#define RT_SENSOR_INTF_I2C (1 << 0)
#define RT_SENSOR_INTF_SPI (1 << 1)
#define RT_SENSOR_INTF_UART (1 << 2)
#define RT_SENSOR_INTF_ONEWIRE (1 << 3)
/* Sensor power mode types */
#define RT_SENSOR_POWER_NONE (0)
#define RT_SENSOR_POWER_DOWN (1) /* power down mode */
#define RT_SENSOR_POWER_NORMAL (2) /* normal-power mode */
#define RT_SENSOR_POWER_LOW (3) /* low-power mode */
#define RT_SENSOR_POWER_HIGH (4) /* high-power mode */
/* Sensor work mode types */
#define RT_SENSOR_MODE_NONE (0)
#define RT_SENSOR_MODE_POLLING (1) /* One shot only read a data */
#define RT_SENSOR_MODE_INT (2) /* TODO: One shot interrupt only read a data */
#define RT_SENSOR_MODE_FIFO (3) /* TODO: One shot interrupt read all fifo data */
/* Sensor control cmd types */
#define RT_SENSOR_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Sensor) + 0) /* Get device id */
#define RT_SENSOR_CTRL_GET_INFO (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Get sensor info */
#define RT_SENSOR_CTRL_SET_RANGE (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* Set the measure range of sensor. unit is info of sensor */
#define RT_SENSOR_CTRL_SET_ODR (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* Set output date rate. unit is HZ */
#define RT_SENSOR_CTRL_SET_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* Set sensor's work mode. ex. RT_SENSOR_MODE_POLLING,RT_SENSOR_MODE_INT */
#define RT_SENSOR_CTRL_SET_POWER (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* Set power mode. args type of sensor power mode. ex. RT_SENSOR_POWER_DOWN,RT_SENSOR_POWER_NORMAL */
#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 6) /* Take a self test */
#define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */
struct rt_sensor_info
{
rt_uint8_t type; /* The sensor type */
rt_uint8_t vendor; /* Vendor of sensors */
const char *model; /* model name of sensor */
rt_uint8_t unit; /* unit of measurement */
rt_uint8_t intf_type; /* Communication interface type */
rt_int32_t range_max; /* maximum range of this sensor's value. unit is 'unit' */
rt_int32_t range_min; /* minimum range of this sensor's value. unit is 'unit' */
rt_uint32_t period_min; /* Minimum measurement period,unit:ms. zero = not a constant rate */
rt_uint8_t fifo_max;
};
struct rt_sensor_intf
{
char *dev_name; /* The name of the communication device */
rt_uint8_t type; /* Communication interface type */
void *user_data; /* Private data for the sensor. ex. i2c addr,spi cs,control I/O */
};
struct rt_sensor_config
{
struct rt_sensor_intf intf; /* sensor interface config */
struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
rt_uint8_t mode; /* sensor work mode */
rt_uint8_t power; /* sensor power mode */
rt_uint16_t odr; /* sensor out data rate */
rt_int32_t range; /* sensor range of measurement */
};
typedef struct rt_sensor_device *rt_sensor_t;
struct rt_sensor_device
{
struct rt_device parent; /* The standard device */
struct rt_sensor_info info; /* The sensor info data */
struct rt_sensor_config config; /* The sensor config data */
void *data_buf; /* The buf of the data received */
rt_size_t data_len; /* The size of the data received */
const struct rt_sensor_ops *ops; /* The sensor ops */
struct rt_sensor_module *module; /* The sensor module */
rt_err_t (*irq_handle)(rt_sensor_t sensor); /* Called when an interrupt is generated, registered by the driver */
};
struct rt_sensor_module
{
rt_mutex_t lock; /* The module lock */
rt_sensor_t sen[RT_SENSOR_MODULE_MAX]; /* The module contains a list of sensors */
rt_uint8_t sen_num; /* Number of sensors contained in the module */
};
/* 3-axis Data Type */
struct sensor_3_axis
{
rt_int32_t x;
rt_int32_t y;
rt_int32_t z;
};
/* Blood Pressure Data Type */
struct sensor_bp
{
rt_int32_t sbp; /* SBP : systolic pressure */
rt_int32_t dbp; /* DBP : diastolic pressure */
};
struct coordinates
{
double longitude;
double latitude;
};
struct rt_sensor_data
{
rt_uint32_t timestamp; /* The timestamp when the data was received */
rt_uint8_t type; /* The sensor type of the data */
union
{
struct sensor_3_axis acce; /* Accelerometer. unit: mG */
struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */
struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */
struct coordinates coord; /* Coordinates unit: degrees */
rt_int32_t temp; /* Temperature. unit: dCelsius */
rt_int32_t humi; /* Relative humidity. unit: permillage */
rt_int32_t baro; /* Pressure. unit: pascal (Pa) */
rt_int32_t light; /* Light. unit: lux */
rt_int32_t proximity; /* Distance. unit: centimeters */
rt_int32_t hr; /* Heart rate. unit: bpm */
rt_int32_t tvoc; /* TVOC. unit: permillage */
rt_int32_t noise; /* Noise Loudness. unit: HZ */
rt_uint32_t step; /* Step sensor. unit: 1 */
rt_int32_t force; /* Force sensor. unit: mN */
rt_uint32_t dust; /* Dust sensor. unit: ug/m3 */
rt_uint32_t eco2; /* eCO2 sensor. unit: ppm */
rt_uint32_t spo2; /* SpO2 sensor. unit: permillage */
rt_uint32_t iaq; /* IAQ sensor. unit: 1 */
rt_uint32_t etoh; /* EtOH sensor. unit: ppm */
struct sensor_bp bp; /* BloodPressure. unit: mmHg */
float mv; /* Voltage sensor. unit: mv */
float ma; /* Current sensor. unit: ma */
float mw; /* Power sensor. unit: mw */
} data;
};
struct rt_sensor_ops
{
rt_ssize_t (*fetch_data)(struct rt_sensor_device *sensor, void *buf, rt_size_t len);
rt_err_t (*control)(struct rt_sensor_device *sensor, int cmd, void *arg);
};
int rt_hw_sensor_register(rt_sensor_t sensor,
const char *name,
rt_uint32_t flag,
void *data);
#ifdef __cplusplus
}
#endif
#endif /* __SENSOR_H__ */

View File

@ -0,0 +1,407 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-01-31 flybreak first version
* 2022-12-17 Meco Man re-implement sensor framework
*/
#ifndef __SENSOR_H__
#define __SENSOR_H__
#include <rtthread.h>
#include "dev_pin.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef RT_USING_RTC
#define rt_sensor_get_ts() time(RT_NULL) /* API for the sensor to get the timestamp */
#else
#define rt_sensor_get_ts() rt_tick_get() /* API for the sensor to get the timestamp */
#endif
#define RT_DEVICE_FLAG_FIFO_RX 0x200 /* Flag to use when the sensor is open by fifo mode */
#define RT_SENSOR_MODULE_MAX (3) /* The maximum number of members of a sensor module */
#define RT_SENSOR_MACRO_GET_NAME(macro) (macro##_STR)
/* Sensor types */
#define RT_SENSOR_TYPE_NONE (0)
#define RT_SENSOR_TYPE_NONE_STR "None"
#define RT_SENSOR_TYPE_ACCE (1)
#define RT_SENSOR_TYPE_ACCE_STR "Accelerometer"
#define RT_SENSOR_TYPE_GYRO (2)
#define RT_SENSOR_TYPE_GYRO_STR "Gyroscope"
#define RT_SENSOR_TYPE_MAG (3)
#define RT_SENSOR_TYPE_MAG_STR "Magnetometer"
#define RT_SENSOR_TYPE_TEMP (4)
#define RT_SENSOR_TYPE_TEMP_STR "Temperature"
#define RT_SENSOR_TYPE_HUMI (5)
#define RT_SENSOR_TYPE_HUMI_STR "Relative Humidity"
#define RT_SENSOR_TYPE_BARO (6)
#define RT_SENSOR_TYPE_BARO_STR "Barometer"
#define RT_SENSOR_TYPE_LIGHT (7)
#define RT_SENSOR_TYPE_LIGHT_STR "Ambient Light"
#define RT_SENSOR_TYPE_PROXIMITY (8)
#define RT_SENSOR_TYPE_PROXIMITY_STR "Proximity"
#define RT_SENSOR_TYPE_HR (9)
#define RT_SENSOR_TYPE_HR_STR "Heart Rate"
#define RT_SENSOR_TYPE_TVOC (10)
#define RT_SENSOR_TYPE_TVOC_STR "TVOC Level"
#define RT_SENSOR_TYPE_NOISE (11)
#define RT_SENSOR_TYPE_NOISE_STR "Noise Loudness"
#define RT_SENSOR_TYPE_STEP (12)
#define RT_SENSOR_TYPE_STEP_STR "Step"
#define RT_SENSOR_TYPE_FORCE (13)
#define RT_SENSOR_TYPE_FORCE_STR "Force"
#define RT_SENSOR_TYPE_DUST (14)
#define RT_SENSOR_TYPE_DUST_STR "Dust"
#define RT_SENSOR_TYPE_ECO2 (15)
#define RT_SENSOR_TYPE_ECO2_STR "eCO2"
#define RT_SENSOR_TYPE_GNSS (16)
#define RT_SENSOR_TYPE_GNSS_STR "GNSS"
#define RT_SENSOR_TYPE_TOF (17)
#define RT_SENSOR_TYPE_TOF_STR "ToF"
#define RT_SENSOR_TYPE_SPO2 (18)
#define RT_SENSOR_TYPE_SPO2_STR "SpO2"
#define RT_SENSOR_TYPE_IAQ (19)
#define RT_SENSOR_TYPE_IAQ_STR "IAQ"
#define RT_SENSOR_TYPE_ETOH (20)
#define RT_SENSOR_TYPE_ETOH_STR "EtOH"
#define RT_SENSOR_TYPE_BP (21)
#define RT_SENSOR_TYPE_BP_STR "Blood Pressure"
#define RT_SENSOR_TYPE_VOLTAGE (22)
#define RT_SENSOR_TYPE_VOLTAGE_STR "Voltage"
#define RT_SENSOR_TYPE_CURRENT (23)
#define RT_SENSOR_TYPE_CURRENT_STR "Current"
/* Sensor vendor types */
#define RT_SENSOR_VENDOR_UNKNOWN (0)
#define RT_SENSOR_VENDOR_UNKNOWN_STR "Unknown"
#define RT_SENSOR_VENDOR_VIRTUAL (1)
#define RT_SENSOR_VENDOR_VIRTUAL_STR "Virtual Sensor"
#define RT_SENSOR_VENDOR_ONCHIP (2)
#define RT_SENSOR_VENDOR_ONCHIP_STR "OnChip"
#define RT_SENSOR_VENDOR_STM (3)
#define RT_SENSOR_VENDOR_STM_STR "STMicroelectronics"
#define RT_SENSOR_VENDOR_BOSCH (4)
#define RT_SENSOR_VENDOR_BOSCH_STR "Bosch"
#define RT_SENSOR_VENDOR_INVENSENSE (5)
#define RT_SENSOR_VENDOR_INVENSENSE_STR "Invensense"
#define RT_SENSOR_VENDOR_SEMTECH (6)
#define RT_SENSOR_VENDOR_SEMTECH_STR "Semtech"
#define RT_SENSOR_VENDOR_GOERTEK (7)
#define RT_SENSOR_VENDOR_GOERTEK_STR "Goertek"
#define RT_SENSOR_VENDOR_MIRAMEMS (8)
#define RT_SENSOR_VENDOR_MIRAMEMS_STR "MiraMEMS"
#define RT_SENSOR_VENDOR_DALLAS (9)
#define RT_SENSOR_VENDOR_DALLAS_STR "Dallas"
#define RT_SENSOR_VENDOR_ASAIR (10)
#define RT_SENSOR_VENDOR_ASAIR_STR "Aosong"
#define RT_SENSOR_VENDOR_SHARP (11)
#define RT_SENSOR_VENDOR_SHARP_STR "Sharp"
#define RT_SENSOR_VENDOR_SENSIRION (12)
#define RT_SENSOR_VENDOR_SENSIRION_STR "Sensirion"
#define RT_SENSOR_VENDOR_TI (13)
#define RT_SENSOR_VENDOR_TI_STR "Texas Instruments"
#define RT_SENSOR_VENDOR_PLANTOWER (14)
#define RT_SENSOR_VENDOR_PLANTOWER_STR "Plantower"
#define RT_SENSOR_VENDOR_AMS (15)
#define RT_SENSOR_VENDOR_AMS_STR "ams-OSRAM AG"
#define RT_SENSOR_VENDOR_MAXIM (16)
#define RT_SENSOR_VENDOR_MAXIM_STR "Maxim Integrated"
#define RT_SENSOR_VENDOR_MELEXIS (17)
#define RT_SENSOR_VENDOR_MELEXIS_STR "Melexis"
#define RT_SENSOR_VENDOR_LSC (18)
#define RT_SENSOR_VENDOR_LSC_STR "Lite On"
/* Sensor unit types */
#define RT_SENSOR_UNIT_NONE (0) /* Dimensionless quantity */
#define RT_SENSOR_UNIT_NONE_STR ""
#define RT_SENSOR_UNIT_MG (1) /* Accelerometer unit: mG */
#define RT_SENSOR_UNIT_MG_STR "mG"
#define RT_SENSOR_UNIT_MDPS (2) /* Gyroscope unit: mdps */
#define RT_SENSOR_UNIT_MDPS_STR "mdps"
#define RT_SENSOR_UNIT_MGAUSS (3) /* Magnetometer unit: mGauss */
#define RT_SENSOR_UNIT_MGAUSS_STR "mGauss"
#define RT_SENSOR_UNIT_LUX (4) /* Ambient light unit: lux */
#define RT_SENSOR_UNIT_LUX_STR "lux"
#define RT_SENSOR_UNIT_M (5) /* Distance unit: m */
#define RT_SENSOR_UNIT_M_STR "m"
#define RT_SENSOR_UNIT_CM (6) /* Distance unit: cm */
#define RT_SENSOR_UNIT_CM_STR "cm"
#define RT_SENSOR_UNIT_MM (7) /* Distance unit: mm */
#define RT_SENSOR_UNIT_MM_STR "mm"
#define RT_SENSOR_UNIT_PA (8) /* Barometer unit: Pa */
#define RT_SENSOR_UNIT_PA_STR "Pa"
#define RT_SENSOR_UNIT_MMHG (9) /* Blood Pressure unit: mmHg */
#define RT_SENSOR_UNIT_MMHG_STR "mmHg"
#define RT_SENSOR_UNIT_PERCENTAGE (10) /* Relative Humidity unit: percentage */
#define RT_SENSOR_UNIT_PERCENTAGE_STR "%"
#define RT_SENSOR_UNIT_PERMILLAGE (11) /* Relative Humidity unit: permillage */
#define RT_SENSOR_UNIT_PERMILLAGE_STR "‰"
#define RT_SENSOR_UNIT_CELSIUS (12) /* Temperature unit: Celsius ℃ */
#define RT_SENSOR_UNIT_CELSIUS_STR "℃"
#define RT_SENSOR_UNIT_FAHRENHEIT (13) /* Temperature unit: Fahrenheit ℉ */
#define RT_SENSOR_UNIT_FAHRENHEIT_STR "℉"
#define RT_SENSOR_UNIT_KELVIN (14) /* Temperature unit: Kelvin K */
#define RT_SENSOR_UNIT_KELVIN_STR "K"
#define RT_SENSOR_UNIT_HZ (15) /* Frequency unit: Hz */
#define RT_SENSOR_UNIT_HZ_STR "Hz"
#define RT_SENSOR_UNIT_V (16) /* Voltage unit: V */
#define RT_SENSOR_UNIT_V_STR "V"
#define RT_SENSOR_UNIT_MV (17) /* Voltage unit: mV */
#define RT_SENSOR_UNIT_MV_STR "mV"
#define RT_SENSOR_UNIT_A (18) /* Current unit: A */
#define RT_SENSOR_UNIT_A_STR "A"
#define RT_SENSOR_UNIT_MA (19) /* Current unit: mA */
#define RT_SENSOR_UNIT_MA_STR "mA"
#define RT_SENSOR_UNIT_N (20) /* Force unit: N */
#define RT_SENSOR_UNIT_N_STR "N"
#define RT_SENSOR_UNIT_MN (21) /* Force unit: mN */
#define RT_SENSOR_UNIT_MN_STR "mN"
#define RT_SENSOR_UNIT_BPM (22) /* Heart rate unit: bpm */
#define RT_SENSOR_UNIT_BPM_STR "bpm"
#define RT_SENSOR_UNIT_PPM (23) /* Concentration unit: ppm */
#define RT_SENSOR_UNIT_PPM_STR "ppm"
#define RT_SENSOR_UNIT_PPB (24) /* Concentration unit: ppb */
#define RT_SENSOR_UNIT_PPB_STR "ppb"
#define RT_SENSOR_UNIT_DMS (25) /* Coordinates unit: DMS */
#define RT_SENSOR_UNIT_DMS_STR "DMS"
#define RT_SENSOR_UNIT_DD (26) /* Coordinates unit: DD */
#define RT_SENSOR_UNIT_DD_STR "DD"
#define RT_SENSOR_UNIT_MGM3 (27) /* Concentration unit: mg/m3 */
#define RT_SENSOR_UNIT_MGM3_STR "mg/m3"
/* Sensor communication interface types */
#define RT_SENSOR_INTF_I2C (1 << 0)
#define RT_SENSOR_INTF_I2C_STR "I2C"
#define RT_SENSOR_INTF_SPI (1 << 1)
#define RT_SENSOR_INTF_SPI_STR "SPI"
#define RT_SENSOR_INTF_UART (1 << 2)
#define RT_SENSOR_INTF_UART_STR "UART"
#define RT_SENSOR_INTF_ONEWIRE (1 << 3)
#define RT_SENSOR_INTF_ONEWIRE_STR "1-Wire"
#define RT_SENSOR_INTF_CAN (1 << 4)
#define RT_SENSOR_INTF_CAN_STR "CAN"
#define RT_SENSOR_INTF_MODBUS (1 << 5)
#define RT_SENSOR_INTF_MODBUS_STR "Modbus"
/**
* Sensor mode
* rt_uint16_t mode
* 0000 | 0000 | 0000 | 0000
* unused accuracy power fetch data
*/
#define RT_SENSOR_MODE_ACCURACY_BIT_OFFSET (8)
#define RT_SENSOR_MODE_POWER_BIT_OFFSET (4)
#define RT_SENSOR_MODE_FETCH_BIT_OFFSET (0)
#define RT_SENSOR_MODE_GET_ACCURACY(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_ACCURACY_BIT_OFFSET) & 0x0F)
#define RT_SENSOR_MODE_GET_POWER(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_POWER_BIT_OFFSET) & 0x0F)
#define RT_SENSOR_MODE_GET_FETCH(mode) (rt_uint8_t)((mode >> RT_SENSOR_MODE_FETCH_BIT_OFFSET) & 0x0F)
#define RT_SENSOR_MODE_CLEAR_ACCURACY(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET)))
#define RT_SENSOR_MODE_CLEAR_POWER(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_POWER_BIT_OFFSET)))
#define RT_SENSOR_MODE_CLEAR_FETCH(mode) (mode &= ((rt_uint16_t)~((rt_uint16_t)0x0F << RT_SENSOR_MODE_FETCH_BIT_OFFSET)))
#define RT_SENSOR_MODE_SET_ACCURACY(mode, accuracy_mode) RT_SENSOR_MODE_CLEAR_ACCURACY(mode); (mode |= (accuracy_mode << RT_SENSOR_MODE_ACCURACY_BIT_OFFSET))
#define RT_SENSOR_MODE_SET_POWER(mode, power_mode) RT_SENSOR_MODE_CLEAR_POWER(mode); (mode |= (power_mode << RT_SENSOR_MODE_POWER_BIT_OFFSET))
#define RT_SENSOR_MODE_SET_FETCH(mode, fetch_mode) RT_SENSOR_MODE_CLEAR_FETCH(mode); (mode |= (fetch_mode << RT_SENSOR_MODE_FETCH_BIT_OFFSET))
/* Sensor mode: accuracy */
#define RT_SENSOR_MODE_ACCURACY_HIGHEST (0)
#define RT_SENSOR_MODE_ACCURACY_HIGHEST_STR "Accuracy Highest"
#define RT_SENSOR_MODE_ACCURACY_HIGH (1)
#define RT_SENSOR_MODE_ACCURACY_HIGH_STR "Accuracy High"
#define RT_SENSOR_MODE_ACCURACY_MEDIUM (2)
#define RT_SENSOR_MODE_ACCURACY_MEDIUM_STR "Accuracy Medium"
#define RT_SENSOR_MODE_ACCURACY_LOW (3)
#define RT_SENSOR_MODE_ACCURACY_LOW_STR "Accuracy Low"
#define RT_SENSOR_MODE_ACCURACY_LOWEST (4)
#define RT_SENSOR_MODE_ACCURACY_LOWEST_STR "Accuracy Lowest"
#define RT_SENSOR_MODE_ACCURACY_NOTRUST (5)
#define RT_SENSOR_MODE_ACCURACY_NOTRUST_STR "Accuracy No Trust"
/* Sensor mode: power */
#define RT_SENSOR_MODE_POWER_HIGHEST (0)
#define RT_SENSOR_MODE_POWER_HIGHEST_STR "Power Highest"
#define RT_SENSOR_MODE_POWER_HIGH (1)
#define RT_SENSOR_MODE_POWER_HIGH_STR "Power High"
#define RT_SENSOR_MODE_POWER_MEDIUM (2)
#define RT_SENSOR_MODE_POWER_MEDIUM_STR "Power Medium"
#define RT_SENSOR_MODE_POWER_LOW (3)
#define RT_SENSOR_MODE_POWER_LOW_STR "Power Low"
#define RT_SENSOR_MODE_POWER_LOWEST (4)
#define RT_SENSOR_MODE_POWER_LOWEST_STR "Power Lowest"
#define RT_SENSOR_MODE_POWER_DOWN (5)
#define RT_SENSOR_MODE_POWER_DOWN_STR "Power Down"
/* Sensor mode: fetch data */
#define RT_SENSOR_MODE_FETCH_POLLING (0) /* One shot only read a data */
#define RT_SENSOR_MODE_FETCH_POLLING_STR "Polling Mode"
#define RT_SENSOR_MODE_FETCH_INT (1) /* TODO: One shot interrupt only read a data */
#define RT_SENSOR_MODE_FETCH_INT_STR "Interrupt Mode"
#define RT_SENSOR_MODE_FETCH_FIFO (2) /* TODO: One shot interrupt read all fifo data */
#define RT_SENSOR_MODE_FETCH_FIFO_STR "FIFO Mode"
/* Sensor control cmd types */
#define RT_SENSOR_CTRL_GET_ID (RT_DEVICE_CTRL_BASE(Sensor) + 0) /* Get device id */
#define RT_SENSOR_CTRL_SELF_TEST (RT_DEVICE_CTRL_BASE(Sensor) + 1) /* Take a self test */
#define RT_SENSOR_CTRL_SOFT_RESET (RT_DEVICE_CTRL_BASE(Sensor) + 2) /* soft reset sensor */
#define RT_SENSOR_CTRL_SET_FETCH_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 3) /* set fetch data mode */
#define RT_SENSOR_CTRL_SET_POWER_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 4) /* set power mode */
#define RT_SENSOR_CTRL_SET_ACCURACY_MODE (RT_DEVICE_CTRL_BASE(Sensor) + 5) /* set accuracy mode */
#define RT_SENSOR_CTRL_USER_CMD_START 0x100 /* User commands should be greater than 0x100 */
/* sensor floating data type */
#ifdef RT_USING_SENSOR_DOUBLE_FLOAT
typedef double rt_sensor_float_t;
#else
typedef float rt_sensor_float_t;
#endif /* RT_USING_SENSOR_DOUBLE_FLOAT */
struct rt_sensor_accuracy
{
rt_sensor_float_t resolution; /* resolution of sesnor measurement */
rt_sensor_float_t error; /* error of sesnor measurement */
};
struct rt_sensor_scale
{
rt_sensor_float_t range_max; /* maximum range of this sensor's value. unit is 'unit' */
rt_sensor_float_t range_min; /* minimum range of this sensor's value. unit is 'unit' */
};
struct rt_sensor_info
{
rt_uint8_t type; /* sensor type */
rt_uint8_t vendor; /* sensors vendor */
const char *name; /* name of sensor */
rt_uint8_t unit; /* unit of measurement */
rt_uint8_t intf_type; /* communication interface type */
rt_uint16_t mode; /* sensor work mode */
rt_uint8_t fifo_max;
rt_sensor_float_t acquire_min; /* minimum acquirement period, unit:ms. zero = not a constant rate */
struct rt_sensor_accuracy accuracy; /* sensor current measure accuracy */
struct rt_sensor_scale scale; /* sensor current scale range */
};
struct rt_sensor_intf
{
char *dev_name; /* The name of the communication device */
rt_uint8_t type; /* Communication interface type */
void *arg; /* Interface argument for the sensor. ex. i2c addr,spi cs,control I/O */
};
struct rt_sensor_config
{
struct rt_sensor_intf intf; /* sensor interface config */
struct rt_device_pin_mode irq_pin; /* Interrupt pin, The purpose of this pin is to notification read data */
};
typedef struct rt_sensor_device *rt_sensor_t;
typedef struct rt_sensor_data *rt_sensor_data_t;
typedef struct rt_sensor_info *rt_sensor_info_t;
typedef struct rt_sensor_accuracy *rt_sensor_accuracy_t;
typedef struct rt_sensor_scale *rt_sensor_scale_t;
struct rt_sensor_device
{
struct rt_device parent; /* The standard device */
struct rt_sensor_info info; /* The sensor info data */
struct rt_sensor_config config; /* The sensor config data */
rt_sensor_data_t data_buf; /* The buf of the data received */
rt_size_t data_len; /* The size of the data received */
const struct rt_sensor_ops *ops; /* The sensor ops */
struct rt_sensor_module *module; /* The sensor module */
rt_err_t (*irq_handle)(rt_sensor_t sensor); /* Called when an interrupt is generated, registered by the driver */
};
struct rt_sensor_module
{
rt_mutex_t lock; /* The module lock */
rt_sensor_t sen[RT_SENSOR_MODULE_MAX]; /* The module contains a list of sensors */
rt_uint8_t sen_num; /* Number of sensors contained in the module */
};
/* 3-axis Data Type */
struct sensor_3_axis
{
rt_sensor_float_t x;
rt_sensor_float_t y;
rt_sensor_float_t z;
};
/* Blood Pressure Data Type */
struct sensor_bp
{
rt_sensor_float_t sbp; /* SBP : systolic pressure */
rt_sensor_float_t dbp; /* DBP : diastolic pressure */
};
struct coordinates
{
rt_sensor_float_t longitude;
rt_sensor_float_t latitude;
};
struct rt_sensor_data
{
rt_uint32_t timestamp; /* The timestamp when the data was received */
rt_uint8_t type; /* The sensor type of the data */
union
{
struct sensor_3_axis acce; /* Accelerometer. unit: mG */
struct sensor_3_axis gyro; /* Gyroscope. unit: mdps */
struct sensor_3_axis mag; /* Magnetometer. unit: mGauss */
struct coordinates coord; /* Coordinates unit: degrees */
struct sensor_bp bp; /* BloodPressure. unit: mmHg */
rt_sensor_float_t temp; /* Temperature. unit: dCelsius */
rt_sensor_float_t humi; /* Relative humidity. unit: permillage */
rt_sensor_float_t baro; /* Pressure. unit: pascal (Pa) */
rt_sensor_float_t light; /* Light. unit: lux */
rt_sensor_float_t proximity; /* Distance. unit: centimeters */
rt_sensor_float_t hr; /* Heart rate. unit: bpm */
rt_sensor_float_t tvoc; /* TVOC. unit: permillage */
rt_sensor_float_t noise; /* Noise Loudness. unit: HZ */
rt_sensor_float_t step; /* Step sensor. unit: 1 */
rt_sensor_float_t force; /* Force sensor. unit: mN */
rt_sensor_float_t dust; /* Dust sensor. unit: ug/m3 */
rt_sensor_float_t eco2; /* eCO2 sensor. unit: ppm */
rt_sensor_float_t spo2; /* SpO2 sensor. unit: permillage */
rt_sensor_float_t iaq; /* IAQ sensor. unit: 1 */
rt_sensor_float_t etoh; /* EtOH sensor. unit: ppm */
} data;
};
struct rt_sensor_ops
{
rt_ssize_t (*fetch_data)(rt_sensor_t sensor, rt_sensor_data_t buf, rt_size_t len);
rt_err_t (*control)(rt_sensor_t sensor, int cmd, void *arg);
};
int rt_hw_sensor_register(rt_sensor_t sensor,
const char *name,
rt_uint32_t flag,
void *data);
rt_sensor_t rt_sensor_device_find(const char *name);
#ifdef __cplusplus
}
#endif
#endif /* __SENSOR_H__ */

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2006-2024 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-11-20 zhujiale the first version
*/
#ifndef __RTT_BYPASS_H__
#define __RTT_BYPASS_H__
#include <rtthread.h>
#include <rttypes.h>
#include <rtdevice.h>
typedef rt_err_t(*bypass_function_t)(struct rt_serial_device* serial, char buf, void* data);
#define RT_BYPASS_LEVEL_MAX 4
#define RT_BYPASS_LEVEL_1 0
#define RT_BYPASS_LEVEL_2 1
#define RT_BYPASS_LEVEL_3 2
#define RT_BYPASS_LEVEL_4 3
#define RT_BYPASS_MAX_LEVEL 4
/*The protect level can be register but can not be unregister we should use it carefully*/
#define RT_BYPASS_PROTECT_LEVEL_1 10
#define RT_BYPASS_PROTECT_LEVEL_2 11
#define RT_BYPASS_PROTECT_LEVEL_3 12
#define RT_BYPASS_PROTECT_LEVEL_4 13
struct rt_serial_bypass_func {
/*The function pointer of the bypassed data processing*/
bypass_function_t bypass;
/*The smaller the array of levels, the higher the priority of execution*/
rt_uint8_t level;
rt_list_t node;
char name[RT_NAME_MAX];
void* data;
};
struct rt_serial_bypass_head
{
rt_list_t head;
struct rt_spinlock spinlock;
};
struct rt_serial_bypass {
struct rt_work work;
struct rt_spinlock spinlock;
struct rt_workqueue* lower_workq;
struct rt_serial_bypass_head* upper_h;
struct rt_serial_bypass_head* lower_h;
rt_mutex_t mutex;
struct rt_ringbuffer* pipe;
};
int serial_bypass_list(int argc, char** argv);
void rt_bypass_work_straight(struct rt_serial_device* serial);
void rt_bypass_putchar(struct rt_serial_device* serial, rt_uint8_t ch);
rt_size_t rt_bypass_getchar(struct rt_serial_device* serial, rt_uint8_t* ch);
rt_err_t rt_bypass_upper_unregister(struct rt_serial_device* serial, rt_uint8_t level);
rt_err_t rt_bypass_lower_unregister(struct rt_serial_device* serial, rt_uint8_t level);
rt_err_t rt_bypass_upper_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data);
rt_err_t rt_bypass_lower_register(struct rt_serial_device* serial, const char* name, rt_uint8_t level, bypass_function_t func, void* data);
#endif

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-16 GuEe-GUI first version
*/
#ifndef __SERIAL_DM_H__
#define __SERIAL_DM_H__
#include <rtthread.h>
#include <rtdevice.h>
#include <posix/string.h>
int serial_dev_set_name(struct rt_serial_device *sdev);
void *serial_base_from_args(char *str);
struct serial_configure serial_cfg_from_args(char *str);
#define serial_for_each_args(arg, args) \
for (char *context = (arg = (typeof(arg))args, (void *)RT_NULL), \
*context_end = strchrnul((char *)args, ' '); \
(arg = strtok_r(arg, ",", &context)) && arg < context_end; \
arg = RT_NULL)
#endif /* __SERIAL_DM_H__ */

View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-02-25 GuEe-GUI the first version
*/
#ifndef __SYSCON_H__
#define __SYSCON_H__
#include <drivers/ofw.h>
struct rt_syscon
{
rt_list_t list;
struct rt_ofw_node *np;
void *iomem_base;
rt_size_t iomem_size;
struct rt_spinlock rw_lock;
};
rt_err_t rt_syscon_read(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t *out_val);
rt_err_t rt_syscon_write(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t val);
rt_err_t rt_syscon_update_bits(struct rt_syscon *syscon, rt_off_t offset, rt_uint32_t mask, rt_uint32_t val);
struct rt_syscon *rt_syscon_find_by_ofw_node(struct rt_ofw_node *np);
struct rt_syscon *rt_syscon_find_by_ofw_compatible(const char *compatible);
struct rt_syscon *rt_syscon_find_by_ofw_phandle(struct rt_ofw_node *np, const char *propname);
#endif /* __SYSCON_H__ */

View File

@ -0,0 +1,205 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-3-08 GuEe-GUI the first version
*/
#ifndef __THERMAL_H__
#define __THERMAL_H__
#include <rtdef.h>
#include <dt-bindings/thermal/thermal.h>
/* No upper/lower limit requirement */
#define RT_THERMAL_NO_LIMIT ((rt_uint32_t)THERMAL_NO_LIMIT)
#define RT_THERMAL_TEMP_INVALID (-274000)
struct rt_thermal_zone_ops;
struct rt_thermal_cooling_device;
struct rt_thermal_cooling_device_ops;
struct rt_thermal_cooling_governor;
enum rt_thermal_trip_type
{
RT_THERMAL_TRIP_ACTIVE = 0,
RT_THERMAL_TRIP_PASSIVE,
RT_THERMAL_TRIP_HOT,
RT_THERMAL_TRIP_CRITICAL,
RT_THERMAL_TRIP_TYPE_MAX,
};
struct rt_thermal_trip
{
/* Temperature value in millidegree celsius */
int temperature;
/* Relative hysteresis in millidegree celsius */
int hysteresis;
enum rt_thermal_trip_type type;
void *priv;
};
struct rt_thermal_zone_params
{
/* Sustainable power (heat) that this thermal zone can dissipate in mW */
int sustainable_power;
/* Slope of a linear temperature adjustment curve */
int slope;
/* Offset of a linear temperature adjustment curve */
int offset;
};
struct rt_thermal_cooling_cell
{
struct rt_thermal_cooling_device *cooling_devices;
rt_uint32_t level_range[2];
};
struct rt_thermal_cooling_map
{
rt_uint32_t contribution;
rt_size_t cells_nr;
struct rt_thermal_cooling_cell *cells;
struct rt_thermal_trip *trips;
};
struct rt_thermal_zone_device
{
struct rt_device parent;
int zone_id;
const struct rt_thermal_zone_ops *ops;
rt_bool_t trips_free;
rt_size_t trips_nr;
struct rt_thermal_trip *trips;
struct rt_thermal_zone_params params;
rt_bool_t enabled;
rt_bool_t cooling;
int temperature;
int last_temperature;
int prev_low_trip;
int prev_high_trip;
rt_list_t notifier_nodes;
struct rt_spinlock nodes_lock;
rt_size_t cooling_maps_nr;
struct rt_thermal_cooling_map *cooling_maps;
rt_tick_t passive_delay, polling_delay;
struct rt_work poller;
struct rt_mutex mutex;
void *priv;
};
struct rt_thermal_zone_ops
{
rt_err_t (*get_temp)(struct rt_thermal_zone_device *zdev, int *out_temp);
rt_err_t (*set_trips)(struct rt_thermal_zone_device *zdev, int low_temp, int high_temp);
rt_err_t (*set_trip_temp)(struct rt_thermal_zone_device *zdev, int trip_id, int temp);
rt_err_t (*set_trip_hyst)(struct rt_thermal_zone_device *zdev, int trip_id, int hyst);
void (*hot)(struct rt_thermal_zone_device *zdev);
void (*critical)(struct rt_thermal_zone_device *zdev);
};
/*
* We don't want to make a temperature control system
* that is finer than an air conditioner's temperature control,
* just ensure get a reliable heat dissipation under high-load task
* or when the SoC temperature is too high.
*/
struct rt_thermal_cooling_device
{
struct rt_device parent;
const struct rt_thermal_cooling_device_ops *ops;
/* The cooling capacity indicator */
rt_ubase_t max_level;
rt_list_t governor_node;
struct rt_thermal_cooling_governor *gov;
void *priv;
};
struct rt_thermal_cooling_device_ops
{
rt_err_t (*bind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
rt_err_t (*unbind)(struct rt_thermal_cooling_device *cdev, struct rt_thermal_zone_device *zdev);
rt_err_t (*get_max_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
rt_err_t (*get_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t *out_level);
rt_err_t (*set_cur_level)(struct rt_thermal_cooling_device *cdev, rt_ubase_t level);
};
struct rt_thermal_cooling_governor
{
rt_list_t list;
const char *name;
rt_list_t cdev_nodes;
void (*tuning)(struct rt_thermal_zone_device *zdev,
int map_idx, int cell_idx, rt_ubase_t *level);
};
struct rt_thermal_notifier;
#define RT_THERMAL_MSG_EVENT_UNSPECIFIED RT_BIT(0) /* Unspecified event */
#define RT_THERMAL_MSG_EVENT_TEMP_SAMPLE RT_BIT(1) /* New Temperature sample */
#define RT_THERMAL_MSG_TRIP_VIOLATED RT_BIT(2) /* TRIP Point violation */
#define RT_THERMAL_MSG_TRIP_CHANGED RT_BIT(3) /* TRIP Point temperature changed */
#define RT_THERMAL_MSG_DEVICE_DOWN RT_BIT(4) /* Thermal device is down */
#define RT_THERMAL_MSG_DEVICE_UP RT_BIT(5) /* Thermal device is up after a down event */
#define RT_THERMAL_MSG_DEVICE_POWER_CAPABILITY_CHANGED RT_BIT(6) /* Power capability changed */
#define RT_THERMAL_MSG_TABLE_CHANGED RT_BIT(7) /* Thermal table(s) changed */
#define RT_THERMAL_MSG_EVENT_KEEP_ALIVE RT_BIT(8) /* Request for user space handler to respond */
typedef rt_err_t (*rt_thermal_notifier_callback)(struct rt_thermal_notifier *notifier,
rt_ubase_t msg);
struct rt_thermal_notifier
{
rt_list_t list;
struct rt_thermal_zone_device *zdev;
rt_thermal_notifier_callback callback;
void *priv;
};
rt_err_t rt_thermal_zone_device_register(struct rt_thermal_zone_device *zdev);
rt_err_t rt_thermal_zone_device_unregister(struct rt_thermal_zone_device *zdev);
rt_err_t rt_thermal_cooling_device_register(struct rt_thermal_cooling_device *cdev);
rt_err_t rt_thermal_cooling_device_unregister(struct rt_thermal_cooling_device *cdev);
rt_err_t rt_thermal_cooling_governor_register(struct rt_thermal_cooling_governor *gov);
rt_err_t rt_thermal_cooling_governor_unregister(struct rt_thermal_cooling_governor *gov);
rt_err_t rt_thermal_cooling_device_change_governor(struct rt_thermal_cooling_device *cdev,
const char *name);
rt_err_t rt_thermal_zone_notifier_register(struct rt_thermal_zone_device *zdev,
struct rt_thermal_notifier *notifier);
rt_err_t rt_thermal_zone_notifier_unregister(struct rt_thermal_zone_device *zdev,
struct rt_thermal_notifier *notifier);
void rt_thermal_zone_device_update(struct rt_thermal_zone_device *zdev, rt_ubase_t msg);
void rt_thermal_cooling_device_kick(struct rt_thermal_zone_device *zdev);
rt_err_t rt_thermal_zone_set_trip(struct rt_thermal_zone_device *zdev, int trip_id,
const struct rt_thermal_trip *trip);
rt_err_t rt_thermal_zone_get_trip(struct rt_thermal_zone_device *zdev, int trip_id,
struct rt_thermal_trip *out_trip);
#endif /* __THERMAL_H__ */

View File

@ -0,0 +1,578 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-10-01 Yi Qiu first version
* 2013-04-26 aozima add DEVICEQUALIFIER support.
* 2017-11-15 ZYH fix ep0 transform error
*/
#ifndef __USB_COMMON_H__
#define __USB_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <rtthread.h>
#define RT_DEBUG_USB 0x00
#define USB_DYNAMIC 0x00
#define USB_CLASS_DEVICE 0x00
#define USB_CLASS_AUDIO 0x01
#define USB_CLASS_CDC 0x02
#define USB_CLASS_HID 0x03
#define USB_CLASS_PHYSICAL 0x05
#define USB_CLASS_IMAGE 0x06
#define USB_CLASS_PRINTER 0x07
#define USB_CLASS_MASS_STORAGE 0x08
#define USB_CLASS_HUB 0x09
#define USB_CLASS_CDC_DATA 0x0a
#define USB_CLASS_SMART_CARD 0x0b
#define USB_CLASS_SECURITY 0x0d
#define USB_CLASS_VIDEO 0x0e
#define USB_CLASS_HEALTHCARE 0x0f
#define USB_CLASS_DIAG_DEVICE 0xdc
#define USB_CLASS_WIRELESS 0xe0
#define USB_CLASS_MISC 0xef
#define USB_CLASS_APP_SPECIFIC 0xfe
#define USB_CLASS_VEND_SPECIFIC 0xff
#define USB_DESC_TYPE_DEVICE 0x01
#define USB_DESC_TYPE_CONFIGURATION 0x02
#define USB_DESC_TYPE_STRING 0x03
#define USB_DESC_TYPE_INTERFACE 0x04
#define USB_DESC_TYPE_ENDPOINT 0x05
#define USB_DESC_TYPE_DEVICEQUALIFIER 0x06
#define USB_DESC_TYPE_OTHERSPEED 0x07
#define USB_DESC_TYPE_IAD 0x0b
#define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22
#define USB_DESC_TYPE_PHYSICAL 0x23
#define USB_DESC_TYPE_HUB 0x29
#define USB_DESC_LENGTH_DEVICE 0x12
#define USB_DESC_LENGTH_CONFIG 0x9
#define USB_DESC_LENGTH_IAD 0x8
#define USB_DESC_LENGTH_STRING 0x4
#define USB_DESC_LENGTH_INTERFACE 0x9
#define USB_DESC_LENGTH_ENDPOINT 0x7
#define USB_REQ_TYPE_STANDARD 0x00
#define USB_REQ_TYPE_CLASS 0x20
#define USB_REQ_TYPE_VENDOR 0x40
#define USB_REQ_TYPE_MASK 0x60
#define USB_REQ_TYPE_DIR_OUT 0x00
#define USB_REQ_TYPE_DIR_IN 0x80
#define USB_REQ_TYPE_DEVICE 0x00
#define USB_REQ_TYPE_INTERFACE 0x01
#define USB_REQ_TYPE_ENDPOINT 0x02
#define USB_REQ_TYPE_OTHER 0x03
#define USB_REQ_TYPE_RECIPIENT_MASK 0x1f
#define USB_FEATURE_ENDPOINT_HALT 0x00
#define USB_FEATURE_DEV_REMOTE_WAKEUP 0x01
#define USB_FEATURE_TEST_MODE 0x02
#define USB_REQ_GET_STATUS 0x00
#define USB_REQ_CLEAR_FEATURE 0x01
#define USB_REQ_SET_FEATURE 0x03
#define USB_REQ_SET_ADDRESS 0x05
#define USB_REQ_GET_DESCRIPTOR 0x06
#define USB_REQ_SET_DESCRIPTOR 0x07
#define USB_REQ_GET_CONFIGURATION 0x08
#define USB_REQ_SET_CONFIGURATION 0x09
#define USB_REQ_GET_INTERFACE 0x0A
#define USB_REQ_SET_INTERFACE 0x0B
#define USB_REQ_SYNCH_FRAME 0x0C
#define USB_REQ_SET_ENCRYPTION 0x0D
#define USB_REQ_GET_ENCRYPTION 0x0E
#define USB_REQ_RPIPE_ABORT 0x0E
#define USB_REQ_SET_HANDSHAKE 0x0F
#define USB_REQ_RPIPE_RESET 0x0F
#define USB_REQ_GET_HANDSHAKE 0x10
#define USB_REQ_SET_CONNECTION 0x11
#define USB_REQ_SET_SECURITY_DATA 0x12
#define USB_REQ_GET_SECURITY_DATA 0x13
#define USB_REQ_SET_WUSB_DATA 0x14
#define USB_REQ_LOOPBACK_DATA_WRITE 0x15
#define USB_REQ_LOOPBACK_DATA_READ 0x16
#define USB_REQ_SET_INTERFACE_DS 0x17
#define USB_STRING_LANGID_INDEX 0x00
#define USB_STRING_MANU_INDEX 0x01
#define USB_STRING_PRODUCT_INDEX 0x02
#define USB_STRING_SERIAL_INDEX 0x03
#define USB_STRING_CONFIG_INDEX 0x04
#define USB_STRING_INTERFACE_INDEX 0x05
#define USB_STRING_OS_INDEX 0x06
#define USB_STRING_MAX 0xff
#define USB_STRING_OS "MSFT100A"
#define USB_PID_OUT 0x01
#define USB_PID_ACK 0x02
#define USB_PID_DATA0 0x03
#define USB_PID_SOF 0x05
#define USB_PID_IN 0x09
#define USB_PID_NACK 0x0A
#define USB_PID_DATA1 0x0B
#define USB_PID_PRE 0x0C
#define USB_PID_SETUP 0x0D
#define USB_PID_STALL 0x0E
#define USB_EP_DESC_OUT 0x00
#define USB_EP_DESC_IN 0x80
#define USB_EP_DESC_NUM_MASK 0x0f
#define USB_EP_ATTR_CONTROL 0x00
#define USB_EP_ATTR_ISOC 0x01
#define USB_EP_ATTR_BULK 0x02
#define USB_EP_ATTR_INT 0x03
#define USB_EP_ATTR_TYPE_MASK 0x03
#define USB_EPNO_MASK 0x7f
#define USB_DIR_OUT 0x00
#define USB_DIR_IN 0x80
#define USB_DIR_INOUT 0x40
#define USB_DIR_MASK 0x80
#define ID_UNASSIGNED 0
#define ID_ASSIGNED 1
#define RH_GET_PORT_STATUS 0
#define RH_SET_PORT_STATUS 1
#define RH_CLEAR_PORT_FEATURE 2
#define RH_SET_PORT_FEATURE 3
#define USB_BUS_POWERED 0
#define USB_SELF_POWERED 1
#define USB_REMOTE_WAKEUP 1
#define USB_EP_HALT 0
/*
* Port feature numbers
*/
#define PORT_FEAT_CONNECTION 0
#define PORT_FEAT_ENABLE 1
#define PORT_FEAT_SUSPEND 2
#define PORT_FEAT_OVER_CURRENT 3
#define PORT_FEAT_RESET 4
#define PORT_FEAT_POWER 8
#define PORT_FEAT_LOWSPEED 9
#define PORT_FEAT_HIGHSPEED 10
#define PORT_FEAT_C_CONNECTION 16
#define PORT_FEAT_C_ENABLE 17
#define PORT_FEAT_C_SUSPEND 18
#define PORT_FEAT_C_OVER_CURRENT 19
#define PORT_FEAT_C_RESET 20
/*
The HcRhPortStatus[1:NDP] register is used to control and report port events on a per-port
basis. NumberDownstreamPorts represents the number of HcRhPortStatus registers that are
implemented in hardware. The lower word is used to reflect the port status, whereas the upper
word reflects the status change bits. Some status bits are implemented with special write behavior
(see below). If a transaction (token through handshake) is in progress when a write to change
port status occurs, the resulting port status change must be postponed until the transaction
completes. Reserved bits should always be written '0'.
*/
#define PORT_CCS 0x00000001UL /* R:CurrentConnectStatus - W:ClearPortEnable */
#define PORT_PES 0x00000002UL /* R:PortEnableStatus - W:SetPortEnable */
#define PORT_PSS 0x00000004UL /* R:PortSuspendStatus - W:SetPortSuspend */
#define PORT_POCI 0x00000008UL /* R:PortOverCurrentIndicator - W:ClearSuspendStatus */
#define PORT_PRS 0x00000010UL /* R:PortResetStatus - W: SetPortReset */
#define PORT_PPS 0x00000100UL /* R:PortPowerStatus - W: SetPortPower */
#define PORT_LSDA 0x00000200UL /* R:LowSpeedDeviceAttached - W:ClearPortPower */
#define PORT_CCSC 0x00010000UL
#define PORT_PESC 0x00020000UL
#define PORT_PSSC 0x00040000UL
#define PORT_POCIC 0x00080000UL
#define PORT_PRSC 0x00100000UL
/*
*Hub Status & Hub Change bit masks
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
#define USB_EP_ATTR(attr) (attr & USB_EP_ATTR_TYPE_MASK)
#define USB_EP_DESC_NUM(addr) (addr & USB_EP_DESC_NUM_MASK)
#define USB_EP_DIR(addr) ((addr & USB_DIR_MASK)>>7)
#define HID_REPORT_ID_KEYBOARD1 1
#define HID_REPORT_ID_KEYBOARD2 2
#define HID_REPORT_ID_KEYBOARD3 3
#define HID_REPORT_ID_KEYBOARD4 7
#define HID_REPORT_ID_MEDIA 4
#define HID_REPORT_ID_GENERAL 5
#define HID_REPORT_ID_MOUSE 6
/*
* Time of usb timeout
*/
#ifndef USB_TIMEOUT_BASIC
#define USB_TIMEOUT_BASIC (RT_TICK_PER_SECOND) /* 1s */
#endif
#ifndef USB_TIMEOUT_LONG
#define USB_TIMEOUT_LONG (RT_TICK_PER_SECOND * 5) /* 5s */
#endif
#ifndef USB_DEBOUNCE_TIME
#define USB_DEBOUNCE_TIME (RT_TICK_PER_SECOND / 5) /* 0.2s */
#endif
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define uswap_8(x) \
(((rt_uint16_t)(*((rt_uint8_t *)(x)))) + \
(((rt_uint16_t)(*(((rt_uint8_t *)(x)) + 1))) << 8))
typedef void (*func_callback)(void *context);
typedef enum
{
USB_STATE_NOTATTACHED = 0,
USB_STATE_ATTACHED,
USB_STATE_POWERED,
USB_STATE_RECONNECTING,
USB_STATE_UNAUTHENTICATED,
USB_STATE_DEFAULT,
USB_STATE_ADDRESS,
USB_STATE_CONFIGURED,
USB_STATE_SUSPENDED
}udevice_state_t;
typedef enum
{
STAGE_IDLE,
STAGE_SETUP,
STAGE_STATUS_IN,
STAGE_STATUS_OUT,
STAGE_DIN,
STAGE_DOUT
} uep0_stage_t;
#pragma pack(1)
struct usb_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
};
typedef struct usb_descriptor* udesc_t;
struct udevice_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t bcdUSB;
rt_uint8_t bDeviceClass;
rt_uint8_t bDeviceSubClass;
rt_uint8_t bDeviceProtocol;
rt_uint8_t bMaxPacketSize0;
rt_uint16_t idVendor;
rt_uint16_t idProduct;
rt_uint16_t bcdDevice;
rt_uint8_t iManufacturer;
rt_uint8_t iProduct;
rt_uint8_t iSerialNumber;
rt_uint8_t bNumConfigurations;
};
typedef struct udevice_descriptor* udev_desc_t;
struct uconfig_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t wTotalLength;
rt_uint8_t bNumInterfaces;
rt_uint8_t bConfigurationValue;
rt_uint8_t iConfiguration;
rt_uint8_t bmAttributes;
rt_uint8_t MaxPower;
rt_uint8_t data[2048];
};
typedef struct uconfig_descriptor* ucfg_desc_t;
struct uinterface_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bInterfaceNumber;
rt_uint8_t bAlternateSetting;
rt_uint8_t bNumEndpoints;
rt_uint8_t bInterfaceClass;
rt_uint8_t bInterfaceSubClass;
rt_uint8_t bInterfaceProtocol;
rt_uint8_t iInterface;
};
typedef struct uinterface_descriptor* uintf_desc_t;
/* Interface Association Descriptor (IAD) */
struct uiad_descriptor
{
rt_uint8_t bLength;
rt_uint8_t bDescriptorType;
rt_uint8_t bFirstInterface;
rt_uint8_t bInterfaceCount;
rt_uint8_t bFunctionClass;
rt_uint8_t bFunctionSubClass;
rt_uint8_t bFunctionProtocol;
rt_uint8_t iFunction;
};
typedef struct uiad_descriptor* uiad_desc_t;
struct uendpoint_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t bEndpointAddress;
rt_uint8_t bmAttributes;
rt_uint16_t wMaxPacketSize;
rt_uint8_t bInterval;
};
typedef struct uendpoint_descriptor* uep_desc_t;
struct ustring_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint8_t String[64];
};
typedef struct ustring_descriptor* ustr_desc_t;
struct uhub_descriptor
{
rt_uint8_t length;
rt_uint8_t type;
rt_uint8_t num_ports;
rt_uint16_t characteristics;
rt_uint8_t pwron_to_good; /* power on to power good */
rt_uint8_t current;
rt_uint8_t removable[8];
rt_uint8_t pwr_ctl[8];
};
typedef struct uhub_descriptor* uhub_desc_t;
/* USB_DESC_TYPE_DEVICEQUALIFIER: Device Qualifier descriptor */
struct usb_qualifier_descriptor
{
rt_uint8_t bLength;
rt_uint8_t bDescriptorType;
rt_uint16_t bcdUSB; // TODO: big-endian.
rt_uint8_t bDeviceClass;
rt_uint8_t bDeviceSubClass;
rt_uint8_t bDeviceProtocol;
rt_uint8_t bMaxPacketSize0;
rt_uint8_t bNumConfigurations;
rt_uint8_t bRESERVED;
} __attribute__ ((packed));
struct usb_os_header_comp_id_descriptor
{
rt_uint32_t dwLength;
rt_uint16_t bcdVersion;
rt_uint16_t wIndex;
rt_uint8_t bCount;
rt_uint8_t reserved[7];
};
typedef struct usb_os_header_comp_id_descriptor * usb_os_header_desc_t;
struct usb_os_property_header
{
rt_uint32_t dwLength;
rt_uint16_t bcdVersion;
rt_uint16_t wIndex;
rt_uint16_t wCount;
};
typedef struct usb_os_property_header * usb_os_property_header_t;
struct usb_os_proerty
{
rt_uint32_t dwSize;
rt_uint32_t dwPropertyDataType;
rt_uint16_t wPropertyNameLength;
const char * bPropertyName;
rt_uint32_t dwPropertyDataLength;
const char * bPropertyData;
};
typedef struct usb_os_proerty * usb_os_proerty_t;
// Value Description
// 1 A NULL-terminated Unicode String (REG_SZ)
// 2 A NULL-terminated Unicode String that includes environment variables (REG_EXPAND_SZ)
// 3 Free-form binary (REG_BINARY)
// 4 A little-endian 32-bit integer (REG_DWORD_LITTLE_ENDIAN)
// 5 A big-endian 32-bit integer (REG_DWORD_BIG_ENDIAN)
// 6 A NULL-terminated Unicode string that contains a symbolic link (REG_LINK)
// 7 Multiple NULL-terminated Unicode strings (REG_MULTI_SZ)
#define USB_OS_PROPERTY_TYPE_REG_SZ 0x01UL
#define USB_OS_PROPERTY_TYPE_REG_EXPAND_SZ 0x02UL
#define USB_OS_PROPERTY_TYPE_REG_BINARY 0x03UL
#define USB_OS_PROPERTY_TYPE_REG_DWORD_LITTLE_ENDIAN 0x04UL
#define USB_OS_PROPERTY_TYPE_REG_DWORD_BIG_ENDIAN 0x05UL
#define USB_OS_PROPERTY_TYPE_REG_LINK 0x06UL
#define USB_OS_PROPERTY_TYPE_REG_MULTI_SZ 0x07UL
#define USB_OS_PROPERTY_DESC(PropertyDataType,PropertyName,PropertyData) \
{\
.dwSize = sizeof(struct usb_os_proerty)-sizeof(const char *)*2\
+sizeof(PropertyName)*2+sizeof(PropertyData)*2,\
.dwPropertyDataType = PropertyDataType,\
.wPropertyNameLength = sizeof(PropertyName)*2,\
.bPropertyName = PropertyName,\
.dwPropertyDataLength = sizeof(PropertyData)*2,\
.bPropertyData = PropertyData\
}
#ifndef HID_SUB_DESCRIPTOR_MAX
#define HID_SUB_DESCRIPTOR_MAX 1
#endif
struct uhid_descriptor
{
rt_uint8_t bLength;
rt_uint8_t type;
rt_uint16_t bcdHID;
rt_uint8_t bCountryCode;
rt_uint8_t bNumDescriptors;
struct hid_descriptor_list
{
rt_uint8_t type;
rt_uint16_t wLength;
}Descriptor[HID_SUB_DESCRIPTOR_MAX];
};
typedef struct uhid_descriptor* uhid_desc_t;
struct hid_report
{
rt_uint8_t report_id;
rt_uint8_t report[63];
rt_uint8_t size;
};
typedef struct hid_report* hid_report_t;
extern void HID_Report_Received(hid_report_t report);
struct urequest
{
rt_uint8_t request_type;
rt_uint8_t bRequest;
rt_uint16_t wValue;
rt_uint16_t wIndex;
rt_uint16_t wLength;
};
typedef struct urequest* ureq_t;
#ifndef MIN
#define MIN(a, b) (a < b ? a : b)
#endif
#ifndef MAX
#define MAX(a, b) (a > b ? a : b)
#endif
/*
* the define related to mass storage
*/
#define USBREQ_GET_MAX_LUN 0xfe
#define USBREQ_MASS_STORAGE_RESET 0xff
#define SIZEOF_CSW 0x0d
#define SIZEOF_CBW 0x1f
#define SIZEOF_INQUIRY_CMD 0x24
#define SIZEOF_MODE_SENSE_6 0x4
#define SIZEOF_READ_CAPACITIES 0xc
#define SIZEOF_READ_CAPACITY 0x8
#define SIZEOF_REQUEST_SENSE 0x12
#define CBWFLAGS_DIR_M 0x80
#define CBWFLAGS_DIR_IN 0x80
#define CBWFLAGS_DIR_OUT 0x00
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_INQUIRY_CMD 0x12
#define SCSI_ALLOW_REMOVAL 0x1e
#define SCSI_MODE_SENSE_6 0x1a
#define SCSI_START_STOP 0x1b
#define SCSI_READ_CAPACITIES 0x23
#define SCSI_READ_CAPACITY 0x25
#define SCSI_READ_10 0x28
#define SCSI_WRITE_10 0x2a
#define SCSI_VERIFY_10 0x2f
#define CBW_SIGNATURE 0x43425355
#define CSW_SIGNATURE 0x53425355
#define CBW_TAG_VALUE 0x12345678
struct ustorage_cbw
{
rt_uint32_t signature;
rt_uint32_t tag;
rt_uint32_t xfer_len;
rt_uint8_t dflags;
rt_uint8_t lun;
rt_uint8_t cb_len;
rt_uint8_t cb[16];
};
typedef struct ustorage_cbw* ustorage_cbw_t;
struct ustorage_csw
{
rt_uint32_t signature;
rt_uint32_t tag;
rt_int32_t data_reside;
rt_uint8_t status;
};
typedef struct ustorage_csw* ustorage_csw_t;
#pragma pack()
struct usb_os_comp_id_descriptor
{
struct usb_os_header_comp_id_descriptor head_desc;
rt_list_t func_desc;
};
typedef struct usb_os_comp_id_descriptor * usb_os_comp_id_desc_t;
struct usb_os_function_comp_id_descriptor
{
rt_list_t list;
rt_uint8_t bFirstInterfaceNumber;
rt_uint8_t reserved1;
rt_uint8_t compatibleID[8];
rt_uint8_t subCompatibleID[8];
rt_uint8_t reserved2[6];
};
typedef struct usb_os_function_comp_id_descriptor * usb_os_func_comp_id_desc_t;
/*
* USB device event loop thread configurations
*/
/* the stack size of USB thread */
#ifndef RT_USBD_THREAD_STACK_SZ
#define RT_USBD_THREAD_STACK_SZ 512
#endif
/* the priority of USB thread */
#ifndef RT_USBD_THREAD_PRIO
#define RT_USBD_THREAD_PRIO 8
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,473 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-10-01 Yi Qiu first version
* 2012-12-12 heyuanjie87 change endpoint and function handler
* 2013-04-26 aozima add DEVICEQUALIFIER support.
* 2017-11-15 ZYH fix ep0 transform error
* 2023-10-11 ChuShicheng change rt_size_t to rt_ssize_t
*/
#ifndef __USB_DEVICE_H__
#define __USB_DEVICE_H__
#include <rtthread.h>
#include "drivers/usb_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Vendor ID */
#ifdef USB_VENDOR_ID
#define _VENDOR_ID USB_VENDOR_ID
#else
#define _VENDOR_ID 0x0EFF
#endif
/* Product ID */
#ifdef USB_PRODUCT_ID
#define _PRODUCT_ID USB_PRODUCT_ID
#else
#define _PRODUCT_ID 0x0001
#endif
#ifndef MAX_INTF_STR
#define MAX_INTF_STR 20
#endif
#define USB_BCD_DEVICE 0x0200 /* USB Specification Release Number in Binary-Coded Decimal */
#define USB_BCD_VERSION 0x0200 /* USB 2.0 */
#define EP0_IN_ADDR 0x80
#define EP0_OUT_ADDR 0x00
#define EP_HANDLER(ep, func, size) RT_ASSERT(ep != RT_NULL); ep->handler(func, size)
#define EP_ADDRESS(ep) ep->ep_desc->bEndpointAddress
#define EP_MAXPACKET(ep) ep->ep_desc->wMaxPacketSize
#define FUNC_ENABLE(func) do{ \
if(func->ops->enable != RT_NULL && \
func->enabled == RT_FALSE) \
{ \
if(func->ops->enable(func) == RT_EOK) \
func->enabled = RT_TRUE; \
} \
}while(0)
#define FUNC_DISABLE(func) do{ \
if(func->ops->disable != RT_NULL && \
func->enabled == RT_TRUE) \
{ \
func->enabled = RT_FALSE; \
func->ops->disable(func); \
} \
}while(0)
#define RT_USBD_CLASS_CTRL_CONNECTED (RT_DEVICE_CTRL_BASE(USBDevice) + 0)
struct ufunction;
struct udevice;
struct uendpoint;
typedef enum
{
/* request to read full count */
UIO_REQUEST_READ_FULL,
/* request to read any count */
UIO_REQUEST_READ_BEST,
/* request to write full count */
UIO_REQUEST_WRITE,
}UIO_REQUEST_TYPE;
struct udcd_ops
{
rt_err_t (*set_address)(rt_uint8_t address);
rt_err_t (*set_config)(rt_uint8_t address);
rt_err_t (*ep_set_stall)(rt_uint8_t address);
rt_err_t (*ep_clear_stall)(rt_uint8_t address);
rt_err_t (*ep_enable)(struct uendpoint* ep);
rt_err_t (*ep_disable)(struct uendpoint* ep);
rt_ssize_t (*ep_read_prepare)(rt_uint8_t address, void *buffer, rt_size_t size);
rt_ssize_t (*ep_read)(rt_uint8_t address, void *buffer);
rt_ssize_t (*ep_write)(rt_uint8_t address, void *buffer, rt_size_t size);
rt_err_t (*ep0_send_status)(void);
rt_err_t (*suspend)(void);
rt_err_t (*wakeup)(void);
};
struct ep_id
{
rt_uint8_t addr;
rt_uint8_t type;
rt_uint8_t dir;
rt_uint16_t maxpacket;
rt_uint8_t status;
};
typedef rt_err_t (*udep_handler_t)(struct ufunction* func, rt_size_t size);
struct uio_request
{
rt_list_t list;
UIO_REQUEST_TYPE req_type;
rt_uint8_t* buffer;
rt_size_t size;
rt_size_t remain_size;
};
typedef struct uio_request* uio_request_t;
struct uendpoint
{
rt_list_t list;
uep_desc_t ep_desc;
rt_list_t request_list;
struct uio_request request;
rt_uint8_t* buffer;
rt_bool_t stalled;
struct ep_id* id;
udep_handler_t handler;
rt_err_t (*rx_indicate)(struct udevice* dev, rt_size_t size);
};
typedef struct uendpoint* uep_t;
struct udcd
{
struct rt_device parent;
const struct udcd_ops* ops;
struct uendpoint ep0;
uep0_stage_t stage;
struct ep_id* ep_pool;
rt_uint8_t device_is_hs;
};
typedef struct udcd* udcd_t;
struct ualtsetting
{
rt_list_t list;
uintf_desc_t intf_desc;
void* desc;
rt_size_t desc_size;
rt_list_t ep_list;
};
typedef struct ualtsetting* ualtsetting_t;
typedef rt_err_t (*uintf_handler_t)(struct ufunction* func, ureq_t setup);
struct uinterface
{
rt_list_t list;
rt_uint8_t intf_num;
ualtsetting_t curr_setting;
rt_list_t setting_list;
uintf_handler_t handler;
};
typedef struct uinterface* uintf_t;
struct ufunction_ops
{
rt_err_t (*enable)(struct ufunction* func);
rt_err_t (*disable)(struct ufunction* func);
rt_err_t (*sof_handler)(struct ufunction* func);
};
typedef struct ufunction_ops* ufunction_ops_t;
struct ufunction
{
rt_list_t list;
ufunction_ops_t ops;
struct udevice* device;
udev_desc_t dev_desc;
void* user_data;
rt_bool_t enabled;
rt_list_t intf_list;
};
typedef struct ufunction* ufunction_t;
struct uconfig
{
rt_list_t list;
struct uconfig_descriptor cfg_desc;
rt_list_t func_list;
};
typedef struct uconfig* uconfig_t;
struct udevice
{
rt_list_t list;
struct udevice_descriptor dev_desc;
struct usb_qualifier_descriptor * dev_qualifier;
usb_os_comp_id_desc_t os_comp_id_desc;
const char** str;
const char *str_intf[MAX_INTF_STR];
udevice_state_t state;
rt_list_t cfg_list;
uconfig_t curr_cfg;
rt_uint8_t nr_intf;
udcd_t dcd;
};
typedef struct udevice* udevice_t;
struct udclass
{
rt_list_t list;
ufunction_t (*rt_usbd_function_create)(udevice_t device);
};
typedef struct udclass* udclass_t;
enum udev_msg_type
{
USB_MSG_SETUP_NOTIFY,
USB_MSG_DATA_NOTIFY,
USB_MSG_EP0_OUT,
USB_MSG_EP_CLEAR_FEATURE,
USB_MSG_SOF,
USB_MSG_RESET,
USB_MSG_PLUG_IN,
/* we don't need to add a "PLUG_IN" event because after the cable is
* plugged in(before any SETUP) the classed have nothing to do. If the host
* is ready, it will send RESET and we will have USB_MSG_RESET. So, a RESET
* should reset and run the class while plug_in is not. */
USB_MSG_PLUG_OUT,
};
typedef enum udev_msg_type udev_msg_type;
struct ep_msg
{
rt_size_t size;
rt_uint8_t ep_addr;
};
struct udev_msg
{
udev_msg_type type;
udcd_t dcd;
union
{
struct ep_msg ep_msg;
struct urequest setup;
} content;
};
typedef struct udev_msg* udev_msg_t;
int rt_usbd_class_list_init(void);
udevice_t rt_usbd_device_new(void);
uconfig_t rt_usbd_config_new(void);
ufunction_t rt_usbd_function_new(udevice_t device, udev_desc_t dev_desc,
ufunction_ops_t ops);
uintf_t rt_usbd_interface_new(udevice_t device, uintf_handler_t handler);
uep_t rt_usbd_endpoint_new(uep_desc_t ep_desc, udep_handler_t handler);
ualtsetting_t rt_usbd_altsetting_new(rt_size_t desc_size);
rt_err_t rt_usbd_core_init(void);
rt_err_t rt_usb_device_init(void);
rt_err_t rt_usbd_event_signal(struct udev_msg* msg);
rt_err_t rt_usbd_device_set_controller(udevice_t device, udcd_t dcd);
rt_err_t rt_usbd_device_set_descriptor(udevice_t device, udev_desc_t dev_desc);
rt_err_t rt_usbd_device_set_string(udevice_t device, const char** ustring);
rt_err_t rt_usbd_device_set_interface_string(udevice_t device, int index, const char* string);
rt_err_t rt_usbd_device_set_qualifier(udevice_t device, struct usb_qualifier_descriptor* qualifier);
rt_err_t rt_usbd_device_set_os_comp_id_desc(udevice_t device, usb_os_comp_id_desc_t os_comp_id_desc);
rt_err_t rt_usbd_device_add_config(udevice_t device, uconfig_t cfg);
rt_err_t rt_usbd_config_add_function(uconfig_t cfg, ufunction_t func);
rt_err_t rt_usbd_class_register(udclass_t udclass);
rt_err_t rt_usbd_function_add_interface(ufunction_t func, uintf_t intf);
rt_err_t rt_usbd_interface_add_altsetting(uintf_t intf, ualtsetting_t setting);
rt_err_t rt_usbd_altsetting_add_endpoint(ualtsetting_t setting, uep_t ep);
rt_err_t rt_usbd_os_comp_id_desc_add_os_func_comp_id_desc(usb_os_comp_id_desc_t os_comp_id_desc, usb_os_func_comp_id_desc_t os_func_comp_id_desc);
rt_err_t rt_usbd_altsetting_config_descriptor(ualtsetting_t setting, const void* desc, rt_off_t intf_pos);
rt_err_t rt_usbd_set_config(udevice_t device, rt_uint8_t value);
rt_err_t rt_usbd_set_altsetting(uintf_t intf, rt_uint8_t value);
udevice_t rt_usbd_find_device(udcd_t dcd);
uconfig_t rt_usbd_find_config(udevice_t device, rt_uint8_t value);
uintf_t rt_usbd_find_interface(udevice_t device, rt_uint8_t value, ufunction_t *pfunc);
uep_t rt_usbd_find_endpoint(udevice_t device, ufunction_t* pfunc, rt_uint8_t ep_addr);
rt_size_t rt_usbd_io_request(udevice_t device, uep_t ep, uio_request_t req);
rt_size_t rt_usbd_ep0_write(udevice_t device, void *buffer, rt_size_t size);
rt_size_t rt_usbd_ep0_read(udevice_t device, void *buffer, rt_size_t size,
rt_err_t (*rx_ind)(udevice_t device, rt_size_t size));
int rt_usbd_vcom_class_register(void);
int rt_usbd_ecm_class_register(void);
int rt_usbd_hid_class_register(void);
int rt_usbd_msc_class_register(void);
int rt_usbd_rndis_class_register(void);
int rt_usbd_winusb_class_register(void);
#ifdef RT_USB_DEVICE_COMPOSITE
rt_err_t rt_usbd_function_set_iad(ufunction_t func, uiad_desc_t iad_desc);
#endif
rt_err_t rt_usbd_set_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index);
rt_err_t rt_usbd_clear_feature(udevice_t device, rt_uint16_t value, rt_uint16_t index);
rt_err_t rt_usbd_ep_set_stall(udevice_t device, uep_t ep);
rt_err_t rt_usbd_ep_clear_stall(udevice_t device, uep_t ep);
rt_err_t rt_usbd_ep0_set_stall(udevice_t device);
rt_err_t rt_usbd_ep0_clear_stall(udevice_t device);
rt_err_t rt_usbd_ep0_setup_handler(udcd_t dcd, struct urequest* setup);
rt_err_t rt_usbd_ep0_in_handler(udcd_t dcd);
rt_err_t rt_usbd_ep0_out_handler(udcd_t dcd, rt_size_t size);
rt_err_t rt_usbd_ep_in_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size);
rt_err_t rt_usbd_ep_out_handler(udcd_t dcd, rt_uint8_t address, rt_size_t size);
rt_err_t rt_usbd_reset_handler(udcd_t dcd);
rt_err_t rt_usbd_connect_handler(udcd_t dcd);
rt_err_t rt_usbd_disconnect_handler(udcd_t dcd);
rt_err_t rt_usbd_sof_handler(udcd_t dcd);
rt_inline rt_err_t dcd_set_address(udcd_t dcd, rt_uint8_t address)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->set_address != RT_NULL);
return dcd->ops->set_address(address);
}
rt_inline rt_err_t dcd_set_config(udcd_t dcd, rt_uint8_t address)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->set_config != RT_NULL);
return dcd->ops->set_config(address);
}
rt_inline rt_err_t dcd_ep_enable(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep_enable != RT_NULL);
return dcd->ops->ep_enable(ep);
}
rt_inline rt_err_t dcd_ep_disable(udcd_t dcd, uep_t ep)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep_disable != RT_NULL);
return dcd->ops->ep_disable(ep);
}
rt_inline rt_size_t dcd_ep_read_prepare(udcd_t dcd, rt_uint8_t address, void *buffer,
rt_size_t size)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
if(dcd->ops->ep_read_prepare != RT_NULL)
{
return dcd->ops->ep_read_prepare(address, buffer, size);
}
else
{
return 0;
}
}
rt_inline rt_size_t dcd_ep_read(udcd_t dcd, rt_uint8_t address, void *buffer)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
if(dcd->ops->ep_read != RT_NULL)
{
return dcd->ops->ep_read(address, buffer);
}
else
{
return 0;
}
}
rt_inline rt_size_t dcd_ep_write(udcd_t dcd, rt_uint8_t address, void *buffer,
rt_size_t size)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep_write != RT_NULL);
return dcd->ops->ep_write(address, buffer, size);
}
rt_inline rt_err_t dcd_ep0_send_status(udcd_t dcd)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep0_send_status != RT_NULL);
return dcd->ops->ep0_send_status();
}
rt_inline rt_err_t dcd_ep_set_stall(udcd_t dcd, rt_uint8_t address)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep_set_stall != RT_NULL);
return dcd->ops->ep_set_stall(address);
}
rt_inline rt_err_t dcd_ep_clear_stall(udcd_t dcd, rt_uint8_t address)
{
RT_ASSERT(dcd != RT_NULL);
RT_ASSERT(dcd->ops != RT_NULL);
RT_ASSERT(dcd->ops->ep_clear_stall != RT_NULL);
return dcd->ops->ep_clear_stall(address);
}
rt_inline void usbd_os_proerty_descriptor_send(ufunction_t func, ureq_t setup, usb_os_proerty_t usb_os_proerty, rt_uint8_t number_of_proerty)
{
struct usb_os_property_header header;
static rt_uint8_t * data;
rt_uint8_t * pdata;
rt_uint8_t index,i;
if(data == RT_NULL)
{
header.dwLength = sizeof(struct usb_os_property_header);
header.bcdVersion = 0x0100;
header.wIndex = 0x05;
header.wCount = number_of_proerty;
for(index = 0;index < number_of_proerty;index++)
{
header.dwLength += usb_os_proerty[index].dwSize;
}
data = (rt_uint8_t *)rt_malloc(header.dwLength);
RT_ASSERT(data != RT_NULL);
pdata = data;
rt_memcpy((void *)pdata,(void *)&header,sizeof(struct usb_os_property_header));
pdata += sizeof(struct usb_os_property_header);
for(index = 0;index < number_of_proerty;index++)
{
rt_memcpy((void *)pdata,(void *)&usb_os_proerty[index],10);
pdata += 10;
for(i = 0;i < usb_os_proerty[index].wPropertyNameLength/2;i++)
{
*pdata = usb_os_proerty[index].bPropertyName[i];
pdata++;
*pdata = 0;
pdata++;
}
*((rt_uint32_t *)pdata) = usb_os_proerty[index].dwPropertyDataLength;
pdata += 4;
for(i = 0;i < usb_os_proerty[index].dwPropertyDataLength/2;i++)
{
*pdata = usb_os_proerty[index].bPropertyData[i];
pdata++;
*pdata = 0;
pdata++;
}
}
}
rt_usbd_ep0_write(func->device, data, setup->wLength);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,269 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2011-3-12 Yi Qiu first version
* 2021-02-23 Leslie Lee provide possibility for multi usb host
*/
#ifndef __RT_USB_HOST_H__
#define __RT_USB_HOST_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <rtthread.h>
#include "usb_common.h"
#define USB_MAX_DEVICE 0x20
#define USB_MAX_INTERFACE 0x08
#define USB_HUB_PORT_NUM 0x04
#define SIZEOF_USB_REQUEST 0x08
#define DEV_STATUS_IDLE 0x00
#define DEV_STATUS_BUSY 0x01
#define DEV_STATUS_ERROR 0x02
#define UPIPE_STATUS_OK 0x00
#define UPIPE_STATUS_STALL 0x01
#define UPIPE_STATUS_ERROR 0x02
#define USBH_PID_SETUP 0x00
#define USBH_PID_DATA 0x01
struct uhcd;
struct uhintf;
struct uhub;
struct upipe;
struct uclass_driver
{
rt_list_t list;
int class_code;
int subclass_code;
rt_err_t (*enable)(void* arg);
rt_err_t (*disable)(void* arg);
void* user_data;
};
typedef struct uclass_driver* ucd_t;
struct uprotocal
{
rt_list_t list;
int pro_id;
rt_err_t (*init)(void* arg);
rt_err_t (*callback)(void* arg);
};
typedef struct uprotocal* uprotocal_t;
struct uinstance
{
struct rt_device parent;
struct udevice_descriptor dev_desc;
ucfg_desc_t cfg_desc;
struct uhcd *hcd;
struct upipe * pipe_ep0_out;
struct upipe * pipe_ep0_in;
rt_list_t pipe;
rt_uint8_t status;
rt_uint8_t type;
rt_uint8_t index;
rt_uint8_t address;
rt_uint8_t speed;
rt_uint8_t max_packet_size;
rt_uint8_t port;
struct uhub* parent_hub;
struct uhintf* intf[USB_MAX_INTERFACE];
};
typedef struct uinstance* uinst_t;
struct uhintf
{
struct uinstance* device;
uintf_desc_t intf_desc;
ucd_t drv;
void *user_data;
};
struct upipe
{
rt_list_t list;
rt_uint8_t pipe_index;
rt_uint32_t status;
struct uendpoint_descriptor ep;
uinst_t inst;
func_callback callback;
void* user_data;
};
typedef struct upipe* upipe_t;
struct uhub
{
struct uhub_descriptor hub_desc;
rt_uint8_t num_ports;
rt_uint32_t port_status[USB_HUB_PORT_NUM];
struct uinstance* child[USB_HUB_PORT_NUM];
rt_bool_t is_roothub;
rt_uint8_t buffer[8];
struct uinstance* self;
struct uhcd *hcd;
};
typedef struct uhub* uhub_t;
struct uhcd_ops
{
rt_err_t (*reset_port) (rt_uint8_t port);
int (*pipe_xfer) (upipe_t pipe, rt_uint8_t token, void* buffer, int nbytes, int timeout);
rt_err_t (*open_pipe) (upipe_t pipe);
rt_err_t (*close_pipe) (upipe_t pipe);
};
typedef struct uhcd_ops* uhcd_ops_t;
struct uhcd
{
struct rt_device parent;
uhcd_ops_t ops;
rt_uint8_t num_ports;
uhub_t roothub;
struct rt_messagequeue *usb_mq;
};
typedef struct uhcd* uhcd_t;
enum uhost_msg_type
{
USB_MSG_CONNECT_CHANGE,
USB_MSG_CALLBACK,
};
typedef enum uhost_msg_type uhost_msg_type;
struct uhost_msg
{
uhost_msg_type type;
union
{
struct uhub* hub;
struct
{
func_callback function;
void *context;
}cb;
}content;
};
typedef struct uhost_msg* uhost_msg_t;
/* usb host system interface */
rt_err_t rt_usb_host_init(const char *name);
void rt_usbh_hub_init(struct uhcd *hcd);
/* usb host core interface */
struct uinstance* rt_usbh_alloc_instance(uhcd_t uhcd);
rt_err_t rt_usbh_attatch_instance(struct uinstance* device);
rt_err_t rt_usbh_detach_instance(struct uinstance* device);
rt_err_t rt_usbh_get_descriptor(struct uinstance* device, rt_uint8_t type, void* buffer, int nbytes);
rt_err_t rt_usbh_set_configure(struct uinstance* device, int config);
rt_err_t rt_usbh_set_address(struct uinstance* device);
rt_err_t rt_usbh_set_interface(struct uinstance* device, int intf);
rt_err_t rt_usbh_clear_feature(struct uinstance* device, int endpoint, int feature);
rt_err_t rt_usbh_get_interface_descriptor(ucfg_desc_t cfg_desc, int num, uintf_desc_t* intf_desc);
rt_err_t rt_usbh_get_endpoint_descriptor(uintf_desc_t intf_desc, int num, uep_desc_t* ep_desc);
/* usb class driver interface */
rt_err_t rt_usbh_class_driver_init(void);
rt_err_t rt_usbh_class_driver_register(ucd_t drv);
rt_err_t rt_usbh_class_driver_unregister(ucd_t drv);
rt_err_t rt_usbh_class_driver_enable(ucd_t drv, void* args);
rt_err_t rt_usbh_class_driver_disable(ucd_t drv, void* args);
ucd_t rt_usbh_class_driver_find(int class_code, int subclass_code);
/* usb class driver implement */
ucd_t rt_usbh_class_driver_hub(void);
ucd_t rt_usbh_class_driver_storage(void);
/* usb hub interface */
rt_err_t rt_usbh_hub_get_descriptor(struct uinstance* device, rt_uint8_t *buffer,
rt_size_t size);
rt_err_t rt_usbh_hub_get_status(struct uinstance* device, rt_uint32_t* buffer);
rt_err_t rt_usbh_hub_get_port_status(uhub_t uhub, rt_uint16_t port,
rt_uint32_t* buffer);
rt_err_t rt_usbh_hub_clear_port_feature(uhub_t uhub, rt_uint16_t port,
rt_uint16_t feature);
rt_err_t rt_usbh_hub_set_port_feature(uhub_t uhub, rt_uint16_t port,
rt_uint16_t feature);
rt_err_t rt_usbh_hub_reset_port(uhub_t uhub, rt_uint16_t port);
rt_err_t rt_usbh_event_signal(uhcd_t uhcd, struct uhost_msg* msg);
void rt_usbh_root_hub_connect_handler(struct uhcd *hcd, rt_uint8_t port, rt_bool_t isHS);
void rt_usbh_root_hub_disconnect_handler(struct uhcd *hcd, rt_uint8_t port);
/* usb host controller driver interface */
rt_inline rt_err_t rt_usb_instance_add_pipe(uinst_t inst, upipe_t pipe)
{
RT_ASSERT(inst != RT_NULL);
RT_ASSERT(pipe != RT_NULL);
rt_list_insert_before(&inst->pipe, &pipe->list);
return RT_EOK;
}
rt_inline upipe_t rt_usb_instance_find_pipe(uinst_t inst,rt_uint8_t ep_address)
{
rt_list_t * l;
for(l = inst->pipe.next;l != &inst->pipe;l = l->next)
{
if(rt_list_entry(l,struct upipe,list)->ep.bEndpointAddress == ep_address)
{
return rt_list_entry(l,struct upipe,list);
}
}
return RT_NULL;
}
rt_inline rt_err_t rt_usb_hcd_alloc_pipe(uhcd_t hcd, upipe_t* pipe, uinst_t inst, uep_desc_t ep)
{
*pipe = (upipe_t)rt_malloc(sizeof(struct upipe));
if(*pipe == RT_NULL)
{
return -RT_ERROR;
}
rt_memset(*pipe,0,sizeof(struct upipe));
(*pipe)->inst = inst;
rt_memcpy(&(*pipe)->ep,ep,sizeof(struct uendpoint_descriptor));
return hcd->ops->open_pipe(*pipe);
}
rt_inline void rt_usb_pipe_add_callback(upipe_t pipe, func_callback callback)
{
pipe->callback = callback;
}
rt_inline rt_err_t rt_usb_hcd_free_pipe(uhcd_t hcd, upipe_t pipe)
{
RT_ASSERT(pipe != RT_NULL);
hcd->ops->close_pipe(pipe);
rt_free(pipe);
return RT_EOK;
}
int rt_usb_hcd_pipe_xfer(uhcd_t hcd, upipe_t pipe, void* buffer, int nbytes, int timeout);
rt_inline int rt_usb_hcd_setup_xfer(uhcd_t hcd, upipe_t pipe, ureq_t setup, int timeout)
{
return hcd->ops->pipe_xfer(pipe, USBH_PID_SETUP, (void *)setup, 8, timeout);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-09-15 tyx the first version
*/
#ifndef __WLAN_H__
#define __WLAN_H__
#include <rtthread.h>
#include <dev_wlan.h>
#include <dev_wlan_cfg.h>
#include <dev_wlan_mgnt.h>
#include <dev_wlan_prot.h>
#include <dev_wlan_workqueue.h>
#endif

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_PHYE_H__
#define __DT_BINDINGS_PHYE_H__
#define PHY_NONE 0
#define PHY_TYPE_SATA 1
#define PHY_TYPE_PCIE 2
#define PHY_TYPE_USB2 3
#define PHY_TYPE_USB3 4
#define PHY_TYPE_UFS 5
#define PHY_TYPE_DP 6
#define PHY_TYPE_XPCS 7
#define PHY_TYPE_SGMII 8
#define PHY_TYPE_QSGMII 9
#define PHY_TYPE_DPHY 10
#define PHY_TYPE_CPHY 11
#define PHY_TYPE_USXGMII 12
#endif /* __DT_BINDINGS_PHYE_H__ */

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_PIN_PIN_H__
#define __DT_BINDINGS_PIN_PIN_H__
/* Bit 0 express polarity */
#define PIN_ACTIVE_HIGH 0
#define PIN_ACTIVE_LOW 1
/* Bit 1 express single-endedness */
#define PIN_PUSH_PULL 0
#define PIN_SINGLE_ENDED 2
/* Bit 2 express Open drain or open source */
#define PIN_LINE_OPEN_SOURCE 0
#define PIN_LINE_OPEN_DRAIN 4
/*
* Open Drain/Collector is the combination of single-ended open drain interface.
* Open Source/Emitter is the combination of single-ended open source interface.
*/
#define PIN_OPEN_DRAIN (PIN_SINGLE_ENDED | PIN_LINE_OPEN_DRAIN)
#define PIN_OPEN_SOURCE (PIN_SINGLE_ENDED | PIN_LINE_OPEN_SOURCE)
/* Bit 3 express PIN suspend/resume and reset persistence */
#define PIN_PERSISTENT 0
#define PIN_TRANSITORY 8
/* Bit 4 express pull up */
#define PIN_PULL_UP 16
/* Bit 5 express pull down */
#define PIN_PULL_DOWN 32
/* Bit 6 express pull disable */
#define PIN_PULL_DISABLE 64
#endif /* __DT_BINDINGS_PIN_PIN_H__ */

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_PIN_STATE_H__
#define __DT_BINDINGS_PIN_STATE_H__
#define PIND_FLAGS_BIT_DIR_SET (1 << 0)
#define PIND_FLAGS_BIT_DIR_OUT (1 << 1)
#define PIND_FLAGS_BIT_DIR_VAL (1 << 2)
#define PIND_FLAGS_BIT_OPEN_DRAIN (1 << 3)
#define PIND_FLAGS_BIT_NONEXCLUSIVE (1 << 4)
/* Don't change anything */
#define PIND_ASIS 0
/* Set lines to input mode */
#define PIND_IN PIND_FLAGS_BIT_DIR_SET
/* Set lines to output and drive them low */
#define PIND_OUT_LOW (PIND_FLAGS_BIT_DIR_SET | PIND_FLAGS_BIT_DIR_OUT)
/* Set lines to output and drive them high */
#define PIND_OUT_HIGH (PIND_FLAGS_BIT_DIR_SET | PIND_FLAGS_BIT_DIR_OUT | PIND_FLAGS_BIT_DIR_VAL)
/* Set lines to open-drain output and drive them low */
#define PIND_OUT_LOW_OPEN_DRAIN (PIND_OUT_LOW | PIND_FLAGS_BIT_OPEN_DRAIN)
/* Set lines to open-drain output and drive them high */
#define PIND_OUT_HIGH_OPEN_DRAIN (PIND_OUT_HIGH | PIND_FLAGS_BIT_OPEN_DRAIN)
#endif /* __DT_BINDINGS_PIN_STATE_H__ */

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_SIZE_H__
#define __DT_BINDINGS_SIZE_H__
#define SIZE_KB 1024
#define SIZE_MB (1024 * SIZE_KB)
#define SIZE_GB (1024 * SIZE_MB)
#define SIZE_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1))
#define SIZE_ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
#endif /* __DT_BINDINGS_SIZE_H__ */

View File

@ -0,0 +1,13 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __DT_BINDINGS_THERMAL_THERMAL_H__
#define __DT_BINDINGS_THERMAL_THERMAL_H__
/* On cooling devices upper and lower limits */
#define THERMAL_NO_LIMIT (~0)
#endif /* __DT_BINDINGS_THERMAL_THERMAL_H__ */

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-28 Shell Add new wait_flags() & wakeup_by_errno() API
* 2024-10-24 yekai Add C++ support
*/
#ifndef COMPLETION_H_
#define COMPLETION_H_
#include <rtdef.h>
#include <rtconfig.h>
/**
* RT-Completion - A Tiny(resource-constrained) & Rapid(lockless) IPC Primitive
*
* It's an IPC using one pointer word with the encoding:
*
* BIT | MAX-1 ----------------- 1 | 0 |
* CONTENT | suspended_thread & ~1 | completed flag |
*/
struct rt_completion
{
/* suspended thread, and completed flag */
rt_atomic_t susp_thread_n_flag;
};
#define RT_COMPLETION_INIT(comp) {0}
#ifdef __cplusplus
extern "C" {
#endif
void rt_completion_init(struct rt_completion *completion);
rt_err_t rt_completion_wait(struct rt_completion *completion,
rt_int32_t timeout);
rt_err_t rt_completion_wait_noisr(struct rt_completion *completion,
rt_int32_t timeout);
rt_err_t rt_completion_wait_flags(struct rt_completion *completion,
rt_int32_t timeout, int suspend_flag);
rt_err_t rt_completion_wait_flags_noisr(struct rt_completion *completion,
rt_int32_t timeout, int suspend_flag);
void rt_completion_done(struct rt_completion *completion);
rt_err_t rt_completion_wakeup(struct rt_completion *completion);
rt_err_t rt_completion_wakeup_by_errno(struct rt_completion *completion, rt_err_t error);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-11-20 Shell Add cond var API in kernel
*/
#ifndef IPC_CONDVAR_H__
#define IPC_CONDVAR_H__
#include <rtthread.h>
typedef struct rt_condvar
{
#ifdef USING_RT_OBJECT
struct rt_object parent;
#endif
rt_atomic_t waiters_cnt;
rt_atomic_t waiting_mtx;
struct rt_wqueue event;
} *rt_condvar_t;
void rt_condvar_init(rt_condvar_t cv, char *name);
int rt_condvar_timedwait(rt_condvar_t cv, rt_mutex_t mtx, int suspend_flag,
rt_tick_t timeout);
int rt_condvar_signal(rt_condvar_t cv);
int rt_condvar_broadcast(rt_condvar_t cv);
rt_inline void rt_condvar_detach(rt_condvar_t cv)
{
RT_UNUSED(cv);
return ;
}
#endif /* IPC_CONDVAR_H__ */

View File

@ -0,0 +1,67 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef DATAQUEUE_H__
#define DATAQUEUE_H__
#include <rtdef.h>
#include <rtconfig.h>
#define RT_DATAQUEUE_EVENT_UNKNOWN 0x00
#define RT_DATAQUEUE_EVENT_POP 0x01
#define RT_DATAQUEUE_EVENT_PUSH 0x02
#define RT_DATAQUEUE_EVENT_LWM 0x03
struct rt_data_item;
/* data queue implementation */
struct rt_data_queue
{
rt_uint32_t magic;
rt_uint16_t size;
rt_uint16_t lwm;
rt_uint16_t get_index : 15;
rt_uint16_t is_empty : 1;
rt_uint16_t put_index : 15;
rt_uint16_t is_full : 1;
struct rt_data_item *queue;
struct rt_spinlock spinlock;
rt_list_t suspended_push_list;
rt_list_t suspended_pop_list;
/* event notify */
void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event);
};
/**
* DataQueue for DeviceDriver
*/
rt_err_t rt_data_queue_init(struct rt_data_queue *queue,
rt_uint16_t size,
rt_uint16_t lwm,
void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event));
rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
const void *data_ptr,
rt_size_t data_size,
rt_int32_t timeout);
rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
const void **data_ptr,
rt_size_t *size,
rt_int32_t timeout);
rt_err_t rt_data_queue_peek(struct rt_data_queue *queue,
const void **data_ptr,
rt_size_t *size);
void rt_data_queue_reset(struct rt_data_queue *queue);
rt_err_t rt_data_queue_deinit(struct rt_data_queue *queue);
rt_uint16_t rt_data_queue_len(struct rt_data_queue *queue);
#endif

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#ifndef PIPE_H__
#define PIPE_H__
#include <rtdef.h>
#include <rtconfig.h>
#include "condvar.h"
/**
* Pipe Device
*/
struct rt_pipe_device
{
struct rt_device parent;
rt_bool_t is_named;
#ifdef RT_USING_POSIX_DEVIO
int pipeno; /* for unamed pipe */
#endif
/* ring buffer in pipe device */
struct rt_ringbuffer *fifo;
rt_uint16_t bufsz;
rt_wqueue_t reader_queue;
rt_wqueue_t writer_queue;
int writer;
int reader;
struct rt_condvar waitfor_parter;
struct rt_mutex lock;
};
typedef struct rt_pipe_device rt_pipe_t;
rt_pipe_t *rt_pipe_create(const char *name, int bufsz);
rt_err_t rt_pipe_open(rt_device_t device, rt_uint16_t oflag);
rt_ssize_t rt_pipe_read(rt_device_t device, rt_off_t pos, void *buffer, rt_size_t count);
rt_ssize_t rt_pipe_write(rt_device_t device, rt_off_t pos, const void *buffer, rt_size_t count);
rt_err_t rt_pipe_control(rt_device_t dev, int cmd, void *args);
rt_err_t rt_pipe_close(rt_device_t device);
int rt_pipe_delete(const char *name);
#endif /* PIPE_H__ */

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2016-09-19 Heyuanjie The first version.
* 2016-12-26 Bernard Update poll interface
*/
#ifndef IPC_POLL_H__
#define IPC_POLL_H__
#include <rtdef.h>
#include <rtconfig.h>
#ifdef __cplusplus
extern "C" {
#endif
struct rt_pollreq;
typedef void (*poll_queue_proc)(rt_wqueue_t *, struct rt_pollreq *);
typedef struct rt_pollreq
{
poll_queue_proc _proc;
short _key;
} rt_pollreq_t;
rt_inline void rt_poll_add(rt_wqueue_t *wq, rt_pollreq_t *req)
{
if (req && req->_proc && wq)
{
req->_proc(wq, req);
}
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-08-25 armink the first version
*/
#ifndef _RINGBLK_BUF_H_
#define _RINGBLK_BUF_H_
#include <rtdef.h>
#include <rtconfig.h>
/*
* Introduction:
* The rbb is the ring buffer which is composed with many blocks. It is different from the ring buffer.
* The ring buffer is only composed with chars. The rbb put and get supported zero copies. So the rbb
* is very suitable for put block and get block by a certain order. Such as DMA block transmit,
* communicate frame send/recv, and so on.
*/
#ifdef __cplusplus
extern "C" {
#endif
enum rt_rbb_status
{
/* unused status when first initialize or after blk_free() */
RT_RBB_BLK_UNUSED,
/* initialized status after blk_alloc() */
RT_RBB_BLK_INITED,
/* put status after blk_put() */
RT_RBB_BLK_PUT,
/* get status after blk_get() */
RT_RBB_BLK_GET,
};
typedef enum rt_rbb_status rt_rbb_status_t;
/**
* the block of rbb
*/
struct rt_rbb_blk
{
rt_rbb_status_t status :8;
/* less then 2^24 */
rt_size_t size :24;
rt_uint8_t *buf;
rt_slist_t list;
};
typedef struct rt_rbb_blk *rt_rbb_blk_t;
/**
* Rbb block queue: the blocks (from block1->buf to blockn->buf) memory which on this queue is continuous.
*/
struct rt_rbb_blk_queue
{
rt_rbb_blk_t blocks;
rt_size_t blk_num;
};
typedef struct rt_rbb_blk_queue *rt_rbb_blk_queue_t;
/**
* ring block buffer
*/
struct rt_rbb
{
rt_uint8_t *buf;
rt_size_t buf_size;
/* all of blocks */
rt_rbb_blk_t blk_set;
rt_size_t blk_max_num;
/* saved the initialized and put status blocks */
rt_slist_t blk_list;
/* point to tail node */
rt_slist_t *tail;
/* free node list */
rt_slist_t free_list;
struct rt_spinlock spinlock;
};
typedef struct rt_rbb *rt_rbb_t;
/* rbb (ring block buffer) API */
void rt_rbb_init(rt_rbb_t rbb, rt_uint8_t *buf, rt_size_t buf_size, rt_rbb_blk_t block_set, rt_size_t blk_max_num);
rt_size_t rt_rbb_get_buf_size(rt_rbb_t rbb);
#ifdef RT_USING_HEAP
rt_rbb_t rt_rbb_create(rt_size_t buf_size, rt_size_t blk_max_num);
void rt_rbb_destroy(rt_rbb_t rbb);
#endif
/* rbb block API */
rt_rbb_blk_t rt_rbb_blk_alloc(rt_rbb_t rbb, rt_size_t blk_size);
void rt_rbb_blk_put(rt_rbb_blk_t block);
rt_rbb_blk_t rt_rbb_blk_get(rt_rbb_t rbb);
rt_size_t rt_rbb_blk_size(rt_rbb_blk_t block);
rt_uint8_t *rt_rbb_blk_buf(rt_rbb_blk_t block);
void rt_rbb_blk_free(rt_rbb_t rbb, rt_rbb_blk_t block);
/* rbb block queue API */
rt_size_t rt_rbb_blk_queue_get(rt_rbb_t rbb, rt_size_t queue_data_len, rt_rbb_blk_queue_t blk_queue);
rt_size_t rt_rbb_blk_queue_len(rt_rbb_blk_queue_t blk_queue);
rt_uint8_t *rt_rbb_blk_queue_buf(rt_rbb_blk_queue_t blk_queue);
void rt_rbb_blk_queue_free(rt_rbb_t rbb, rt_rbb_blk_queue_t blk_queue);
rt_size_t rt_rbb_next_blk_queue_len(rt_rbb_t rbb);
#ifdef __cplusplus
}
#endif
#endif /* _RINGBLK_BUF_H_ */

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-14 Jackistang add comments for function interface.
*/
#ifndef RINGBUFFER_H__
#define RINGBUFFER_H__
#include <rtdef.h>
#include <rtconfig.h>
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ring buffer */
struct rt_ringbuffer
{
rt_uint8_t *buffer_ptr;
/* use the msb of the {read,write}_index as mirror bit. You can see this as
* if the buffer adds a virtual mirror and the pointers point either to the
* normal or to the mirrored buffer. If the write_index has the same value
* with the read_index, but in a different mirror, the buffer is full.
* While if the write_index and the read_index are the same and within the
* same mirror, the buffer is empty. The ASCII art of the ringbuffer is:
*
* mirror = 0 mirror = 1
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Full
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* read_idx-^ write_idx-^
*
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* | 0 | 1 | 2 | 3 | 4 | 5 | 6 ||| 0 | 1 | 2 | 3 | 4 | 5 | 6 | Empty
* +---+---+---+---+---+---+---+|+~~~+~~~+~~~+~~~+~~~+~~~+~~~+
* read_idx-^ ^-write_idx
*/
rt_uint32_t read_mirror : 1;
rt_uint32_t read_index : 31;
rt_uint32_t write_mirror : 1;
rt_uint32_t write_index : 31;
/* as we use msb of index as mirror bit, the size should be signed and
* could only be positive. */
rt_int32_t buffer_size;
};
enum rt_ringbuffer_state
{
RT_RINGBUFFER_EMPTY,
RT_RINGBUFFER_FULL,
/* half full is neither full nor empty */
RT_RINGBUFFER_HALFFULL,
};
/**
* RingBuffer for DeviceDriver
*
* Please note that the ring buffer implementation of RT-Thread
* has no thread wait or resume feature.
*/
void rt_ringbuffer_init(struct rt_ringbuffer *rb, rt_uint8_t *pool, rt_int32_t size);
void rt_ringbuffer_reset(struct rt_ringbuffer *rb);
rt_size_t rt_ringbuffer_put(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint32_t length);
rt_size_t rt_ringbuffer_put_force(struct rt_ringbuffer *rb, const rt_uint8_t *ptr, rt_uint32_t length);
rt_size_t rt_ringbuffer_putchar(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_putchar_force(struct rt_ringbuffer *rb, const rt_uint8_t ch);
rt_size_t rt_ringbuffer_get(struct rt_ringbuffer *rb, rt_uint8_t *ptr, rt_uint32_t length);
rt_size_t rt_ringbuffer_peek(struct rt_ringbuffer *rb, rt_uint8_t **ptr);
rt_size_t rt_ringbuffer_getchar(struct rt_ringbuffer *rb, rt_uint8_t *ch);
rt_size_t rt_ringbuffer_data_len(struct rt_ringbuffer *rb);
#ifdef RT_USING_HEAP
struct rt_ringbuffer* rt_ringbuffer_create(rt_uint32_t length);
void rt_ringbuffer_destroy(struct rt_ringbuffer *rb);
#endif
/**
* @brief Get the buffer size of the ring buffer object.
*
* @param rb A pointer to the ring buffer object.
*
* @return Buffer size.
*/
rt_inline rt_uint32_t rt_ringbuffer_get_size(struct rt_ringbuffer *rb)
{
RT_ASSERT(rb != RT_NULL);
return rb->buffer_size;
}
/** return the size of empty space in rb */
#define rt_ringbuffer_space_len(rb) ((rb)->buffer_size - rt_ringbuffer_data_len(rb))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018/06/26 Bernard Fix the wait queue issue when wakeup a soon
* to blocked thread.
*/
#ifndef WAITQUEUE_H__
#define WAITQUEUE_H__
#include <rtdef.h>
#include <rtconfig.h>
#define RT_WQ_FLAG_CLEAN 0x00
#define RT_WQ_FLAG_WAKEUP 0x01
struct rt_wqueue_node;
typedef int (*rt_wqueue_func_t)(struct rt_wqueue_node *wait, void *key);
struct rt_wqueue_node
{
rt_thread_t polling_thread;
rt_list_t list;
rt_wqueue_t *wqueue;
rt_wqueue_func_t wakeup;
rt_uint32_t key;
};
typedef struct rt_wqueue_node rt_wqueue_node_t;
int __wqueue_default_wake(struct rt_wqueue_node *wait, void *key);
rt_inline void rt_wqueue_init(rt_wqueue_t *queue)
{
RT_ASSERT(queue != RT_NULL);
queue->flag = RT_WQ_FLAG_CLEAN;
rt_list_init(&(queue->waiting_list));
rt_spin_lock_init(&(queue->spinlock));
}
void rt_wqueue_add(rt_wqueue_t *queue, struct rt_wqueue_node *node);
void rt_wqueue_remove(struct rt_wqueue_node *node);
int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int timeout);
int rt_wqueue_wait_killable(rt_wqueue_t *queue, int condition, int timeout);
int rt_wqueue_wait_interruptible(rt_wqueue_t *queue, int condition, int timeout);
void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key);
void rt_wqueue_wakeup_all(rt_wqueue_t *queue, void *key);
#define DEFINE_WAIT_FUNC(name, function) \
struct rt_wqueue_node name = { \
rt_current_thread, \
RT_LIST_OBJECT_INIT(((name).list)), \
function, \
0 \
}
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, __wqueue_default_wake)
#endif

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-01 Meco Man remove rt_delayed_work_init() and rt_delayed_work structure
* 2021-08-14 Jackistang add comments for rt_work_init()
*/
#ifndef WORKQUEUE_H__
#define WORKQUEUE_H__
#include <rtdef.h>
#include <rtconfig.h>
#include "completion.h"
#ifdef __cplusplus
extern "C" {
#endif
enum
{
RT_WORK_STATE_PENDING = 0x0001, /* Work item pending state */
RT_WORK_STATE_SUBMITTING = 0x0002, /* Work item submitting state */
};
/**
* work type definitions
*/
enum
{
RT_WORK_TYPE_DELAYED = 0x0001,
};
/* workqueue implementation */
struct rt_workqueue
{
rt_list_t work_list;
rt_list_t delayed_list;
struct rt_work *work_current; /* current work */
struct rt_semaphore sem;
rt_thread_t work_thread;
struct rt_spinlock spinlock;
struct rt_completion wakeup_completion;
};
struct rt_work
{
rt_list_t list;
void (*work_func)(struct rt_work *work, void *work_data);
void *work_data;
rt_uint16_t flags;
rt_uint16_t type;
rt_tick_t timeout_tick;
struct rt_workqueue *workqueue;
};
#ifdef RT_USING_HEAP
/**
* WorkQueue for DeviceDriver
*/
void rt_work_init(struct rt_work *work, void (*work_func)(struct rt_work *work, void *work_data), void *work_data);
struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority);
rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue);
rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work);
rt_err_t rt_workqueue_submit_work(struct rt_workqueue *queue, struct rt_work *work, rt_tick_t ticks);
rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work);
rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work);
rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue);
rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *work);
#ifdef RT_USING_SYSTEM_WORKQUEUE
rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t ticks);
rt_err_t rt_work_urgent(struct rt_work *work);
rt_err_t rt_work_cancel(struct rt_work *work);
#endif /* RT_USING_SYSTEM_WORKQUEUE */
#ifdef __cplusplus
}
#endif
#endif /* RT_USING_HEAP */
#endif

View File

@ -0,0 +1,276 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-01-08 bernard first version.
* 2014-07-12 bernard Add workqueue implementation.
*/
#ifndef __RT_DEVICE_H__
#define __RT_DEVICE_H__
#include <rtdef.h>
#include <rtthread.h>
#include <drivers/core/driver.h>
#include <drivers/core/bus.h>
#include <drivers/classes/block.h>
#include <drivers/classes/char.h>
#include <drivers/classes/graphic.h>
#include <drivers/classes/mtd.h>
#include <drivers/classes/net.h>
#include "ipc/ringbuffer.h"
#include "ipc/completion.h"
#include "ipc/dataqueue.h"
#include "ipc/workqueue.h"
#include "ipc/condvar.h"
#include "ipc/waitqueue.h"
#include "ipc/pipe.h"
#include "ipc/poll.h"
#include "ipc/ringblk_buf.h"
#ifdef __cplusplus
extern "C" {
#endif
#define RT_DEVICE(device) ((rt_device_t)device)
#ifdef RT_USING_DM
#include "drivers/core/dm.h"
#include "drivers/core/numa.h"
#include "drivers/core/power_domain.h"
#include "drivers/platform.h"
#ifdef RT_USING_ATA
#ifdef RT_ATA_AHCI
#include "drivers/ahci.h"
#endif /* RT_ATA_AHCI */
#endif /* RT_USING_ATA */
#ifdef RT_USING_LED
#include "drivers/led.h"
#endif
#ifdef RT_USING_MBOX
#include "drivers/mailbox.h"
#endif /* RT_USING_MBOX */
#ifdef RT_USING_BLK
#include "drivers/blk.h"
#endif /* RT_USING_BLK */
#ifdef RT_USING_DMA
#include "drivers/dma.h"
#endif /* RT_USING_DMA */
#include "drivers/iio.h"
#ifdef RT_USING_NVME
#include "drivers/nvme.h"
#endif /* RT_USING_NVME */
#ifdef RT_USING_OFW
#include "drivers/ofw.h"
#include "drivers/ofw_fdt.h"
#include "drivers/ofw_io.h"
#include "drivers/ofw_irq.h"
#include "drivers/ofw_raw.h"
#endif /* RT_USING_OFW */
#ifdef RT_USING_PHYE
#include "drivers/phye.h"
#endif /* RT_USING_PHYE */
#ifdef RT_USING_PIC
#include "drivers/pic.h"
#endif /* RT_USING_PIC */
#ifdef RT_USING_PCI
#include "drivers/pci.h"
#ifdef RT_PCI_MSI
#include "drivers/pci_msi.h"
#endif /* RT_PCI_MSI */
#ifdef RT_PCI_ENDPOINT
#include "drivers/pci_endpoint.h"
#endif /* RT_PCI_ENDPOINT */
#endif /* RT_USING_PCI */
#ifdef RT_USING_REGULATOR
#include "drivers/regulator.h"
#endif /* RT_USING_REGULATOR */
#ifdef RT_USING_RESET
#include "drivers/reset.h"
#endif /* RT_USING_RESET */
#ifdef RT_USING_SCSI
#include "drivers/scsi.h"
#endif /* RT_USING_SCSI */
#ifdef RT_MFD_SYSCON
#include "drivers/syscon.h"
#endif /* RT_MFD_SYSCON */
#ifdef RT_USING_THERMAL
#include "drivers/thermal.h"
#endif /* RT_USING_THERMAL */
#endif /* RT_USING_DM */
#ifdef RT_USING_RTC
#include "drivers/dev_rtc.h"
#ifdef RT_USING_ALARM
#include "drivers/dev_alarm.h"
#endif /* RT_USING_ALARM */
#endif /* RT_USING_RTC */
#ifdef RT_USING_SPI
#include "drivers/dev_spi.h"
#endif /* RT_USING_SPI */
#ifdef RT_USING_MTD_NOR
#include "drivers/mtd_nor.h"
#endif /* RT_USING_MTD_NOR */
#ifdef RT_USING_MTD_NAND
#include "drivers/mtd_nand.h"
#endif /* RT_USING_MTD_NAND */
#ifdef RT_USING_USB_DEVICE
#include "drivers/usb_device.h"
#endif /* RT_USING_USB_DEVICE */
#ifdef RT_USING_USB_HOST
#include "drivers/usb_host.h"
#endif /* RT_USING_USB_HOST */
#ifdef RT_USING_SERIAL
#ifdef RT_USING_SERIAL_V2
#include "drivers/dev_serial_v2.h"
#else
#include "drivers/dev_serial.h"
#ifdef RT_USING_SERIAL_BYPASS
#include "drivers/serial_bypass.h"
#endif /* RT_USING_SERIAL_BYPASS */
#endif
#endif /* RT_USING_SERIAL */
#ifdef RT_USING_I2C
#include "drivers/dev_i2c.h"
#ifdef RT_USING_I2C_BITOPS
#include "drivers/dev_i2c_bit_ops.h"
#endif /* RT_USING_I2C_BITOPS */
#ifdef RT_USING_DM
#include "drivers/dev_i2c_dm.h"
#endif /* RT_USING_DM */
#endif /* RT_USING_I2C */
#ifdef RT_USING_PHY
#include "drivers/phy.h"
#endif /* RT_USING_PHY */
#ifdef RT_USING_SDIO
#include "drivers/dev_mmcsd_core.h"
#include "drivers/dev_sd.h"
#include "drivers/dev_sdio.h"
#endif /* RT_USING_SDIO */
#ifdef RT_USING_WDT
#include "drivers/dev_watchdog.h"
#endif /* RT_USING_WDT */
#ifdef RT_USING_PIN
#include "drivers/dev_pin.h"
#endif /* RT_USING_PIN */
#ifdef RT_USING_SENSOR
#ifdef RT_USING_SENSOR_V2
#include "drivers/sensor_v2.h"
#else
#include "drivers/sensor.h"
#endif /* RT_USING_SENSOR_V2 */
#endif /* RT_USING_SENSOR */
#ifdef RT_USING_CAN
#include "drivers/dev_can.h"
#endif /* RT_USING_CAN */
#ifdef RT_USING_HWTIMER
#include "drivers/hwtimer.h"
#endif /* RT_USING_HWTIMER */
#ifdef RT_USING_AUDIO
#include "drivers/dev_audio.h"
#endif /* RT_USING_AUDIO */
#ifdef RT_USING_CPUTIME
#include "drivers/cputime.h"
#endif /* RT_USING_CPUTIME */
#ifdef RT_USING_ADC
#include "drivers/adc.h"
#endif /* RT_USING_ADC */
#ifdef RT_USING_DAC
#include "drivers/dac.h"
#endif /* RT_USING_DAC */
#ifdef RT_USING_PWM
#include "drivers/dev_pwm.h"
#endif /* RT_USING_PWM */
#ifdef RT_USING_PM
#include "drivers/pm.h"
#endif /* RT_USING_PM */
#ifdef RT_USING_WIFI
#include "drivers/wlan.h"
#endif /* RT_USING_WIFI */
#ifdef MTD_USING_NOR
#include "drivers/mtdnor.h"
#endif /* MTD_USING_NOR */
#ifdef MTD_USING_NAND
#include "drivers/mtdnand.h"
#endif /* MTD_USING_NAND */
#ifdef RT_USING_HWCRYPTO
#include "drivers/crypto.h"
#endif /* RT_USING_HWCRYPTO */
#ifdef RT_USING_PULSE_ENCODER
#include "drivers/pulse_encoder.h"
#endif /* RT_USING_PULSE_ENCODER */
#ifdef RT_USING_INPUT_CAPTURE
#include "drivers/rt_inputcapture.h"
#endif /* RT_USING_INPUT_CAPTURE */
#ifdef RT_USING_TOUCH
#include "drivers/dev_touch.h"
#endif
#ifdef RT_USING_DEV_BUS
#include "drivers/rt_dev_bus.h"
#endif
#ifdef RT_USING_LCD
#include "drivers/lcd.h"
#endif
#ifdef RT_USING_CLK
#include "drivers/clk.h"
#endif /* RT_USING_CLK */
#ifdef __cplusplus
}
#endif
#endif /* __RT_DEVICE_H__ */