📄 at91sio.c
字号:
status = UART_GET_CSR(port); pending = status& pChan->read_status_mask;/*& port->read_status_mask;*/ if (pending) { do { if (pending & AT91C_US_RXRDY) { ch = UART_GET_CHAR(port); /* Call callback routine. */ (*pChan->putRcvChar)(pChan->putRcvArg, ch); } /* Clear the relevent break bits */ if (pending & AT91C_US_RXBRK) { UART_PUT_CR(port, AT91C_US_RSTSTA); /*port->icount.brk++;*/ } if (pending & (AT91C_US_TXRDY|AT91C_US_TXEMPTY) ) { if ((*pChan->getTxChar)(pChan->getTxArg, &ch) != ERROR) { /* Write char to Transmit Data Register. */ UART_PUT_CHAR (port , ch); } else { /* Disable Transmit Holding Register Empty Interrupt. */ UART_PUT_IDR(port, AT91C_US_TXRDY|AT91C_US_TXEMPTY ); /*pChan->read_status_mask &= ~(AT91C_US_TXRDY|AT91C_US_TXEMPTY);*/ AT91_SYS->AIC_ICCR = (1<<pChan->intLvl); /*UART_PUT_CR(port, AT91C_US_TXDIS );*/ break; } } status = UART_GET_CSR(port); pending = status&(pChan->read_status_mask);/* & port->read_status_mask;*/ } while (pending); }}/******************************************************************************** at91SioBaudSet - set the baud rates** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioBaudSet( AT91_SIO_CHAN *pChan, /* device to control */ int baudRate /* baud rate */ ){#if 0 int cnt; if (pChan->ch != 0) /* high-speed UART */ { if (baudRate == 0) /* hangup request */ { return (at91SioHup(pChan)); } } /* Calculate the baud rate. */ cnt = (UART_BRGCLK_FREQ / (baudRate * 16 * (1 << (UART_BRGCLK_DIV_FACTOR * 4)))) - 1; /* Baudrate divisor must fit in a 12-bit register. */ if ((cnt < 0) || (cnt > 0xFFF)) { return EIO; } /* Write to the Baud Rate Divisor Register. */ *AT91_UBRD(pChan->ch) = (UINT16)((cnt << AT91_UBRD_CNT_SHIFT) | UART_BRGCLK_DIV_FACTOR);#endif unsigned long flags; unsigned int mode, imr; AT91PS_USART port =(AT91PS_USART) (pChan->base); /* Get current mode register */ mode = port->US_MR & ~(AT91C_US_CHRL | AT91C_US_NBSTOP | AT91C_US_PAR); /* first, disable interrupts and drain transmitter *//* local_irq_save(flags);*/ imr = UART_GET_IMR(port); /* get interrupt mask */ UART_PUT_IDR(port, -1); /* disable all interrupts *//* local_irq_restore(flags);*/ /*while (!(UART_GET_CSR(port) & AT91C_US_TXEMPTY)) { barrier(); }*/ /* disable receiver and transmitter */ UART_PUT_CR(port, AT91C_US_TXDIS | AT91C_US_RXDIS); /* set the baud rate */ UART_PUT_BRGR(port,AT91F_US_Baudrate(AT91C_MASTER_CLOCK ,baudRate) ); UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN); /* restore interrupts */ UART_PUT_IER(port, imr); pChan->baudRate = baudRate; return OK;}/******************************************************************************** at91SioOptsSet - set the serial options** Set the channel operating mode to that specified. All sioLib options are* supported: CLOCAL, HUPCL, CREAD, CSIZE, PARENB, and PARODD.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioOptsSet( AT91_SIO_CHAN *pChan, /* device to control */ int options /* options */ ){#if 0 UINT32 ucon; /* Set default bits for UART Control Register. */ ucon = AT91_UCON_RMODE_CPU | /* CPU Request */ AT91_UCON_TMODE_CPU | /* CPU Request */#ifdef UARTCLK_EXTERNAL AT91_UCON_SCSEL_UCLK; /* External */#else /* UARTCLK_EXTERNAL */ AT91_UCON_SCSEL_PCLK2; /* Internal (PCLK2 = PCLK / 2) */#endif /* UARTCLK_EXTERNAL */ /* Set character size. */ switch (options & CSIZE) { case CS5: ucon |= AT91_UCON_WL_5; /* 5 Bits */ break; case CS6: ucon |= AT91_UCON_WL_6; /* 6 Bits */ break; case CS7: ucon |= AT91_UCON_WL_7; /* 7 Bits */ break; case CS8: ucon |= AT91_UCON_WL_8; /* 8 Bits */ break; } /* Set stop bits. */ if (!(options & STOPB)) /* send two stop bits (else one) */ { ucon |= AT91_UCON_STB_1; /* One Stop Bit per Frame */ } else { ucon |= AT91_UCON_STB_2; /* Two Stop Bit per Frame */ } /* Set parity. */ if (!(options & PARENB)) /* parity detection enabled (else disabled) */ { ucon |= AT91_UCON_PMD_NO; /* No Parity */ } else { if (options & PARODD) /* odd parity (else even) */ { ucon |= AT91_UCON_PMD_ODD; /* Odd Parity */ } else { ucon |= AT91_UCON_PMD_EVEN; /* Even Parity */ } } if (pChan->ch != 0) /* high-speed UART. */ { ucon |= AT91_HUCON_RFTL_28 | /* Receive FIFO Trigger Level */ AT91_HUCON_TFTL_16 | /* Transmit FIFO Trigger Level */ AT91_HUCON_RFEN | /* Receive FIFO Enable */ AT91_HUCON_TFEN; /* Transmit FIFO Enable */ if (!(options & CLOCAL)) /* ignore modem status lines */ { ucon |= AT91_HUCON_HFEN | /* Hardware Flow Control Enable */ AT91_HUCON_RTSRTR_RTS | /* RTS/RTR Selection */ AT91_HUCON_DTR; /* Data Terminal Ready to Pin */ } } /* Write UART Control Register. */ *AT91_UCON(pChan->ch) = ucon;#endif unsigned long flags; unsigned int mode, imr; AT91PS_USART port =(AT91PS_USART) (pChan->base); /* Get current mode register */ mode = port->US_MR & ~(AT91C_US_CHRL | AT91C_US_NBSTOP | AT91C_US_PAR); /* byte size */ switch (options & CSIZE) { case CS5: mode |= AT91C_US_CHRL_5_BITS; break; case CS6: mode |= AT91C_US_CHRL_6_BITS; break; case CS7: mode |= AT91C_US_CHRL_7_BITS; break; default: mode |= AT91C_US_CHRL_8_BITS; break; } /* stop bits */ if (options & STOPB) mode |= AT91C_US_NBSTOP_2_BIT; /* parity */ if (options & PARENB) { if (options & PARENB) { /* Mark or Space parity */ if (options & PARODD) mode |= AT91C_US_PAR_MARK; else mode |= AT91C_US_PAR_SPACE; } else if (options & PARODD) mode |= AT91C_US_PAR_ODD; else mode |= AT91C_US_PAR_EVEN; } else mode |= AT91C_US_PAR_NONE; /* TODO: Ignore all characters if CREAD is set.*/ /* first, disable interrupts and drain transmitter */ /*local_irq_save(flags);*/ imr = UART_GET_IMR(port); /* get interrupt mask */ UART_PUT_IDR(port, -1); /* disable all interrupts */ /*local_irq_restore(flags);*/ /*while (!(UART_GET_CSR(port) & AT91C_US_TXEMPTY)) { barrier(); }*/ /* disable receiver and transmitter */ UART_PUT_CR(port, AT91C_US_TXDIS | AT91C_US_RXDIS); /* set the parity, stop bits and data size */ UART_PUT_MR(port, mode); /* set the baud rate *//* UART_PUT_BRGR(port, quot);*/ UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN); /* restore interrupts */ UART_PUT_IER(port, imr); /* CTS flow-control and modem-status interrupts */ /*if (UART_ENABLE_MS(port, cflag))*/ /* at91_pops.enable_ms(port);*/ pChan->options = options; return OK;}/******************************************************************************** at91SioModeSet - set the channel's SIO mode** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioModeSet( AT91_SIO_CHAN *pChan, /* device to control */ int sioMode /* SIO mode */ ){ AT91PS_USART uart =(AT91PS_USART) (pChan->base); if ((sioMode != SIO_MODE_POLL) && (sioMode != SIO_MODE_INT)) { return EIO; } if (sioMode == SIO_MODE_INT) /* interrupt mode */ { uart->US_IDR = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_ENDRX | AT91C_US_ENDTX | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_TXEMPTY | AT91C_US_TXBUFE | AT91C_US_RXBUFF | AT91C_US_COMM_TX | AT91C_US_COMM_RX | AT91C_US_TIMEOUT ; uart->US_IER = AT91C_US_RXRDY | AT91C_US_TXRDY|AT91C_US_TXRDY /* | AT91C_US_ENDRX | AT91C_US_ENDTX | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_TXEMPTY | AT91C_US_TXBUFE | AT91C_US_RXBUFF | AT91C_US_COMM_TX | AT91C_US_COMM_RX */; } else /* polling mode */ { /* uart->US_IER = AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE ; */ uart->US_IDR = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_ENDRX | AT91C_US_ENDTX | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_TXEMPTY | AT91C_US_TXBUFE | AT91C_US_RXBUFF | AT91C_US_COMM_TX | AT91C_US_COMM_RX | AT91C_US_TIMEOUT ; } pChan->sioMode = sioMode; return OK;}/******************************************************************************** at91SioOpen - set the modem control lines ** Set the modem control lines(RTS, DTR) TRUE if not already set.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioOpen( AT91_SIO_CHAN *pChan /* device to control */ ){ AT91PS_USART uart =(AT91PS_USART) (pChan->base); if (pChan->base == (void*) AT91C_BASE_DBGU ) /* console UART */ { return ENOSYS; } if (!(pChan->options & HUPCL)) /* hang up on last close */ { return ENOSYS; } if (pChan->options & CLOCAL) /* ignore modem status lines */ { return ENOSYS; } /* Asserts DTR. */ uart->US_CR |=AT91C_US_DTREN; /* Data Terminal Ready to Pin */ return OK;}/******************************************************************************** at91SioHup - hang up the modem control lines ** Resets the RTS and DTR signals.** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioHup( AT91_SIO_CHAN *pChan /* device to control */ ){ AT91PS_USART uart =(AT91PS_USART) (pChan->base); if (uart == AT91C_BASE_DBGU) /* console UART */ { return ENOSYS; } if (!(pChan->options & HUPCL)) /* hang up on last close */ { return ENOSYS; } if (pChan->options & CLOCAL) /* ignore modem status lines */ { return ENOSYS; } /* Deasserts DTR. */ uart->US_CR &=~AT91C_US_DTREN; /* Data Terminal Ready to Pin */ return OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -