📄 at91sio.c
字号:
AT91_SIO_CHAN *pChan = (AT91_SIO_CHAN *)pSioChan; #ifndef AT91C_DBGU_PDC_MODE AT91PS_USART port =(AT91PS_USART) (pChan->base); #endif UINT32 dbgupdctxlength = 0; if (pChan->sioMode != SIO_MODE_INT) /* polling mode */ { return ENOSYS; }#ifdef AT91C_DBGU_PDC_MODE #if 1 semTake(semDbguPdcTx, WAIT_FOREVER ); #else taskDelay(10); #endif while((*pChan->getTxChar)(pChan->getTxArg, (char *)(dbgupdctxbuffer + dbgupdctxlength)) == OK) { dbgupdctxlength++; } #if 1 /* pdc interrupt */ if (AT91C_DbguPdc_Send_Frame_Start(dbgupdctxbuffer, dbgupdctxlength) == -1) { return ENOSYS; } #else /* pdc polling */ AT91F_PDC_Open((AT91PS_PDC) &(((AT91PS_USART) AT91C_BASE_DBGU)->US_RPR)); AT91F_US_SendFrame((AT91PS_USART) AT91C_BASE_DBGU, dbgupdctxbuffer, dbgupdctxlength, 0, 0); #if 0 UART_PUT_IER(port, AT91C_US_ENDTX); #else while (AT91F_PDC_IsTxEmpty (AT91C_BASE_PDC_DBGU)==0); AT91F_PDC_Close((AT91PS_PDC) &(((AT91PS_USART) AT91C_BASE_DBGU)->US_RPR)); #endif #endif #else /* AT91C_DBGU_PDC_MODE */ /* Enable Transmit Holding Register Empty Interrupt. */ UART_PUT_IER(port, AT91C_US_TXEMPTY);#endif /* AT91C_DBGU_PDC_MODE */ return OK;}/******************************************************************************** at91SioCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters and* receiving characters. In general, drivers may support other types of callbacks* too.** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/LOCAL int at91SioCallbackInstall( SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */ int callbackType, /* type of callback */ STATUS (*callback)(), /* callback */ void * callbackArg /* parameter to callback */ ){ AT91_SIO_CHAN *pChan = (AT91_SIO_CHAN *)pSioChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar = callback; pChan->getTxArg = callbackArg; break; case SIO_CALLBACK_PUT_RCV_CHAR: pChan->putRcvChar = callback; pChan->putRcvArg = callbackArg; break; default: return ENOSYS; } return OK; }/******************************************************************************** at91SioPollInput - poll the device for input** RETURNS: OK if a character arrived, EIO on device error, EAGAIN if the input* buffer if empty, ENOSYS if the device is interrupt-only.*/LOCAL int at91SioPollInput( SIO_CHAN *pSioChan, /* device to poll */ char *inChar /* buffer to receive char */ ){ AT91_SIO_CHAN *pChan = (AT91_SIO_CHAN *)pSioChan; UINT32 stat; AT91PS_USART port =(AT91PS_USART) (pChan->base); /*stat = *at91_USTAT(pChan->ch);*/ stat = UART_GET_CSR(port); /*stat = *at91_USTAT(pChan->ch);*/ /* If no valid data present, retry later. */ if (!(stat & AT91C_US_RXRDY)) /* Receive Data Valid */ { return EAGAIN; } /* Read character from Receive Data Register. */ *inChar = UART_GET_CHAR(port); /**inChar = (char)*at91_URXBUF(pChan->ch);*/ return OK;}/********************************************************************************* at91SioPollOutput - output a character in polled mode** RETURNS: OK if a character arrived, EIO on device error, EAGAIN if the output* buffer if full. ENOSYS if the device is interrupt-only.*/LOCAL int at91SioPollOutput( SIO_CHAN *pSioChan, /* device to poll */ char outChar /* char to transmit */ ){ AT91_SIO_CHAN *pChan = (AT91_SIO_CHAN *)pSioChan; UINT32 stat; AT91PS_USART port =(AT91PS_USART) (pChan->base); /*stat = *at91_USTAT(pChan->ch);*/ stat = UART_GET_CSR(port); if (!(stat & AT91C_US_TXEMPTY)) /* Transmit Holding Register Empty */ { return EAGAIN; } /* Write char to Transmit Data Register. */ UART_PUT_CHAR(port, outChar);/**at91_UTXBUF(pChan->ch) = (VUINT8)outChar;*/ return OK;}#if 1/* * Interrupt handler */void at91SioInt(AT91_SIO_CHAN *pChan ){ char ch = 0; unsigned int status = 0, pending = 0; AT91PS_USART port = 0; if(pChan==0) { pChan = pDbgUChan; if(pChan==NULL) return; } port =(AT91PS_USART) (pChan->base); status = UART_GET_CSR(port); pending = status & (pChan->read_status_mask); while (pending) { if (pending & AT91C_US_RXRDY) { ch = UART_GET_CHAR(port); /* Call callback routine. */ (*pChan->putRcvChar)(pChan->putRcvArg, ch); } #ifdef AT91C_DBGU_PDC_MODE if (pending & AT91C_US_ENDTX) { #if 1 AT91C_DbguPdc_Send_Frame_Stop(); semGive(semDbguPdcTx); #else AT91F_PDC_Close((AT91PS_PDC) &(((AT91PS_USART) AT91C_BASE_DBGU)->US_RPR)); AT91F_PDC_SetTx((AT91PS_PDC) &(((AT91PS_USART)AT91C_BASE_DBGU)->US_RPR), (char *) 0, 1); UART_PUT_IDR(port, AT91C_US_ENDTX); #endif AT91_SYS->AIC_ICCR = (1<<pChan->intLvl); break; } #else /*AT91C_DBGU_PDC_MODE */ /* DBGU normal single char interrupt mode */ if (pending & 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_TXEMPTY ); AT91_SYS->AIC_ICCR = (1<<pChan->intLvl); break; } } #endif /* AT91C_DBGU_PDC_MODE */ status = UART_GET_CSR(port); pending = status & (pChan->read_status_mask); }}#else/* * Interrupt handler */void at91SioInt(AT91_SIO_CHAN *pChan ){ char ch = 0; unsigned int status = 0, pending = 0; AT91PS_USART port = 0; if(pChan==0) { pChan = pDbgUChan; if(pChan==NULL) return; } port =(AT91PS_USART) (pChan->base); status = UART_GET_CSR(port); pending = status& pChan->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_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_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); } while (pending); }}#endif/******************************************************************************** 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -