⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z16f_serial.c

📁 這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************** * arch/z16/src/z16f/z16f_serial.c * *   Copyright (C) 2008 Gregory Nutt. All rights reserved. *   Author: Gregory Nutt <spudmonkey@racsa.co.cr> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * 3. Neither the name NuttX nor the names of its contributors may be *    used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************//**************************************************************************** * Included Files ****************************************************************************/#include <nuttx/config.h>#include <sys/types.h>#include <unistd.h>#include <semaphore.h>#include <string.h>#include <errno.h>#include <debug.h>#include <nuttx/irq.h>#include <nuttx/arch.h>#include <nuttx/serial.h>#include <arch/serial.h>#include "chip/chip.h"#include "os_internal.h"#include "up_internal.h"#ifdef CONFIG_USE_SERIALDRIVER/**************************************************************************** * Definitions ****************************************************************************//* System clock frequency value from ZDS target settings */extern _Erom unsigned long SYS_CLK_FREQ;#define _DEFCLK ((unsigned long)&SYS_CLK_FREQ)#define STATE_DISABLED   0#define STATE_RXENABLED  1#define STATE_TXENABLED  2/**************************************************************************** * Private Types ****************************************************************************/struct z16f_uart_s{  uint32               uartbase;	/* Base address of UART					 * registers */  uint32               baud;		/* Configured baud */  boolean              rxenabled;	/* RX interrupt enabled */  boolean              txenabled;	/* TX interrupt enabled */  ubyte                rxirq;		/* RX IRQ associated with this UART */  ubyte                txirq;		/* RX IRQ associated with this UART */  ubyte                parity;		/* 0=none, 1=odd, 2=even */  boolean              stopbits2;	/* TRUE: Configure with 2					 * stop bits instead of 1 */};/**************************************************************************** * Private Function Prototypes ****************************************************************************/static int     z16f_setup(struct uart_dev_s *dev);static void    z16f_shutdown(struct uart_dev_s *dev);static int     z16f_attach(struct uart_dev_s *dev);static void    z16f_detach(struct uart_dev_s *dev);static int     z16f_rxinterrupt(int irq, void *context);static int     z16f_txinterrupt(int irq, void *context);static int     z16f_ioctl(struct file *filep, int cmd, unsigned long arg);static int     z16f_receive(struct uart_dev_s *dev, uint32 *status);static void    z16f_rxint(struct uart_dev_s *dev, boolean enable);static boolean z16f_rxavailable(struct uart_dev_s *dev);static void    z16f_send(struct uart_dev_s *dev, int ch);static void    z16f_txint(struct uart_dev_s *dev, boolean enable);static boolean z16f_txready(struct uart_dev_s *dev);static boolean z16f_txempty(struct uart_dev_s *dev);/**************************************************************************** * Private Variables ****************************************************************************/struct uart_ops_s g_uart_ops ={  z16f_setup,          /* setup */  z16f_shutdown,       /* shutdown */  z16f_attach,         /* attach */  z16f_detach,         /* detach */  z16f_ioctl,          /* ioctl */  z16f_receive,        /* receive */  z16f_rxint,          /* rxint */  z16f_rxavailable,    /* rxavailable */  z16f_send,           /* send */  z16f_txint,          /* txint */  z16f_txready,        /* txready */  z16f_txempty         /* txempty */};/* I/O buffers */static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE];static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE];static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE];static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE];/* This describes the state of the DM320 uart0 port. */static struct z16f_uart_s g_uart0priv ={  Z16F_UART0_BASE,          /* uartbase */  CONFIG_UART0_BAUD,        /* baud */  FALSE,                    /* rxenabled */  FALSE,                    /* txenabled */  Z16F_IRQ_UART0RX,         /* rxirq */  Z16F_IRQ_UART0TX,         /* txirq */  CONFIG_UART0_PARITY,      /* parity */  CONFIG_UART0_2STOP        /* stopbits2 */};static uart_dev_t g_uart0port ={  0,                        /* open_count */  FALSE,                    /* xmitwaiting */  FALSE,                    /* recvwaiting */#ifdef CONFIG_UART0_SERIAL_CONSOLE  TRUE,                     /* isconsole */#else  FALSE,                    /* isconsole */#endif  { 0 },                    /* closesem */  { 0 },                    /* xmitsem */  { 0 },                    /* recvsem */  {    { 0 },                  /* xmit.sem */    0,                      /* xmit.head */    0,                      /* xmit.tail */    CONFIG_UART0_TXBUFSIZE, /* xmit.size */    g_uart0txbuffer,        /* xmit.buffer */  },  {    { 0 },                  /* recv.sem */    0,                      /* recv.head */    0,                      /* recv.tail */    CONFIG_UART0_RXBUFSIZE, /* recv.size */    g_uart0rxbuffer,        /* recv.buffer */  },  &g_uart_ops,              /* ops */  &g_uart0priv,             /* priv */};/* This describes the state of the DM320 uart1 port. */static struct z16f_uart_s g_uart1priv ={  Z16F_UART1_BASE,          /* uartbase */  CONFIG_UART1_BAUD,        /* baud */  FALSE,                    /* rxenabled */  FALSE,                    /* txenabled */  Z16F_IRQ_UART1RX,         /* rxirq */  Z16F_IRQ_UART1TX,         /* txirq */  CONFIG_UART1_PARITY,      /* parity */  CONFIG_UART1_2STOP        /* stopbits2 */};static uart_dev_t g_uart1port ={  0,                        /* open_count */  FALSE,                    /* xmitwaiting */  FALSE,                    /* recvwaiting */#ifdef CONFIG_UART1_SERIAL_CONSOLE  TRUE,                     /* isconsole */#else  FALSE,                    /* isconsole */#endif  { 0 },                    /* closesem */  { 0 },                    /* xmitsem */  { 0 },                    /* recvsem */  {    { 0 },                  /* xmit.sem */    0,                      /* xmit.head */    0,                      /* xmit.tail */    CONFIG_UART1_TXBUFSIZE, /* xmit.size */    g_uart1txbuffer,        /* xmit.buffer */  },  {    { 0 },                  /* recv.sem */    0,                      /* recv.head */    0,                      /* recv.tail */    CONFIG_UART0_RXBUFSIZE, /* recv.size */    g_uart0rxbuffer,        /* recv.buffer */  },  &g_uart_ops,              /* ops */  &g_uart1priv,             /* priv */};/* Now, which one with be tty0/console and which tty1? */#ifdef CONFIG_UART1_SERIAL_CONSOLE# define CONSOLE_DEV     g_uart1port# define TTYS0_DEV       g_uart1port# define TTYS1_DEV       g_uart0port#else# define CONSOLE_DEV     g_uart0port# define TTYS0_DEV       g_uart0port# define TTYS1_DEV       g_uart1port#endif/**************************************************************************** * Private Functions ****************************************************************************//**************************************************************************** * Name: z16f_disableuartirq ****************************************************************************/static ubyte z16f_disableuartirq(struct uart_dev_s *dev){  struct z16f_uart_s *priv  = (struct z16f_uart_s*)dev->priv;  irqstate_t          flags = irqsave();  ubyte               state = priv->rxenabled ? STATE_RXENABLED : STATE_DISABLED | \                              priv->txenabled ? STATE_TXENABLED : STATE_DISABLED;  z16f_txint(dev, FALSE);  z16f_rxint(dev, FALSE);  irqrestore(flags);  return state;}/**************************************************************************** * Name: z16f_restoreuartirq ****************************************************************************/static void z16f_restoreuartirq(struct uart_dev_s *dev, ubyte state){  struct z16f_uart_s *priv  = (struct z16f_uart_s*)dev->priv;  irqstate_t          flags = irqsave();  z16f_txint(dev, (state & STATE_TXENABLED) ? TRUE : FALSE);  z16f_rxint(dev, (state & STATE_RXENABLED) ? TRUE : FALSE);  irqrestore(flags);}/**************************************************************************** * Name: z16f_consoleput ****************************************************************************/static void z16f_consoleput(ubyte ch){  struct z16f_uart_s *priv = (struct z16f_uart_s*)CONSOLE_DEV.priv;  int tmp;  for (tmp = 1000 ; tmp > 0 ; tmp--)    {      if (z16f_txready(&CONSOLE_DEV))        {          break;        }    }  putreg8(ch,  priv->uartbase + Z16F_UART_TXD);}/**************************************************************************** * Name: z16f_setup * * Description: *   Configure the UART baud, parity, etc. This method is called the first *   time that the serial port is opened. * ****************************************************************************/static int z16f_setup(struct uart_dev_s *dev){#ifndef CONFIG_SUPPRESS_UART_CONFIG  struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;  uint32 brg;  ubyte ctl0;  ubyte ctl1;  /* Calculate and set the baud rate generation register.   * BRG = (freq + baud * 8)/(baud * 16)   */  brg = (_DEFCLK + (priv->baud << 3))/(priv->baud << 4);  putreg16((uint16)brg, priv->uartbase + Z16F_UART_BR);  /* Configure STOP bits */  ctl0 = ctl1 = 0;  if (priv->stopbits2)    {      ctl0 |= Z16F_UARTCTL0_STOP;    }  /* Configure parity */  if (priv->parity == 1)    {      ctl0 |= (Z16F_UARTCTL0_PEN|Z16F_UARTCTL0_PSEL);    }  else if (priv->parity == 2)    {      ctl0 |= Z16F_UARTCTL0_PEN;    }  putreg8(ctl0, priv->uartbase + Z16F_UART_CTL0);  putreg8(ctl1, priv->uartbase + Z16F_UART_CTL1);  /* Enable UART receive (REN) and transmit (TEN) */  ctl0 |= (Z16F_UARTCTL0_TEN|Z16F_UARTCTL0_REN);  putreg8(ctl0, priv->uartbase + Z16F_UART_CTL0);#endif  return OK;}/**************************************************************************** * Name: z16f_shutdown * * Description: *   Disable the UART.  This method is called when the serial *   port is closed * ****************************************************************************/static void z16f_shutdown(struct uart_dev_s *dev){  struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;  (void)z16f_disableuartirq(dev);}/**************************************************************************** * Name: z16f_attach * * Description: *   Configure the UART to operation in interrupt driven mode.  This method is *   called when the serial port is opened.  Normally, this is just after the *   the setup() method is called, however, the serial console may operate in *   a non-interrupt driven mode during the boot phase. * *   RX and TX interrupts are not enabled when by the attach method (unless the *   hardware supports multiple levels of interrupt enabling).  The RX and TX *   interrupts are not enabled until the txint() and rxint() methods are called. * ****************************************************************************/static int z16f_attach(struct uart_dev_s *dev){  struct z16f_uart_s *priv = (struct z16f_uart_s*)dev->priv;  int ret;  /* Attach the RX IRQ */  ret = irq_attach(priv->rxirq, z16f_rxinterrupt);  if (ret == OK)    {      /* Attach the TX IRQ */      ret = irq_attach(priv->txirq, z16f_txinterrupt);      if (ret != OK)        {          irq_detach(priv->rxirq);        }    }  return ret;}/**************************************************************************** * Name: z16f_detach * * Description:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -