#ifndef RTE_GPIO_H__ #define RTE_GPIO_H__ #include "stdint.h" #include "GPIO\RTE_GPIO_BAT32A239.h" /**@enum RTE_GPIO_Level_en_t * @brief GPIO端口的电平 \n */ #define RTE_GPIO_LEVEL_LOW (0x00U) /**< 低电平 */ #define RTE_GPIO_LEVEL_HIGH (0x01U) /**< 高电平 */ /**@enum RTE_GPIO_Dir_en_t * @brief GPIO端口的输入输出方向 \n */ #define RTE_GPIO_DIR_IN (0x00U) /**< 输入 */ #define RTE_GPIO_DIR_OUT (0x80U) /**< 输出 */ /******************************************************************************* * GPIO 的输入工作模式定义 * ======================================================================= * bit 8 | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 * -------+-------+-------+-------+-------+-------+-------+-------+------- * DIR | - | - | - | TYPE | - | - | PULL UP/DN * ======================================================================= * - 其中DIR须为 RTE_GPIO_DIR_IN *******************************************************************************/ /**@enum RTE_GPIO_Pull_en_t * @brief GPIO端口的上下拉 \n */ #define RTE_GPIO_PULL_NONE (0x00U) /**< 无上/下拉 */ #define RTE_GPIO_PULL_DOWN (0x01U) /**< 下拉 */ #define RTE_GPIO_PULL_UP (0x02U) /**< 上拉 */ #define RTE_GPIO_PULL_BOTH (0x03U) /**< 上下拉同时存在(拉至1/2VCC),慎用 */ /**@enum RTE_GPIO_Input_Type_en_t * @brief GPIO端口的输入类型 \n */ #define RTE_GPIO_INPUT_CMOS (0x00U) /**< COMS电平输入 */ #define RTE_GPIO_INPUT_TTL (0x10U) /**< TTL电平输入 */ /******************************************************************************* * GPIO 的输出工作模式定义 * ======================================================================= * bit 8 | bit 7 | bit 6 | bit 5 | bit 4 | bit 3 | bit 2 | bit 1 | bit 0 * -------+-------+-------+-------+-------+-------+-------+-------+------- * DIR | Rsvd. | Rsvd. | Rsvd. | TYPE | SPEED | LEVEL * ======================================================================= * - 其中DIR须为 RTE_GPIO_DIR_OUT * - 其中LEVEL为输出电平 RTE_GPIO_LEVEL_LOW 或 RTE_GPIO_LEVEL_HIGH *******************************************************************************/ /**@enum RTE_GPIO_Output_Type_en_t * @brief GPIO端口的输出类型 \n */ #define RTE_GPIO_OUTPUT_PP (0x00U) /**< Push-Pull推挽输出 */ #define RTE_GPIO_OUTPUT_OD (0x10U) /**< Open Drain开漏输出 */ /**@enum RTE_GPIO_Output_Speed_en_t * @brief GPIO端口的输出速度 \n */ #define RTE_GPIO_SPEED_HIGH (0x00U) /**< 输出最高速度 */ #define RTE_GPIO_SPEED_0 (0x00U) /**< 输出速度等级0 (最高) */ #define RTE_GPIO_SPEED_1 (0x02U) /**< 输出速度等级1 */ #define RTE_GPIO_SPEED_2 (0x04U) /**< 输出速度等级2 */ #define RTE_GPIO_SPEED_3 (0x06U) /**< 输出速度等级3 */ #define RTE_GPIO_SPEED_4 (0x08U) /**< 输出速度等级4 */ #define RTE_GPIO_SPEED_5 (0x0AU) /**< 输出速度等级5 */ #define RTE_GPIO_SPEED_6 (0x0CU) /**< 输出速度等级6 */ #define RTE_GPIO_SPEED_7 (0x0EU) /**< 输出速度等级7 (最低) */ #define RTE_GPIO_SPEED_LOW (0x0EU) /**< 输出最低速度 */ /******************************************************************************* * RTE_GPIO_Init 函数和 RTE_GPIO_Config 函数的参数中的GPIO工作模式由多个字段组合而成 * * 当GPIO被配置成输入模式时,GPIO工作模式应当依照输入模式下定义的字段组合而成,例如: * u8Mode = RTE_GPIO_DIR_IN | RTE_GPIO_PULL_UP | RTE_GPIO_INPUT_CMOS * * 当GPIO被配置成输出模式时,GPIO工作模式应当依照输出模式下定义的字段组合而成,例如: * u8Mode = RTE_GPIO_DIR_OUT | RTE_GPIO_OUTPUT_PP | RTE_GPIO_LEVEL_HIGH * *******************************************************************************/ /**@enum RTE_GPIO_Input_Type_en_t * @brief GPIO工作模式掩码 \n */ #define RTE_GPIO_DIR_MASK (0x80U) /**< 输入输出方向掩码 bit 7 */ #define RTE_GPIO_PULL_MASK (0x03U) /**< 上/下拉掩码 bit 0 - bit 1 */ #define RTE_GPIO_INPUT_TYPE_MASK (0x10U) /**< 输入类型掩码 bit 4 */ #define RTE_GPIO_LEVEL_MASK (0x01U) /**< 输出电平掩码 bit 0 */ #define RTE_GPIO_SPEED_MASK (0x0EU) /**< 输出速度掩码 bit 1 - bit 3 */ #define RTE_GPIO_OUTPUT_TYPE_MASK (0x10U) /**< 输出类型掩码 bit 4 */ #define RTE_GPIO_INT_EDGE_MODE_MASK (0x04U) /**< 边沿中断模式掩码 bit 2 */ /**@enum RTE_GPIO_Interrupt_Type_en_t * @brief GPIO端口的中断类型 \n */ typedef enum { RTE_GPIO_INT_LOW_LEVEL = 0x00U, /**< 低电平中断 */ RTE_GPIO_INT_HIGH_LEVEL = 0x01U, /**< 高电平中断 */ RTE_GPIO_INT_FALLING_EDGE = 0x04U, /**< 下降沿中断 */ RTE_GPIO_INT_RISING_EDGE = 0x05U, /**< 上升沿中断 */ RTE_GPIO_INT_DUAL_EDGE = 0x06U, /**< 双沿中断 */ }RTE_GPIO_Interrupt_Type_en_t; /**@type RTE_GPIO_Int_Handler_Func_ptr_t * @brief GPIO端口的中断服务回调函数 \n * @param[in] u16Pin 发生中断的端口编号 * @param[in] u8Level 发生中断时端口的电平, 0为低电平, 1为高电平 */ typedef void (*RTE_GPIO_Int_Handler_Func_ptr_t) (uint16_t u16Pin, uint8_t u8Level); /**@enum RTE_GPIO_Mode_en_t * @brief GPIO端口的工作模式 \n */ typedef enum { RTE_GPIO_MODE_INPUT_CMOS = 0x00U, /**< CMOS电平悬空输入 */ RTE_GPIO_MODE_INPUT_CMOS_PD = 0x01U, /**< CMOS电平下拉输入 */ RTE_GPIO_MODE_INPUT_CMOS_PU = 0x02U, /**< CMOS电平上拉输入 */ RTE_GPIO_MODE_INPUT_TTL = 0x04U, /**< TTL电平悬空输入 */ RTE_GPIO_MODE_INPUT_TTL_PD = 0x05U, /**< TTL电平下拉输入 */ RTE_GPIO_MODE_INPUT_TTL_PU = 0x06U, /**< TTL电平上拉输入 */ RTE_GPIO_MODE_OUTPUT_PP_LOW = 0x40U, /**< 推挽输出低电平 */ RTE_GPIO_MODE_OUTPUT_PP_HIGH = 0x41U, /**< 推挽输出高电平 */ RTE_GPIO_MODE_OUTPUT_OD_LOW = 0x42U, /**< 开漏输出低电平 */ RTE_GPIO_MODE_OUTPUT_OD_HIGH = 0x43U, /**< 开漏输出高电平 */ RTE_GPIO_MODE_INVALID = 0xFFU, /**< 无效的GPIO模式 */ }RTE_GPIO_Mode_en_t; /**@struct RTE_GPIO_Config_st_t * @brief GPIO端口的配置结构 \n */ typedef struct { uint16_t u16PinNum; /**< GPIO端口编号(RTE_GPIO_PORTxx_PINyy) */ uint16_t u16PinMode; /**< GPIO工作模式 */ }RTE_GPIO_Config_st_t; /****************************************************************************** * GPIO控制函数 ******************************************************************************/ extern void RTE_GPIO_Init(void); extern void RTE_GPIO_DeInit(void); extern int32_t RTE_GPIO_Config(uint16_t u16Pin, uint8_t u8Mode); extern int32_t RTE_GPIO_Bulk_Config(RTE_GPIO_Config_st_t *pstGPIOPinList, uint32_t u32Num); extern int32_t RTE_GPIO_Set_Level(uint16_t u16Pin, uint8_t u8Level); extern uint8_t RTE_GPIO_Get_Level(uint16_t u16Pin); extern int32_t RTE_GPIO_Set_Port(uint8_t u8Port, uint32_t u32Value); extern uint32_t RTE_GPIO_Get_Port(uint8_t u8Port); /******************************************************************************* * GPIO中断函数 * * GPIO所有的中断操作都是基于中断描述符的 * 由于不同芯片的GPIO结构存在差异, GPIO中断描述符在芯片各自的GPIO头文件中定义 * GPIO中断描述符中的参数必须使用RTE_GPIO_Interrupt_Register设置, 禁止直接修改 * * 使用GPIO中断的步骤: * 1. 使用RTE_GPIO_IRQ_Desc_st_t声明中断描述符, 生命周期为长期有效(全局/静态变量) * 每一个中断需要有唯一的中断描述符, 需要使用多少中断, 就声明多少个描述符 * 2. 初始化GPIO * 3. 使用RTE_GPIO_Config将中断引脚配置为输入 * 4. 使用RTE_GPIO_Interrupt_Register将中断引脚注册到其对应的中断描述符 * 5. 使用RTE_GPIO_Interrupt_Enable使能中断 * 6. 在中断系统中开启对应的外设中断 * 7. 使用中断功能, 可以通过RTE_GPIO_Get_Interrupt_Flag获取中断标志, 也可以直接使用 * 注册的中断回调函数 * 8. 在不需要使用GPIO中断时,可能通过RTE_GPIO_Interrupt_Disable将其禁用 *******************************************************************************/ extern int32_t RTE_GPIO_Interrupt_Register(RTE_GPIO_IRQ_Desc_st_t *pstIRQDesc, uint16_t u16Pin, RTE_GPIO_Interrupt_Type_en_t enType, RTE_GPIO_Int_Handler_Func_ptr_t pfnHandler); extern int32_t RTE_GPIO_Interrupt_Enable(RTE_GPIO_IRQ_Desc_st_t *pstIRQDesc); extern int32_t RTE_GPIO_Interrupt_Disable(RTE_GPIO_IRQ_Desc_st_t *pstIRQDesc); extern int32_t RTE_GPIO_Get_Interrupt_Flag(RTE_GPIO_IRQ_Desc_st_t *pstIRQDesc); extern int32_t RTE_GPIO_Clear_Interrupt_Flag(RTE_GPIO_IRQ_Desc_st_t *pstIRQDesc); #endif /* RTE_GPIO_H__ */