#ifndef _UART_DEV_H_ #define _UART_DEV_H_ #include "typedef.h" #include "os/os_api.h" #include "jiffies.h" #include "irq.h" /* #include "jtime.h" */ #define CONFIG_ENABLE_UART_SEM 1 #define SET_INTERRUPT ___interrupt #define irq_disable(x) bit_clr_ie(x) #define irq_enable(x) bit_set_ie(x) #ifndef time_after #define time_after(a,b) (((long)(b) - (long)(a)) < 0) #endif #ifndef time_before #define time_before(a,b) time_after(b,a) #endif #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif static inline u32 ut_get_jiffies(void) { #if 1 return jiffies; #endif #if 0 return Jtime_updata_jiffies(); #endif } static inline u32 ut_msecs_to_jiffies(u32 msecs) { if (msecs >= 10) { msecs /= 10; } else if (msecs) { msecs = 1; } return msecs; } #if CONFIG_ENABLE_UART_SEM typedef OS_SEM UT_Semaphore ; static inline void UT_OSSemCreate(UT_Semaphore *sem, u32 count) { os_sem_create(sem, count); } static inline void UT_OSSemPost(UT_Semaphore *sem) { os_sem_post(sem); } static inline u32 UT_OSSemPend(UT_Semaphore *sem, u32 timeout) { return os_sem_pend(sem, timeout); } static inline void UT_OSSemSet(UT_Semaphore *sem, u32 count) { os_sem_set(sem, count); } static inline void UT_OSSemClose(UT_Semaphore *sem) { } static inline void ut_sleep() { os_time_dly(1); } #else typedef volatile u32 UT_Semaphore; static inline void UT_OSSemCreate(UT_Semaphore *sem, u32 count) { *sem = count; } static inline void UT_OSSemPost(UT_Semaphore *sem) { (*sem)++; } static inline u32 UT_OSSemPend(UT_Semaphore *sem, u32 timeout) { u32 _timeout = timeout + ut_get_jiffies(); extern void clr_wdt(); while (1) { if (*sem) { (*sem) --; break; } if ((timeout != 0) && time_before(_timeout, ut_get_jiffies())) { return -1; } clr_wdt(); } return 0; } static inline void UT_OSSemSet(UT_Semaphore *sem, u32 count) { *sem = count; } static inline void UT_OSSemClose(UT_Semaphore *sem) { } static inline void ut_sleep() { extern void clr_wdt(); clr_wdt(); } #endif typedef void (*ut_isr_cbfun)(void *ut_bus, u32 status); struct uart_platform_data_t { u8 tx_pin; ///< 作为发送引脚的引脚号,可从参考gpio.h枚举中选,当引脚为空时,则填 -1 u8 rx_pin; ///< 作为接收引脚的引脚号,可从参考gpio.h枚举中选,当引脚为空时,则填 -1 void *rx_cbuf; ///< 如果使用中断DMA接收,则写入循环buf的首地址,ut中断使能;如果不使用,则写入NULL,无中断 u32 rx_cbuf_size; ///< 循环buf的大小,必须为2的多少几次幂,如果不用循环buf,该值无效,可写NULL u32 frame_length; ///< 产生RT中断的字节数,如无中断,该值无效 u32 rx_timeout; ///< 产生OT中断的时间值,单位ms,如无中断,该值无效 ut_isr_cbfun isr_cbfun; ///< ut中断的回调函数句柄,不用回调函数则写入NULL,如无中断,句柄无效 void *argv; ///< ut中断的回调函数的一个扩展形参,可供用户设定,如无回调函数,此参数无效 u32 is_9bit: 1; ///< ut九位模式使能位,0:关闭;1:使能 u32 baud: 24; ///< ut的波特率 }; /** * @brief 循环buf结构体类型定义 */ typedef struct { u8 *buffer; ///<循环buf的首地址 u32 buf_size; ///<循环buf的大小 u32 buf_in; ///<循环buf的写偏移量 u32 buf_out; ///<循环buf的读偏移量 } KFIFO; enum { UT_TX = 1, UT_RX, UT_RX_OT }; /** * @brief ut初始化函数的返回结构体,含各函数指针,供外部使用 */ typedef struct { ut_isr_cbfun isr_cbfun; ///< ut中断的回调函数句柄,不用回调函数则写入NULL,如无中断,句柄无效 void *argv; ///< ut中断的回调函数的一个扩展形参,在此返回 void (*putbyte)(char a); ///< ut发送一个byte u8(*getbyte)(u8 *buf, u32 timeout); ///< ut接收一个byte,buf:字节存放地址;timeout:超时时间,单位ms;返回0:失败;返回1:成功 u32(*read)(u8 *inbuf, u32 len, u32 timeout); ///< ut接收一个字符串,inbuf:字符串存放首地址;len:预接收长度;timeout:超时时间,单位ms;返回实际接收的长度 void (*write)(const u8 *outbuf, u32 len); ///< ut发送一个字符串,outbuf:字符串首地址;len:发送的字符串长度; void (*set_baud)(u32 baud); ///< ut设置波特率,baud:波特率值 u32 frame_length; u32 rx_timeout; KFIFO kfifo; ///< ut用的循环buf结构体的指针 UT_Semaphore sem_rx; UT_Semaphore sem_tx; } uart_bus_t; const uart_bus_t *uart_dev_open(const struct uart_platform_data_t *arg); u32 uart_dev_close(uart_bus_t *ut); //////////////////////////////////////////////////////////////////////////////// #endif