📄 at91sio.c
字号:
/* s3c2510Sio.c - at91rm9200 UART controller driver */#include "vxWorks.h"#include "intLib.h"#include "errno.h"#include "config.h"#include "h/drv/intrCtl/at91Intr.h"#include "h/drv/sio/at91Sio.h"#include "lib_AT91RM9200.h"#include "at91rm9200.h"#define UART_PUT_CR(port,v) port->US_CR = v#define UART_GET_MR(port) port->US_MR#define UART_PUT_MR(port,v) port->US_MR = v#define UART_PUT_IER(port,v) port->US_IER = v#define UART_PUT_IDR(port,v) port->US_IDR = v#define UART_GET_IMR(port) port->US_IMR#define UART_GET_CSR(port) port->US_CSR#define UART_GET_CHAR(port) port->US_RHR#define UART_PUT_CHAR(port,v) port->US_THR = v#define UART_GET_BRGR(port) port->US_BRGR#define UART_PUT_BRGR(port,v) port->US_BRGR = v#define UART_PUT_RTOR(port,v) port->US_RTOR = v/* #define UART_GET_CR(port) port->US_CR // is write-only*/ /* PDC registers */#define UART_PUT_PTCR(port,v) port->US_PTCR = v#define UART_PUT_RPR(port,v) port->US_RPR = v#define UART_PUT_RCR(port,v) port->US_RCR = v#define UART_GET_RCR(port) port->US_RCR#define UART_PUT_RNPR(port,v) port->US_RNPR = v#define UART_PUT_RNCR(port,v) port->US_RNCR = v#undef AT91C_DBGU_POLLING_MODE_DEBUG/* Local Forward Declarations *//*LOCAL STATUS s3c2510SioDummyCallback(void);*/LOCAL int at91SioBaudSet(AT91_SIO_CHAN *pChan, int baudRate);LOCAL int at91SioOptsSet(AT91_SIO_CHAN *pChan, int options);LOCAL int at91SioModeSet(AT91_SIO_CHAN *pChan, int sioMode);LOCAL int at91SioOpen(AT91_SIO_CHAN *pChan);LOCAL int at91SioHup(AT91_SIO_CHAN *pChan);LOCAL int at91SioIoctl(SIO_CHAN *pSioChan, int cmd, void* arg);LOCAL int at91SioTxStartup(SIO_CHAN *pSioChan);LOCAL int at91SioCallbackInstall(SIO_CHAN * pSioChan, int callbackType, STATUS (*callback)(), void * callbackArg);LOCAL int at91SioPollInput(SIO_CHAN *pSioChan, char *inChar);LOCAL int at91SioPollOutput(SIO_CHAN *pSioChan, char outChar);#ifdef AT91C_DBGU_PDC_MODE#include "cacheLib.h"LOCAL unsigned int AT91C_DbguPdc_Init(void);LOCAL unsigned int AT91C_DbguPdc_Send_Frame_Start(char *, unsigned int );LOCAL unsigned int AT91C_DbguPdc_Send_Frame_Stop(void);#define DBGU_PDC_TXBUFFER_LENGTH 512LOCAL char *dbgupdctxbuffer = NULL;LOCAL SEM_ID semDbguPdcTx = NULL;#endif /* AT91C_DBGU_PDC_MODE *//* Driver Function Table */LOCAL SIO_DRV_FUNCS at91SioDrvFuncs = { at91SioIoctl, at91SioTxStartup, (int (*)())at91SioCallbackInstall, at91SioPollInput, at91SioPollOutput};LOCAL AT91_SIO_CHAN *pDbgUChan = NULL;/********************************************************************************* at91SioDummyCallback - dummy callback routine.** RETURNS: ERROR, always.*/LOCAL STATUS at91SioDummyCallback(void){ return ERROR;}/******************************************************************************** at91SioDevInit - initialize a UART** This routine is called to initialize the chip to a quiescent state. Note that* the `ch' field of at91_CHAN must be less than or equal to the maximum* number of UART channels to configure as SIOs, as defined in at91.h** RETURNS: N/A*/void at91SioDevInit( AT91_SIO_CHAN *pChan /* device to initialize */ ){ AT91PS_USART port=(AT91PS_USART) pChan->base; #ifdef AT91C_DBGU_POLLING_MODE_DEBUG char *buffer = "at91's dbgu polling output test.\n\r";#endif if(pChan->base==(void*)AT91C_BASE_DBGU) { /*Open PIO for DBGU*/ AT91F_DBGU_CfgPIO(); /*Configure DBGU*/ AT91F_US_Configure ( (AT91PS_USART) AT91C_BASE_DBGU, /* DBGU base address*/ AT91C_MASTER_CLOCK, /* MCK:48MHz*/ AT91C_US_ASYNC_MODE, /* mode Register to be programmed*/ AT91C_CONSOLE_DEFAULT_BAUDRATE , /* baudrate to be programmed*/ 0); /* timeguard to be programmed*/ #ifdef AT91C_DBGU_PDC_MODE AT91C_DbguPdc_Init(); #endif /* Enable peripheral clock if required */ AT91_SYS->PMC_PCER = 1 << AT91C_ID_SYS; /* Finally, clear and enable interruptss*/ pDbgUChan = pChan; #ifdef AT91C_DBGU_PDC_MODE pChan->read_status_mask = AT91C_US_RXRDY | AT91C_US_ENDTX; #else /* AT91C_DBGU_PDC_MODE */ #if 1 pChan->read_status_mask = AT91C_US_RXRDY | AT91C_US_TXEMPTY; #else pChan->read_status_mask = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK|AT91C_US_TXEMPTY | AT91C_US_TXBUFE | AT91C_US_ENDTX; #endif #endif /* AT91C_DBGU_PDC_MODE */ /* Disable interrupt*/ UART_PUT_IDR(port, -1); /* enable xmit & rcvr */ UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN); #ifdef AT91C_DBGU_POLLING_MODE_DEBUG #ifdef AT91C_DBGU_PDC_MODE AT91F_PDC_Open((AT91PS_PDC) &(((AT91PS_USART) AT91C_BASE_DBGU)->US_RPR)); AT91F_US_SendFrame((AT91PS_USART) AT91C_BASE_DBGU, "at91's dbgu pdc test.\n\r",sizeof("at91's dbgu pdc test.\n\r"),0,0); while (AT91F_PDC_IsTxEmpty (AT91C_BASE_PDC_DBGU)==0); AT91F_PDC_Close((AT91PS_PDC) &(((AT91PS_USART) AT91C_BASE_DBGU)->US_RPR)); #else while(*buffer != '\0') { while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++); } #endif #endif }else{ AT91F_PIO_CfgPeriph(AT91C_BASE_PIOB,AT91C_PB21_RXD1 | AT91C_PB20_TXD1,0); /* First, enable the clock of the PIOB*/ AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1<<AT91C_ID_US1 ) ; /* Usart Configure*/ AT91F_US_Configure (port, AT91C_MASTER_CLOCK,AT91C_US_ASYNC_MODE, AT91C_CONSOLE_DEFAULT_BAUDRATE, 0); /* Enable usart */ UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN); /* enable xmit & rcvr */ pChan->read_status_mask = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK|AT91C_US_TXEMPTY; /* Enable USART IT error and AT91C_US_ENDRX*/ AT91F_US_EnableIt(port,AT91C_US_TIMEOUT | AT91C_US_FRAME | AT91C_US_OVRE |AT91C_US_ENDRX|AT91C_US_TXEMPTY); /* open Usart 1 interrupt*/ /*AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US1, USART_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, usart_asm_irq_handler); AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US1); */ /* set time out US_RTOR * Arm time out after 255 * 4 bits time * for 115200 bit time = 1/115200 = 8.6 micro sec time out unuti= 4* 8.6 = 34 micro */ port->US_RTOR = 0xFFFF; /*Enable usart SSTO*/ port->US_CR = AT91C_US_STTTO;} /* Initialize each channel's structure. */ pChan->pDrvFuncs = &at91SioDrvFuncs; pChan->getTxChar = at91SioDummyCallback; pChan->putRcvChar = at91SioDummyCallback; at91SioBaudSet(pChan, AT91C_CONSOLE_DEFAULT_BAUDRATE); at91SioOptsSet(pChan, CREAD | CS8); at91SioModeSet(pChan, SIO_MODE_POLL);#if 0 while(*buffer != '\0') { while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++); }#endif}/******************************************************************************** at91SioDevInit2 - initialize a UART, part 2** This routine is called by the BSP after interrupts have been connected. The* driver can now operate in interrupt mode. Before this routine is called only* polled mode operations should be allowed.** RETURNS: N/A*/void at91SioDevInit2( AT91_SIO_CHAN *pChan /* device to initialize */ ){}/********************************************************************************* at91SioIoctl - special device control** This routine handles the IOCTL messages from the user. It supports commands* to get/set baud rate, mode(INT,POLL), hardware options(parity, number of data* bits) and modem control(RTS/CTS and DTR/DSR handshakes). The ioctl commands* SIO_HUP and SIO_OPEN are used to implement the HUPCL(hang up on last close)* function.** As on a UNIX system, requesting a baud rate of zero is translated into a* hangup request. The DTR and RTS lines are dropped. This should cause a* connected modem to drop the connection. The SIO_HUP command will only hangup* if the HUPCL option is active. The SIO_OPEN function will raise DTR and RTS* lines whenever it is called. Use the BAUD_RATE=0 function to hangup when HUPCL* is not active.** The CLOCAL option will disable hardware flow control. When selected, hardware* flow control is not used. When not selected hardware flow control is based on* the RTS/CTS signals. CTS is the clear to send input from the other end. It* must be true for this end to begin sending new characters. In most drivers,* the RTS signal will be assumed to be connected to the opposite end's CTS* signal and can be used to control output from the other end. Raising RTS* asserts CTS at the other end and the other end can send data. Lowering RTS* de-asserts CTS and the other end will stop sending data. (This is non-EIA* defined use of RTS).** RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed request.*/LOCAL int at91SioIoctl( SIO_CHAN *pSioChan, /* device to control */ int cmd, /* request code */ void *arg /* some argument */ ){ AT91_SIO_CHAN *pChan = (AT91_SIO_CHAN *)pSioChan; int status = OK; int lockKey; switch (cmd) { /* Set the baud rate. */ case SIO_BAUD_SET: /* Disable interrupts during chip access. */ lockKey = intLock(); status = at91SioBaudSet(pChan, (int)arg); /* Enable interrupts after chip access. */ intUnlock(lockKey); break; /* Get the baud rate. */ case SIO_BAUD_GET: *(int *)arg = pChan->baudRate; break; /* Set the hardware options (as defined in sioLib.h). */ case SIO_HW_OPTS_SET: /* Disable interrupts during chip access. */ lockKey = intLock(); status = at91SioOptsSet(pChan, (int)arg); /* Enable interrupts after chip access. */ intUnlock(lockKey); break; /* Get the hardware options (as defined in sioLib.h). */ case SIO_HW_OPTS_GET: *(int *)arg = pChan->options; break; /* Set the mode (e.g., to interrupt or polled). */ case SIO_MODE_SET: /* Disable interrupts during chip access. */ lockKey = intLock(); status = at91SioModeSet(pChan, (int)arg); /* Enable interrupts after chip access. */ intUnlock(lockKey); break; /* Get the current mode. */ case SIO_MODE_GET: *(int *)arg = pChan->sioMode; break; /* Get the available modes. */ case SIO_AVAIL_MODES_GET: *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL; break; case SIO_OPEN: status = at91SioOpen(pChan); break; case SIO_HUP: status = at91SioHup(pChan); break; default: status = ENOSYS; } return (status);}/******************************************************************************** at91SioTxStartup - start the interrupt transmitter** RETURNS: OK on success, ENOSYS if the device is polled-only, or EIO on* hardware error.*/LOCAL int at91SioTxStartup( SIO_CHAN *pSioChan /* device to start */ ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -