?? ser_mcf5272_uart.c
字號:
chan - pointer to the serial private data.
RETURN:
the character read from the UART.
*/
static unsigned char MCF5272_uart_getc(serial_channel *chan)
{
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *)chan->dev_priv;
/* Wait until character has been received */
while (!(MCF5272_UART_READ(port->base->usr_ucsr) & MCF5272_UART_USR_RXRDY))
{
diag_printf("ready poll");
}
/* Read the character from the FIFO queue. */
return MCF5272_UART_READ(port->base->urf);
}
/*******************************************************************************
MCF5272_uart_set_config() - Set up the device characteristics; baud rate, etc.
INPUT:
chan - pointer to the serial private data.
key - configuration key (command).
xbuf - pointer to the configuration buffer
len - the length of the configuration buffer
RETURN:
NOERR - If the configuration is successful
EINVAL - If the argument is invalid
*/
Cyg_ErrNo MCF5272_uart_set_config(serial_channel *chan, cyg_uint32 key,
const void *xbuf, cyg_uint32 *len)
{
cyg_serial_info_t *config = (cyg_serial_info_t *)xbuf;
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
switch (key) {
case CYG_IO_SET_CONFIG_SERIAL_INFO:
{
/* Set serial configuration. */
if ( *len < sizeof(cyg_serial_info_t) ) {
return EINVAL;
}
*len = sizeof(cyg_serial_info_t);
if (!MCF5272_uart_config_port(chan, config))
return EINVAL;
}
break;
case CYG_IO_GET_CONFIG_SERIAL_INFO:
// Retrieve UART configuration
*config = port->config;
break;
default:
return EINVAL;
}
return ENOERR;
}
/*******************************************************************************
MCF5272_uart_start_xmit() - Enable the transmitter on the device.
INPUT:
chan - pointer to the serial private data.
*/
static void MCF5272_uart_start_xmit(serial_channel *chan)
{
CYG_INTERRUPT_STATE int_state;
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
/* Enable the UART transmit. */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXEN);
/* Enable transmit interrupt */
HAL_DISABLE_INTERRUPTS(int_state);
port->imr_mirror |= MCF5272_UART_UIMR_TXRDY;
MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
HAL_RESTORE_INTERRUPTS(int_state);
}
/******************************************************************************************************
MCF5272_uart_stop_xmit() - Disable the transmitter on the device
INPUT:
chan - pointer to the serial private data.
*/
static void MCF5272_uart_stop_xmit(serial_channel * chan)
{
CYG_INTERRUPT_STATE int_state;
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
/* Disable transmit interrupt */
HAL_DISABLE_INTERRUPTS(int_state);
port->imr_mirror &= ~MCF5272_UART_UIMR_TXRDY;
MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
HAL_RESTORE_INTERRUPTS(int_state);
/* Disable the UART transmit.
!!!!!!!!!!!!!
!!!WARNING!!!
!!!!!!!!!!!!!
If the transmit the disabe
the diag_printf routines will poll forever to transmit the
a character. Hence, don't ever disable the transmit if
we want it to work with diag_printf.
*/
//MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_TXDE);
}
/******************************************************************************************************
MCF5272_uart_ISR() - UART I/O interrupt interrupt service routine (ISR).
INPUT:
vector - the interrupt vector number
data - user parameter.
RETURN:
returns CYG_ISR_CALL_DSR to call the DSR.
*/
static cyg_uint32 MCF5272_uart_ISR(cyg_vector_t vector, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *) data;
MCF5272_uart_info_t * port = (MCF5272_uart_info_t *) chan->dev_priv;
/* Write the value in the interrupt status register back
to the mask register to disable the interrupt temporarily.
*/
MCF5272_UART_WRITE(port->base->uisr_uimr, 0);
return CYG_ISR_CALL_DSR; // Cause DSR to run
}
/******************************************************************************************************
MCF5272_uart_DSR() - Defered Service Routine (DSR) - This routine processes the interrupt
from the device.
INPUT:
vector - The interrupt vector number
count - The nunber of DSR requests.
data - Device specific information
*/
static void MCF5272_uart_DSR(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
serial_channel *chan = (serial_channel *)data;
MCF5272_uart_info_t *port = (MCF5272_uart_info_t *)chan->dev_priv;
volatile u8_t isr;
/* Retrieve the interrupt status bits. We use these status bits to figure out
what process shouled we perform: read from the UART or inform of a completion
of a data transmission.
*/
/* Retrieve the interrupt status register so
* the DSR can look it up.
*/
while((isr = (MCF5272_UART_READ(port->base->uisr_uimr) & port->imr_mirror)))
{
switch (port->autobaud_state)
{
default:
case AB_IDLE:
if (isr & MCF5272_UART_UISR_DB)
{
/* Detected the begin of a break, set the state to AB_BEGIN_BREAK
*/
port->autobaud_state = AB_BEGIN_BREAK;
/* Reset the Delta Break bit in the UISR */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT);
}
break;
case AB_BEGIN_BREAK:
if (isr & MCF5272_UART_UISR_DB)
{
/* Detected the end of a break, set the state to AB_BEGIN, and
setup autobaud detection.
*/
port->autobaud_state = AB_BEGIN;
/* Reset the Delta Break bit in the UISR and Enable autobaud */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_RESET_BKCHGINT |
MCF5272_UART_UCR_ENAB);
/* Enable autobaud completion interrupt */
port->imr_mirror |= MCF5272_UART_UIMR_ABC;
/* Disable the delta break interrupt so we can't receive
anymore break interrupt.
*/
port->imr_mirror &= ~MCF5272_UART_UIMR_DB;
}
break;
case AB_BEGIN:
if (isr & MCF5272_UART_UISR_ABC)
{
int count;
// Retrieve the baudrate that we're using now.
u16_t divider = (port->base->uabu << 8) + port->base->uabl;
// Search in the list to find a match.
for (count = sizeof(dividers_table)/sizeof(unsigned long) - 1;
count >= 0;
count--)
{
if (divider < dividers_table[count]) break;
}
// Set the baud.
port->config.baud = count;
/* Autobaud completion */
port->autobaud_state = AB_IDLE;
/* Disable autobaud */
MCF5272_UART_WRITE(port->base->ucr, MCF5272_UART_UCR_NONE);
/* Ignore autobaud completion interrupt. */
port->imr_mirror &= ~MCF5272_UART_UIMR_ABC;
/* Reenable begin break change and receive interrupt. */
port->imr_mirror |= MCF5272_UART_UIMR_DB;
}
break;
}
/* Receive character interrupt */
if ((isr & MCF5272_UART_UISR_RXRDY))
/* Ignore all receive interrupt when we're autobauding. */
{
// Read all the characters in the fifo.
while ((MCF5272_UART_READ(port->base->uisr_uimr) & MCF5272_UART_UISR_RXRDY))
{
char c;
/* Read the character from the UART. */
c = MCF5272_UART_READ(port->base->urb_utb);
/* Pass the read character to the upper layer. */
(chan->callbacks->rcv_char)(chan, c);
}
}
/* Transmit complete interrupt */
if ((isr & MCF5272_UART_UISR_TXRDY))
{
/* Transmit holding register is empty */
(chan->callbacks->xmt_char)(chan);
}
}
/* Unmask all the DUART interrupts that were masked in the ISR, so */
/* that we can receive the next interrupt. */
MCF5272_UART_WRITE(port->base->uisr_uimr, port->imr_mirror);
}
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL0
unsigned long MCF5272_uart_get_channel_0_baud_rate()
{
/* return the baud rate for the first serial port */
return baud_rates_table[MCF5272_uart_channel_info_0.config.baud];
}
#endif
#ifdef CYGPKG_IO_SERIAL_MCF5272_UART_CHANNEL1
unsigned long MCF5272_uart_get_channel_1_baud_rate()
{
/* return the baud rate for the second serial port */
return baud_rates_table[MCF5272_uart_channel_info_1.config.baud];
}
#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -