📄 uartgba.c
字号:
GbaUartEnable(); /* * Verify the result. */ if (GbaUartGetParity() != mode) { return -1; } return 0;}/*! * \brief Query the USART hardware for the number of stop bits. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return The number of stop bits set, either 1 or 2. */static u_char GbaUartGetStopBits(void){ return 1;}/*! * \brief Set the USART hardware to the number of stop bits. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int GbaUartSetStopBits(u_char bits){ GbaUartDisable(); GbaUartEnable(); /* * Verify the result. */ if (GbaUartGetStopBits() != bits) { return -1; } return 0;}/*! * \brief Query the USART hardware status. * * \return Status flags. */static u_long GbaUartGetStatus(void){ u_long rc = 0; /* * Set receiver error flags. */ /* * Determine software handshake status. The flow control status may * change during interrupt, but this doesn't really hurt us. */ if (flow_control) { if (flow_control & XOFF_SENT) { rc |= UART_RXDISABLED; } if (flow_control & XOFF_RCVD) { rc |= UART_TXDISABLED; } } /* * If transmitter and receiver haven't been detected disabled by any * of the checks above, then they are probably enabled. */ if ((rc & UART_RXDISABLED) == 0) { rc |= UART_RXENABLED; } if ((rc & UART_TXDISABLED) == 0) { rc |= UART_TXENABLED; } return rc;}/*! * \brief Set the USART hardware status. * * \param flags Status flags. * * \return 0 on success, -1 otherwise. */static int GbaUartSetStatus(u_long flags){ /* * Process software handshake control. */ if (flow_control) { /* Access to the flow control status must be atomic. */ NutEnterCritical(); /* * Enabling or disabling the receiver means to behave like * having sent a XON or XOFF character resp. */ if (flags & UART_RXENABLED) { flow_control &= ~XOFF_SENT; } else if (flags & UART_RXDISABLED) { flow_control |= XOFF_SENT; } /* * Enabling or disabling the transmitter means to behave like * having received a XON or XOFF character resp. */ if (flags & UART_TXENABLED) { flow_control &= ~XOFF_RCVD; } else if (flags & UART_TXDISABLED) { flow_control |= XOFF_RCVD; } NutExitCritical(); } /* * Verify the result. */ if ((GbaUartGetStatus() & ~UART_ERRORS) != flags) { return -1; } return 0;}/*! * \brief Query the USART hardware for synchronous mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return Or-ed combination of \ref UART_SYNC, \ref UART_MASTER, * \ref UART_NCLOCK and \ref UART_HIGHSPEED. */static u_char GbaUartGetClockMode(void){ return 0;}/*! * \brief Set asynchronous or synchronous mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param mode Must be an or-ed combination of USART_SYNC, USART_MASTER, * USART_NCLOCK and USART_HIGHSPEED. * * \return 0 on success, -1 otherwise. */static int GbaUartSetClockMode(u_char mode){ /* * Verify the result. */ if (GbaUartGetClockMode() != mode) { return -1; } return 0;}/*! * \brief Query flow control mode. * * This routine is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \return See UsartIOCtl(). */static u_long GbaUartGetFlowControl(void){ u_long rc = 0; if (flow_control) { rc |= USART_MF_XONXOFF; } else { rc &= ~USART_MF_XONXOFF; } return rc;}/*! * \brief Set flow control mode. * * This function is called by ioctl function of the upper level USART * driver through the USARTDCB jump table. * * \param flags See UsartIOCtl(). * * \return 0 on success, -1 otherwise. */static int GbaUartSetFlowControl(u_long flags){ /* * Set software handshake mode. */ if (flags & USART_MF_XONXOFF) { if (flow_control == 0) { NutEnterCritical(); flow_control = 1 | XOFF_SENT; /* force XON to be sent on next read */ NutExitCritical(); } } else { NutEnterCritical(); flow_control = 0; NutExitCritical(); } /* * Verify the result. */ if (GbaUartGetFlowControl() != flags) { return -1; } return 0;}/*! * \brief Start the USART transmitter hardware. * * The upper level USART driver will call this function through the * USARTDCB jump table each time it added one or more bytes to the * transmit buffer. */static void GbaUartTxStart(void){ RINGBUF *rbf = &dcb_uart.dcb_tx_rbf; register u_char *cp = rbf->rbf_tail; NutEnterCritical(); if(tx_stop) { if (rbf->rbf_cnt) { rbf->rbf_cnt--; outw(REG_SIODATA8, *cp); if (++cp == rbf->rbf_last) { cp = rbf->rbf_start; } rbf->rbf_tail = cp; tx_stop = 0; } } outw(REG_SIOCNT, inw(REG_SIOCNT) | SIO_SEND_ENA); NutExitCritical();}/*! * \brief Start the USART receiver hardware. * * The upper level USART driver will call this function through the * USARTDCB jump table each time it removed enough bytes from the * receive buffer. Enough means, that the number of bytes left in * the buffer is below the low watermark. */static void GbaUartRxStart(void){ /* * Do any required software flow control. */ NutEnterCritical(); if (flow_control && (flow_control & XOFF_SENT) != 0) { if (inw(REG_SIOCNT) & SIO_TX_FULL) { flow_control |= XON_PENDING; } else { outw(REG_SIODATA8, ASCII_XON); flow_control &= ~XON_PENDING; } flow_control &= ~(XOFF_SENT | XOFF_PENDING); } outw(REG_SIOCNT, inw(REG_SIOCNT) | SIO_RECV_ENA); NutExitCritical();}/* * \brief Initialize the USART hardware driver. * * This function is called during device registration by the upper level * USART driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int GbaUartInit(void){ int rc; /* * Activate MBV2 UART mode by setting SC low and SD high for at * least 50 milliseconds. */ outw(REG_RCNT, 0x8032); NutSleep(100); /* Disable master interrupt. */ outw(REG_IME, 0); /* Register our interrupt service. */ if((rc = NutRegisterIrqHandler(&sig_SIO, GbaUartIsr, &dcb_uart)) == 0) { /* Enable UART mode. */ outw(REG_RCNT, 0x0000); /* Set UART mode */ outw(REG_SIOCNT, SIO_IRQ_ENA | SIO_MODE_UART | SIO_DATA_8BIT | SIO_BAUD_38400); /* Clear receive/transmit */ outw(REG_SIOCNT, inw(REG_SIOCNT) | SIO_RX_EMPTY | SIO_TX_FULL); /* Enable FIFO. */ //outw(REG_SIOCNT, inw(REG_SIOCNT) | SIO_FIFO_ENA); /* Enable SIO interrupts. */ outw(REG_IE, inw(REG_IE) | INT_SIO); } printf("I[%04X]", inw(REG_SIOCNT)); /* Enable master interrupt. */ outw(REG_IME, 1); return rc;}/* * \brief Deinitialize the USART hardware driver. * * This function is called during device deregistration by the upper * level USART driver through the USARTDCB jump table. * * \return 0 on success, -1 otherwise. */static int GbaUartDeinit(void){ /* Deregister receive and transmit interrupts. */ NutRegisterIrqHandler(&sig_SIO, 0, 0); return 0;}#if 1/*! * \brief UART0 device control block structure. */static USARTDCB dcb_uart = { 0, /* dcb_modeflags */ 0, /* dcb_statusflags */ 0, /* dcb_rtimeout */ 0, /* dcb_wtimeout */ {0, 0, 0, 0, 0, 0, 0, 0}, /* dcb_tx_rbf */ {0, 0, 0, 0, 0, 0, 0, 0}, /* dcb_rx_rbf */ 0, /* dbc_last_eol */ GbaUartInit, /* dcb_init */ GbaUartDeinit, /* dcb_deinit */ GbaUartTxStart, /* dcb_tx_start */ GbaUartRxStart, /* dcb_rx_start */ GbaUartSetFlowControl, /* dcb_set_flow_control */ GbaUartGetFlowControl, /* dcb_get_flow_control */ GbaUartSetSpeed, /* dcb_set_speed */ GbaUartGetSpeed, /* dcb_get_speed */ GbaUartSetDataBits, /* dcb_set_data_bits */ GbaUartGetDataBits, /* dcb_get_data_bits */ GbaUartSetParity, /* dcb_set_parity */ GbaUartGetParity, /* dcb_get_parity */ GbaUartSetStopBits, /* dcb_set_stop_bits */ GbaUartGetStopBits, /* dcb_get_stop_bits */ GbaUartSetStatus, /* dcb_set_status */ GbaUartGetStatus, /* dcb_get_status */ GbaUartSetClockMode, /* dcb_set_clock_mode */ GbaUartGetClockMode, /* dcb_get_clock_mode */};/*! * \name AVR USART0 Device *//*@{*//*! * \brief USART0 device information structure. * * An application must pass a pointer to this structure to * NutRegisterDevice() before using the serial communication * driver of the AVR's on-chip USART0. * * The device is named \b uart0. * * \showinitializer */NUTDEVICE devUartGba = { 0, /* Pointer to next device, dev_next. */ {'u', 'a', 'r', 't', '0', 0, 0, 0, 0}, /* Unique device name, dev_name. */ IFTYP_CHAR, /* Type of device, dev_type. */ 0, /* Base address, dev_base (not used). */ 0, /* First interrupt number, dev_irq (not used). */ 0, /* Interface control block, dev_icb (not used). */ &dcb_uart, /* Driver control block, dev_dcb. */ UsartInit, /* Driver initialization routine, dev_init. */ UsartIOCtl, /* Driver specific control function, dev_ioctl. */ UsartRead, /* Read from device, dev_read. */ UsartWrite, /* Write to device, dev_write. */ UsartOpen, /* Open a device or file, dev_open. */ UsartClose, /* Close a device or file, dev_close. */ UsartSize /* Request file size, dev_size. */};#endif/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -