#include "includes.h" #include "Uart.h" //#include "bsp.h" //extern int rs485_send_flag; uart_info g_uart_info[UART_MAX]; uart_rcv_buf_t g_uart_rcv_buf; uart_config_struct g_uart_cfg[] = { {GPIOA, GPIO_PIN_10,GPIOA, GPIO_PIN_9, 0, USART0_IRQn, USART0, RCU_USART0, RCU_GPIOA, 0, 0}, {GPIOA, GPIO_PIN_3, GPIOA, GPIO_PIN_2, 0, USART1_IRQn, USART1, RCU_USART1, RCU_GPIOA, 0, 0}, {GPIOD, GPIO_PIN_9, GPIOD, GPIO_PIN_8, GPIO_USART2_FULL_REMAP, USART2_IRQn, USART2, RCU_USART2, RCU_GPIOD, RCU_AF, 0}, {GPIOC, GPIO_PIN_11,GPIOC, GPIO_PIN_10, 0, UART3_IRQn, UART3, RCU_UART3, RCU_GPIOC, RCU_AF, 0}, {GPIOD, GPIO_PIN_2, GPIOC, GPIO_PIN_12, 0, UART4_IRQn, UART4, RCU_UART4, RCU_GPIOC, RCU_GPIOD, RCU_AF}, }; int uart_msg_send(uint8_t uartid, const char *buf, uint32_t buflen); int fputc(int ch, FILE *f) { uint32_t uart_def = g_uart_cfg[UART_DEBUG].uart_def; usart_data_transmit(uart_def, (uint8_t)ch); while(RESET == usart_flag_get(uart_def, USART_FLAG_TC)); return ch; } void data_dump(const char *name, uint8_t *data, uint16_t length) { int index = 0; printf("%s Data Info: \r\n ", name); for(index = 0;index < length;index++) { if((index%4 == 0)&&index) { if((index%16 == 0)&&index) { printf("\r\n "); } else { printf(" "); } } printf("%02x ", *(data + index)); } printf("\r\n"); } void uart_init(uint8_t uartid, uint32_t baud, uint32_t wordlen, uint32_t parity) { uart_config_struct *p_uart = NULL; uint32_t USARTx; p_uart = &g_uart_cfg[uartid]; USARTx = p_uart->uart_def; if(p_uart->gpio_clk) rcu_periph_clock_enable((rcu_periph_enum)p_uart->gpio_clk); if(p_uart->gpio_clk1) rcu_periph_clock_enable((rcu_periph_enum)p_uart->gpio_clk1); if(p_uart->gpio_clk2) rcu_periph_clock_enable((rcu_periph_enum)p_uart->gpio_clk2); rcu_periph_clock_enable((rcu_periph_enum)p_uart->uart_clk); //USART1_TX GPIOA.9初始化 gpio_init(p_uart->tx_port, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, p_uart->tx_pin); //USART1_RX GPIOA.10初始化 gpio_init(p_uart->rx_port, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, p_uart->rx_pin); if(p_uart->remap) { gpio_pin_remap_config(p_uart->remap, ENABLE); } //USART 初始化设置 usart_deinit(USARTx); usart_word_length_set(USARTx, wordlen); usart_stop_bit_set(USARTx, USART_STB_1BIT); usart_parity_config(USARTx, parity); usart_baudrate_set(USARTx, baud); usart_receive_config(USARTx, USART_RECEIVE_ENABLE); usart_transmit_config(USARTx, USART_TRANSMIT_ENABLE); usart_enable(USARTx); // //Usart1 NVIC 配置 // nvic_irq_enable(p_uart->irq_no, 0, uartid); // // // 使能串口接收中断 // usart_interrupt_enable(USARTx, USART_INT_RBNE); } uint8_t uart_rcv_buf_wr_rd(uint8_t uartid, uint8_t wr_rd, uint8_t state, uint16_t index, uint8_t val) { uint8_t p_data = 0; if(state == P_BUF) { switch(uartid) { case UART1_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart1_buf[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart1_buf[index]; break; case UART2_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart2_buf[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart2_buf[index]; break; case UART3_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart3_buf[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart3_buf[index]; break; case UART4_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart4_buf[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart4_buf[index]; break; case UART5_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart5_buf[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart5_buf[index]; break; default: break; } } else if(state == P_DATA) { switch(uartid) { case UART1_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart1_pdata[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart1_pdata[index]; break; case UART2_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart2_pdata[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart2_pdata[index]; break; case UART3_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart3_pdata[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart3_pdata[index]; break; case UART4_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart4_pdata[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart4_pdata[index]; break; case UART5_ID: if(wr_rd == P_WRITE) g_uart_rcv_buf.uart5_pdata[index] = val; else if(wr_rd == P_READ) p_data = g_uart_rcv_buf.uart5_pdata[index]; break; default: break; } } return p_data; } /**************************************************************************** * --uart_interrupt() UART0中断服务程序。 * Input: * uid --串口编号 * pinfo --串口信息处理结构指针 *Output: * None *Return: * None */ void uart_interrupt(uint8_t uartid) { uint16_t index = 0; uint8_t val =0; uart_info *pinfo = NULL; uart_config_struct *p_uart = NULL; uint32_t USARTx = NULL; pinfo = &g_uart_info[uartid]; p_uart = &g_uart_cfg[uartid]; USARTx = p_uart->uart_def; if(RESET != usart_interrupt_flag_get(USARTx, USART_INT_FLAG_RBNE)) { val = (uint8_t)usart_data_receive(USARTx); usart_interrupt_flag_clear(USARTx,USART_INT_FLAG_ERR_FERR); pinfo->USART_ReceiveTimeCounter = USART_RECEIVE_OVERTIME;//接收计时 pinfo->Rcv_Over = 0;//接收标志 if(!pinfo->rinfo.flag.bufof) {/*如果接收缓冲没有溢出*/ index = pinfo->rinfo.rtbuf.pinput; // pinfo->rinfo.rtbuf.buf[index] = val; uart_rcv_buf_wr_rd(uartid,P_WRITE,P_BUF,index,val);////////// index = (index+1) % (pinfo->rinfo.rproc.datalen);/*以datalen为模加index*/ if(index == pinfo->rinfo.rtbuf.poutput) {/*接收的速度大于处理的速度了*/ pinfo->rinfo.flag.bufof = ENABLE;/*溢出了*/ } else { pinfo->rinfo.rtbuf.pinput = index;/*更新输入指针长度*/ } } } return; } /************************************************ 函数名称 : USART_ReceiveOvertimeProcess 功 能 : 串口超时接收 参 数 : 返 回 值 : 无 作 者 : sun *************************************************/ void USART_ReceiveOvertimeProcess(void) { uint16_t i = 0; for(i = 0; i < 5; i++) { if(g_uart_info[i].USART_ReceiveTimeCounter >= SYSTEMTICK_PERIOD_MS) { g_uart_info[i].Rcv_Over = 0; g_uart_info[i].USART_ReceiveTimeCounter -= SYSTEMTICK_PERIOD_MS; if(g_uart_info[i].USART_ReceiveTimeCounter < SYSTEMTICK_PERIOD_MS) { g_uart_info[i].Rcv_Over = 1; } } } } /****************************************************************************************** *uart_rs232_init --串口初始化函数 *-- *Input: * prt --协议类型 * rcv --信息接收函数 *Output: * 无 *Return: * OK/ERROR 表示执行成功与否 * */ int uart_rs232_init(uint8_t uartid, uart_rcv_func rcv) { uart_info *pinfo = NULL; uart_config_struct *p_uart = NULL; pinfo = &g_uart_info[uartid]; p_uart = &g_uart_cfg[uartid]; /*清数据结构*/ memset(pinfo, 0, sizeof(uart_info)); /*记录接收报文处理函数*/ pinfo->rinfo.rproc.rcv = rcv; /*lint -save -e611*/ pinfo->uartid = uartid; pinfo->arg = (void *)p_uart->uart_def; /*lint -restore*/ /*接收和发送指针执行相应的缓冲区*/ //pinfo->rinfo.rproc.pdata = p_rx_data; if(uartid == UART_4G) { pinfo->rinfo.rproc.datalen = UART_RCV_LEN_BIG; } else { pinfo->rinfo.rproc.datalen = UART_RCV_LEN_SMALL; } // pinfo->rinfo.rproc.datalen = UART_RCV_TEMPBUF_LEN; //pinfo->sinfo.pdata = p_tx_data; // pinfo->sinfo.datalen = 1024; //trace_otp_trace1(uart_msg_send, uartid, "My Friends, Uart%d!!!\n", uartid+1); return 0; } //u8 uart_msg_send_disable(u8 uartid) //{ // uart_info *pinfo = NULL; // pinfo = &g_uart_info[uartid]; // return (pinfo->sinfo.poutput != pinfo->sinfo.pinput); //} /**********************************************************/ uint32_t uart_choice(uint8_t uartid) { uint32_t USARTx = 0; switch(uartid) { case UART1_ID: USARTx = USART0; break; case UART2_ID: USARTx = USART1; break; case UART3_ID: USARTx = USART2; break; case UART4_ID: USARTx = UART3; break; case UART5_ID: USARTx = UART4; break; default: break; } return USARTx; } /**********************************************************/ /******************************************************************************* *uart1_msg_send 发送报文处理 *Input: * buf --需要发送的数据指针 * buflen --发送的数据长度 *Output: * None *Return: * OK/ERROR,表示执行成功和失败 */ int uart_msg_send(uint8_t uartid, const char *buf, uint32_t buflen) { // uint32_t t = 0; uint32_t USARTx; if(uartid > UART5_ID) return -1; USARTx = uart_choice(uartid); while(buflen--) { usart_data_transmit(USARTx, *buf); // 发送一个字节数据 while(RESET == usart_flag_get(USARTx, USART_FLAG_TBE)); // 发送完成判断 buf++; } return 0; } /******************************************************************************* *uart_rcv_process 接收报文处理,按照相应的协议,对接收缓冲区的报文进行处理,并调用 * 注册的rcv处理函数; *Input: * prt --报文处理使用的协议,根据协议类型进行报文接收; * prinfo --接收缓冲区相关信息指针; *Output: * None *Return: * OK/ERROR,表示执行成功和失败 */ int uart_rcv_process(uint8_t uartid) { uint8_t val = 0; uint32_t index = 0; uint32_t ucnt = 0; uart_info *pinfo = NULL; // uart_config_struct *p_uart = NULL; uart_rcv_info *prinfo = NULL; pinfo = &g_uart_info[uartid]; // p_uart = &g_uart_cfg[uartid]; prinfo = &pinfo->rinfo; /*参数检查*/ if(prinfo == NULL) { return -1; } // if(pinfo->Rcv_Over==0)//串口数据未接收完 // return -1; // else // pinfo->Rcv_Over = 0; /*20090828modify,szb*/ if(prinfo->flag.bufof==TRUE) { prinfo->flag.bufof=FALSE; prinfo->rtbuf.poutput = prinfo->rtbuf.pinput; prinfo->rproc.outcnt = 0; } /*看看接收暂存缓冲区当前有没有数据可以接收*/ if(prinfo->rtbuf.poutput == prinfo->rtbuf.pinput) {/*没有新数据*/ return 0; } /*记录接收暂存缓冲区开始处理的位置*/ index = prinfo->rtbuf.poutput; ucnt = prinfo->rproc.outcnt; /*处理已经接收完毕但是还没有处理的报文内容*/ while(index != prinfo->rtbuf.pinput) { /*获取接收缓冲区的内容*/ // val = prinfo->rtbuf.buf[index]; // prinfo->rproc.pdata[ucnt] = val; val = uart_rcv_buf_wr_rd(uartid,P_READ,P_BUF,index,0); uart_rcv_buf_wr_rd(uartid,P_WRITE,P_DATA,ucnt,val); /*处理下一个字符*/ index = (index+1) % (pinfo->rinfo.rproc.datalen); ucnt = (ucnt+1) % (pinfo->rinfo.rproc.datalen); } // if(prinfo->rproc.rcv) {/* 注册接收函数 */ // prinfo->rproc.rcv(pinfo->uartid, pinfo->arg, prinfo->rproc.pdata, ucnt, NULL); // ucnt = 0; // } /*更新输出起始指针*/ prinfo->rtbuf.poutput = index; prinfo->rproc.outcnt = ucnt; return 0; } int uart_blocking_read(char *buffer, uint8_t uartid, uint32_t timeout) { // OS_ERR err; uart_info *pinfo = NULL; // uart_config_struct *p_uart = NULL; uart_rcv_info *prinfo = NULL; int ret = 1; pinfo = &g_uart_info[uartid]; // p_uart = &g_uart_cfg[uartid]; prinfo = &pinfo->rinfo; // uart_rcv_wait(uartid,timeout); // while(timeout--) { // OSTimeDlyHMSM(0, 0, 0, 1, OS_OPT_TIME_DLY, &err); // } if(prinfo->rproc.outcnt) { // memcpy(buffer, prinfo->rproc.pdata, prinfo->rproc.outcnt); if(uartid == UART1_ID) memcpy(buffer, g_uart_rcv_buf.uart1_pdata, prinfo->rproc.outcnt); else if(uartid == UART2_ID) memcpy(buffer, g_uart_rcv_buf.uart2_pdata, prinfo->rproc.outcnt); else if(uartid == UART3_ID) memcpy(buffer, g_uart_rcv_buf.uart3_pdata, prinfo->rproc.outcnt); else if(uartid == UART4_ID) memcpy(buffer, g_uart_rcv_buf.uart4_pdata, prinfo->rproc.outcnt); else if(uartid == UART5_ID) memcpy(buffer, g_uart_rcv_buf.uart5_pdata, prinfo->rproc.outcnt); ret = prinfo->rproc.outcnt; prinfo->rproc.outcnt = 0; } else { ret = 0; } return ret; } /***************************************************************************** ** Function name: USART1_IRQHandler ** ** Descriptions: UART1 interrupt handler ** ** parameters: None ** Returned value: None ** *****************************************************************************/ void USART0_IRQHandler(void) { uart_interrupt(UART1_ID); } void USART1_IRQHandler(void) { uart_interrupt(UART2_ID); } void USART2_IRQHandler(void) { uart_interrupt(UART3_ID); } void UART3_IRQHandler(void) { uart_interrupt(UART4_ID); } void UART4_IRQHandler(void) { uart_interrupt(UART5_ID); } //void uart_rcv_wait(uint8_t uartid, uint32_t timeout) //{ // OS_ERR err; // while(g_uart_info[uartid].Rcv_Over==0 && timeout) { // timeout--; // OSTimeDlyHMSM(0, 0, 0, 1, OS_OPT_TIME_DLY, &err); // } //// g_uart_info[uartid].Rcv_Over=0; //} uint32_t uart_blocking_read_over(char *buffer, uint8_t uartid, uint32_t timeout) { uint32_t uart_len=0,uart_len_temp=0; uart_len = uart_blocking_read(buffer,uartid,1); if(uart_len) { while(timeout && g_uart_info[uartid].Rcv_Over==0) { timeout--; uart_len_temp = uart_blocking_read(buffer+uart_len,uartid,1); uart_len += uart_len_temp; } } return uart_len; }