📄 lh79524_uart_driver.c
字号:
break;
/* Get tx fifo level */
case UART_GET_TX_FIFO_LVL:
/* Enable the device */
if ((void*)arg == NULL)
{
status = _ERROR;
break;
}
*(INT_32*)arg = pdev->cfg.tx_fifo_depth;
break;
/* set rx fifo level */
case UART_SET_RX_FIFO_LVL:
temp = pregs->ifls;
temp &= UART_RX_FIFO_MASK;
temp |= ((UNS_32)arg<<3);
pregs->ifls = temp;
/* Save the config data */
pdev->cfg.rx_fifo_depth = arg;
break;
/* Get rx fifo level */
case UART_GET_RX_FIFO_LVL:
/* Enable the device */
if ((void*)arg == NULL)
{
status = _ERROR;
break;
}
*(INT_32*)arg = pdev->cfg.rx_fifo_depth;
break;
/* Get and set requests for the frame type (8-N-1 etc).*/
case UART_SET_FRAME_OPTIONS:
pregs->lcr_h = arg;
/* Save the options */
pdev->cfg.options = arg;
break;
case UART_GET_FRAME_OPTIONS:
/* Enable the device */
if ((void*)arg == NULL)
{
status = _ERROR;
break;
}
*(INT_32*)arg = pdev->cfg.options;
break;
/* Return the uart interrupt service routine */
case UART_GET_ISR:
/* Sanity check */
if ((void*)arg == NULL)
{
status = _ERROR;
break;
}
/* Bind the ISR for uart to the arg pointer */
*(INT_32**)arg = (void*)pdev->irq_hdlr;
break;
/* Enable polling mode */
case UART_SET_POLL_MODE:
/* Set the device into polled mode */
pdev->cfg.poll_mode = TRUE;
/* Mask all uart interrupts at the source */
pregs->imsc = UART_IMASK_ALL;
/* Clear any pending errors */
pregs->rsr_ecr = UART_ECR_CLEAR;
/* clear any pending interrupts */
pregs->icr = UART_CLR_ALL;
break;
/* Enable interrupt mode */
case UART_SET_INT_MODE:
/* Set the device into interrupt */
pdev->cfg.poll_mode = FALSE;
break;
/* Get and set requests for the 16 byte fifo */
case UART_ENABLE_FIFO:
/* Enable the fifo */
temp = pregs->lcr_h;
temp |= UART_LCR_FEN;
pregs->lcr_h = temp;
break;
/* Disable 16 byte fifo */
case UART_DISABLE_FIFO:
/* Disable the fifo */
temp = pregs->lcr_h;
temp &= ~UART_LCR_FEN;
pregs->lcr_h = temp;
break;
/* Mask (disable) interrupt source */
case UART_DISABLE_INT:
/* Mask the desired interrupt */
temp = pregs->imsc;
temp &= ~arg;
pregs->imsc = temp;
break;
/* UnMask (enable) interrupt source */
case UART_ENABLE_INT:
/* Unmask the desired interrupt */
temp = pregs->imsc;
temp |= arg;
pregs->imsc = temp;
/* Save the state */
pdev->imask = temp;
break;
/* enable loopback */
case UART_ENABLE_LOOPBACK:
temp = pregs->cr;
temp |= UART_CR_LBE;
pregs->cr = temp;
break;
/* disable loopback */
case UART_DISABLE_LOOPBACK:
temp = pregs->cr;
temp &= ~UART_CR_LBE;
pregs->cr = temp;
break;
/* Flush the Rx and Tx fifos and ring buffers */
case UART_FLUSH:
/* Save state */
temp = pregs->cr;
/* Enable the receiver */
pregs->cr = UART_CR_RXE | UART_CR_ENABLE;
/* Drain the reciever */
while (!(pregs->fr & UART_FR_RXFE))
{
temp = pregs->dr;
}
/* Enable the tranmitter */
pregs->cr = UART_CR_TXE | UART_CR_ENABLE;
/* Wait for transmitter to drain */
while (!(pregs->fr & UART_FR_TXFE));
/* Restore state */
pregs->cr = temp;
/* reset the fifo tx and rx buffers */
RING_FLUSH (&pdev->rx_id);
RING_FLUSH (&pdev->tx_id);
break;
/* Enable and disable the reciever */
case UART_ENABLE_RX:
/* Enable the receiver */
temp = pregs->cr;
temp |= UART_CR_RXE;
pregs->cr = temp;
break;
case UART_DISABLE_RX:
/* Disable the receiver */
temp = pregs->cr;
temp &= ~UART_CR_RXE;
pregs->cr = temp;
break;
/* Enable and disable the transmitter */
case UART_ENABLE_TX:
/* Enable the transmitter */
temp = pregs->cr;
temp |= UART_CR_TXE;
pregs->cr = temp;
break;
case UART_DISABLE_TX:
/* Disable the transmitter */
temp = pregs->cr;
temp &= ~UART_CR_TXE;
pregs->cr = temp;
break;
/* Enable and disable the device */
case UART_START:
temp = pregs->cr;
temp |= UART_CR_ENABLE;
pregs->cr = temp;
break;
case UART_STOP:
/* Disable the device */
temp = pregs->cr;
temp &= ~UART_CR_ENABLE;
pregs->cr = temp;
break;
default:
status = _ERROR;
break;
}
/* Return the io control status */
return (status);
}
/***********************************************************************
*
* Function: uart0_enable
*
* Purpose:
* Enable multiplexed uart0 pins and clock.
*
* Processing:
* Configure IOCON and RCPC registers.
*
* Parameters:
* enable - Specified whether to enable or diable the port
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart0_enable (BOOL_32 enable)
{
UNS_32 muxval = 0;
if(enable == FALSE)
{
/* disable the clock */
RCPC->periphclkctrl0 |= RCPC_CLKCTRL0_U0_DISABLE;
return;
}
/* read the mux register */
muxval = IOCON->mux_ctl_5;
/* clear the required fields */
muxval &= ~(_SBF(IOCON_RES5_PB6_INT0_UARTRX0_UARTIRRX0,0x11) |
_SBF(IOCON_RES5_PB7_INT1_UARTTX0_UARTIRTX0,0x11));
/* select URTTX0 & UARTRX0 */
muxval |= IOCON_MUX5_UARTTX0 | IOCON_MUX5_UARTRX0;
IOCON->mux_ctl_5 = muxval;
/* read the mux register */
muxval = IOCON->mux_ctl_6;
/* clear the required fields */
muxval &= ~(_SBF(IOCON_RES6_PB1_DREQ_UARTRTS0,0x11) |
_SBF(IOCON_RES6_PB0_DACK_UARTCTS0,0x11));
/* select URTTX0 & UARTRX0 */
muxval |= IOCON_MUX6_UARTRTS0 | IOCON_MUX6_UARTCTS0;
IOCON->mux_ctl_6 = muxval;
/* now enable the UART0 clock */
RCPC->periphclkctrl0 &= ~RCPC_CLKCTRL0_U0_DISABLE;
}
/***********************************************************************
*
* Function: uart1_enable
*
* Purpose:
* Enable multiplexed uart1 pins and clock.
*
* Processing:
* Configure IOCON and RCPC registers.
*
* Parameters:
* enable - Specified whether to enable or diable the port
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart1_enable (BOOL_32 enable)
{
UNS_32 muxval = 0;
if(enable == FALSE)
{
/* disable the clock */
RCPC->periphclkctrl0 |= RCPC_CLKCTRL0_U1_DISABLE;
return;
}
/* read the mux register */
muxval = IOCON->mux_ctl_5;
/* clear the required fields */
muxval &= ~(_SBF(IOCON_RES5_PB4_SSPRX_I2STXD_UARTRX1_UARTIRRX1,0x11) |
_SBF(IOCON_RES5_PB5_SSPTX_I2STXD_UARTTX1_UARTIRTX1,0x11));
/* select URTTX1 & UARTRX1 */
muxval |= IOCON_MUX5_UARTTX1 | IOCON_MUX5_UARTRX1;
IOCON->mux_ctl_5 = muxval;
/* now enable the UART1 clock */
RCPC->periphclkctrl0 &= ~RCPC_CLKCTRL0_U1_DISABLE;
}
/***********************************************************************
*
* Function: uart2_enable
*
* Purpose:
* Enable multiplexed uart2 pins and clock.
*
* Processing:
* Configure IOCON and RCPC registers.
*
* Parameters:
* enable - Specified whether to enable or diable the port
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart2_enable (BOOL_32 enable)
{
UNS_32 muxval = 0;
if(enable == FALSE)
{
/* disable the clock */
RCPC->periphclkctrl0 |= RCPC_CLKCTRL0_U2_DISABLE;
return;
}
/* read the mux register */
muxval = IOCON->mux_ctl_5;
/* clear the required fields */
muxval &= ~(_SBF(IOCON_RES5_PA0_INT2_UARTRX2_UARTIRRX2,0x11) |
_SBF(IOCON_RES5_PA1_INT3_UARTTX2_UARTIRTX2,0x11));
/* select URTTX0 & UARTRX0 */
muxval |= IOCON_MUX5_UARTRX2 | IOCON_MUX5_UARTTX2;
IOCON->mux_ctl_5 = muxval;
/* now enable the UART0 clock */
RCPC->periphclkctrl0 &= ~RCPC_CLKCTRL0_U2_DISABLE;
}
/***********************************************************************
*
* Function: uart0_isr
*
* Purpose:
* handle uart0 interrupts, sets device control struct and calls common
* int handler
*
* Processing:
* Assigns appropriate value to p_dev pointer and calls common routine.
*
* Parameters: None
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart0_isr (void)
{
uart_isr ((void*)pdriver[0]);
}
/***********************************************************************
*
* Function: uart1_isr
*
* Purpose:
* handle uart1 interrupts, sets device control struct and calls common
* int handler
*
* Processing:
* Assigns appropriate value to p_dev pointer and calls common routine.
*
* Parameters: None
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart1_isr (void)
{
uart_isr ((void*)pdriver[1]);
}
/***********************************************************************
*
* Function: uart2_isr
*
* Purpose:
* handle uart2 interrupts, sets device control struct and calls common
* int handler
*
* Processing:
* Assigns appropriate value to p_dev pointer and calls common routine.
*
* Parameters: None
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart2_isr (void)
{
uart_isr ((void*)pdriver[2]);
}
/***********************************************************************
*
* Function: uart_isr
*
* Purpose:
* common handler for uart01 interrupts
*
* Processing:
* Reads interrupt status and tests for bit set. Clears error ints.
* RX calls handler function. TX int loads data from ring buffer to
* device until FIFO is full.
*
* Parameters:
* p_dev: pointer to device control structure.
*
* Outputs: None
*
* Returns: None
*
* Notes:
* For CONSISTENCY with the UART2 drivers, the priority is hard
* coded.
*
**********************************************************************/
static void uart_isr (void* dev)
{
UNS_16 imask = 0; /* value of masked interrupts */
DRIVER_T* pdev = (DRIVER_T*)dev;
REGS_T* pregs = (REGS_T*)pdev->regs;
/* Get status of currently masked interrupts */
imask = pregs->mis;
/* uart overrun error */
if ((imask & UART_INT_OE) == UART_INT_OE)
{
pdev->isr[UART_OE_POS](dev, UART_INT_OE);
}
/* uart line break error */
if ((imask & UART_INT_BE) == UART_INT_BE)
{
pdev->isr[UART_BE_POS](dev, UART_INT_BE);
}
/* uart parity bit error */
if ((imask & UART_INT_PE) == UART_INT_PE)
{
pdev->isr[UART_PE_POS](dev, UART_INT_PE);
}
/* uart framing error */
if ((imask & UART_INT_FE) == UART_INT_FE)
{
pdev->isr[UART_FE_POS](dev, UART_INT_FE);
}
/* uart transmitter empty */
if ((imask & UART_INT_TX) == UART_INT_TX)
{
pdev->isr[UART_TX_POS](dev);
}
/* uart reciever is full */
else if ((imask & UART_INT_RX) == UART_INT_RX)
{
pdev->isr[UART_RX_POS](dev);
}
/* uart receiver timeout error */
else if ((imask & UART_INT_RT) == UART_INT_RT)
{
pdev->isr[UART_RT_POS](dev);
}
}
/***********************************************************************
*
* Function: uart_rx_isr
*
* Purpose:
* handler for uart01 read and read timeout interrupts
*
* Processing:
* Loads the data into the ring buffer and clears the interrupt
*
* Parameters: p_dev: pointer to device control structure.
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart_rx_isr (void* dev)
{
DRIVER_T* pdev = (DRIVER_T*)dev;
REGS_T* pregs = (REGS_T*)pdev->regs;
/* While there is data in the fifo */
while ( !(pregs->fr & UART_FR_RXFE) )
{
/* There is data so pass it up the sio channel buffer */
RING_PUTC (&pdev->rx_id, (CHAR)pregs->dr);
}
/* Clear the interrupt */
pregs->icr |= (UART_INT_RX | UART_INT_RT);
return;
}
/***********************************************************************
*
* Function: uart_tx_isr
*
* Purpose:
* handler for uart write interrupts
*
* Processing:
* loads data from ring buffer to device until FIFO is full.
*
* Parameters: p_dev: pointer to device control structure.
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart_tx_isr (void* dev)
{
DRIVER_T* pdev = (DRIVER_T*)dev;
REGS_T* pregs = (REGS_T*)pdev->regs;
/* clear the interrupt at the source */
pregs->icr = UART_INT_TX;
/* Make sure there is data to be sent */
if ( (RING_COUNT (&pdev->tx_id) == 0) &&
(pregs->fr & UART_FR_TXFE) &&
!(pregs->fr & UART_FR_BUSY) )
{
/* Turn off the Tx interrupts */
(void) uart_ioctl
((INT_32)dev, UART_DISABLE_INT, UART_INT_TX);
/* Clear the interrupt */
pregs->icr = UART_INT_TX;
/* Disable the transmitter */
(void) uart_ioctl ((INT_32)dev, UART_DISABLE_TX, 0);
}
else
{
/* There is data so fill the fifo */
while ( (RING_COUNT (&pdev->tx_id) != 0) &&
!(pregs->fr & UART_FR_TXFF) )
{
/* Write the data to the device */
RING_GETC (&pdev->tx_id, pregs->dr);
}
}
}
/***********************************************************************
*
* Function: uart_err_isr
*
* Purpose:
* handler for uart error interrupts
*
* Processing:
* Clears the interrupt
*
* Parameters: p_dev: pointer to device control structure.
*
* Outputs: None
*
* Returns: None
*
* Notes: None
*
**********************************************************************/
static void uart_err_isr (void* dev,
INT_32 src)
{
DRIVER_T* pdev = (DRIVER_T*)dev;
REGS_T* pregs = (REGS_T*)pdev->regs;
/* clear the interrupt */
pregs->icr = src;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -