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

📄 mg5uart.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
 *  wrappers which are nearly functionally identical. */#define __ISR(_TYPE, _OFFSET) \  MG5UART_STATIC void mg5uart_process_isr_ ## _TYPE ( \    int  minor \  ); \  \  MG5UART_STATIC rtems_isr mg5uart_isr_ ## _TYPE ( \    rtems_vector_number vector \  ) \  { \    int   minor; \    extern void mips_default_isr(int vector); \   \    for(minor=0 ; minor<Console_Port_Count ; minor++) { \      if( Console_Port_Tbl[minor].deviceType == SERIAL_MG5UART && \          vector == Console_Port_Tbl[minor].ulIntVector + _OFFSET ) { \        mg5uart_process_isr_ ## _TYPE (minor); \	return; \      } \    } \    mips_default_isr( vector ); \  }__ISR(rx_frame_error, MG5UART_IRQ_RX_FRAME_ERROR)__ISR(rx_overrun_error, MG5UART_IRQ_RX_OVERRUN_ERROR)__ISR(tx_empty, MG5UART_IRQ_TX_EMPTY)__ISR(tx_ready, MG5UART_IRQ_TX_READY)__ISR(rx_ready, MG5UART_IRQ_RX_READY)MG5UART_STATIC void mg5uart_process_isr_rx_error(   int  minor,    unsigned32 mask ){  unsigned32              pMG5UART;  int                     shift;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_IRQ_SHIFT;  else    shift = MONGOOSEV_UART1_IRQ_SHIFT;  /* now clear the error */  MG5UART_SETREG(     pMG5UART,     MG5UART_STATUS_REGISTER,     mask << shift );}MG5UART_STATIC void mg5uart_process_isr_rx_frame_error(  int  minor){   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_FRAME_ERROR );}MG5UART_STATIC void mg5uart_process_isr_rx_overrun_error(  int  minor){   mg5uart_process_isr_rx_error( minor, MONGOOSEV_UART_RX_OVERRUN_ERROR );}MG5UART_STATIC void mg5uart_process_tx_isr(   int        minor,   unsigned32 source){   unsigned32      pMG5UART;   int             shift;      pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;   mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);   if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )      shift = MONGOOSEV_UART0_IRQ_SHIFT;   else      shift = MONGOOSEV_UART1_IRQ_SHIFT;         MG5UART_SETREG(      pMG5UART,      MG5UART_STATUS_REGISTER,      source << shift );   if( rtems_termios_dequeue_characters( Console_Port_Data[minor].termios_data, 1) )   {      mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);      return;   }   /*    *  There are no more characters to transmit.  The tx interrupts are be cleared    *  by writing data to the uart, so just disable the tx interrupt sources.    */     Console_Port_Data[minor].bActive = FALSE;   /* mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX); */}MG5UART_STATIC void mg5uart_process_isr_tx_empty(  int  minor){   /* mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_EMPTY ); */}MG5UART_STATIC void mg5uart_process_isr_tx_ready(  int  minor){   mg5uart_process_tx_isr( minor, MONGOOSEV_UART_TX_READY );}MG5UART_STATIC void mg5uart_process_isr_rx_ready(  int  minor){  unsigned32              pMG5UART_port;  unsigned char           c;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  /* reading the RX buffer automatically resets the interrupt flag */  c = (unsigned char) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);  rtems_termios_enqueue_raw_characters(     Console_Port_Data[minor].termios_data,     &c, 1 );}/* *  mg5uart_initialize_interrupts * *  This routine initializes the console's receive and transmit *  ring buffers and loads the appropriate vectors to handle the interrupts. */MG5UART_STATIC void mg5uart_initialize_interrupts(int minor){  unsigned long v;  mg5uart_init(minor);  Console_Port_Data[minor].bActive = FALSE;  v = Console_Port_Tbl[minor].ulIntVector;  set_vector(mg5uart_isr_rx_frame_error,   v + MG5UART_IRQ_RX_FRAME_ERROR, 1);  set_vector(mg5uart_isr_rx_overrun_error, v + MG5UART_IRQ_RX_OVERRUN_ERROR, 1);  set_vector(mg5uart_isr_tx_empty,         v + MG5UART_IRQ_TX_EMPTY, 1);  set_vector(mg5uart_isr_tx_ready,         v + MG5UART_IRQ_TX_READY, 1);  set_vector(mg5uart_isr_rx_ready,         v + MG5UART_IRQ_RX_READY, 1);  mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL_EXCEPT_TX);}/* *  mg5uart_write_support_int * *  Console Termios output entry point when using interrupt driven output. */MG5UART_STATIC int mg5uart_write_support_int(  int         minor,  const char *buf,  int         len){  unsigned32      Irql;  unsigned32      pMG5UART_port;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  /*   *  We are using interrupt driven output and termios only sends us   *  one character at a time.   */  if ( !len )     return 0;  /*   *  Put the character out and enable interrupts if necessary.   */  rtems_interrupt_disable(Irql);  MG5UART_SETREG(pMG5UART_port, MG5UART_TX_BUFFER, *buf);  if( Console_Port_Data[minor].bActive == FALSE )   {     Console_Port_Data[minor].bActive = TRUE;     mg5uart_enable_interrupts(minor, MG5UART_ENABLE_ALL);  }  rtems_interrupt_enable(Irql);  return 1;}/* *  mg5uart_write_support_polled * *  Console Termios output entry point when using polled output. * */MG5UART_STATIC int mg5uart_write_support_polled(  int         minor,  const char *buf,  int         len){  int nwrite = 0;  /*   * poll each byte in the string out of the port.   */  while (nwrite < len)   {    mg5uart_write_polled(minor, *buf++);    nwrite++;  }  /*   * return the number of bytes written.   */  return nwrite;}/* *  mg5uart_inbyte_nonblocking_polled * *  Console Termios polling input entry point. */MG5UART_STATIC int mg5uart_inbyte_nonblocking_polled(  int minor){  unsigned32              pMG5UART;  unsigned32              pMG5UART_port;  unsigned32              status;  unsigned32              tmp,shift;  pMG5UART      = Console_Port_Tbl[minor].ulCtrlPort1;  pMG5UART_port = Console_Port_Tbl[minor].ulCtrlPort2;  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_IRQ_SHIFT;  else    shift = MONGOOSEV_UART1_IRQ_SHIFT;  /* reset overrrun or framing errors */  status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;  if( (tmp = (status & 0x3)) )  {     MG5UART_SETREG(pMG5UART, MG5UART_STATUS_REGISTER, (tmp << shift) );     status = MG5UART_GETREG(pMG5UART, MG5UART_STATUS_REGISTER) >> shift;  }  if ( status & MONGOOSEV_UART_RX_READY )   {     return (int) MG5UART_GETREG(pMG5UART_port, MG5UART_RX_BUFFER);  }   else   {     return -1;  }}/* *  mg5uart_baud_rate */MG5UART_STATIC int mg5uart_baud_rate(  int           minor,  int           baud,  unsigned int *code){  rtems_unsigned32 clock;  rtems_unsigned32 tmp_code;  rtems_unsigned32 baud_requested;  baud_requested = baud & CBAUD;  if (!baud_requested)    baud_requested = B9600;              /* default to 9600 baud */  baud_requested = termios_baud_to_number( baud_requested );  clock = (rtems_unsigned32) Console_Port_Tbl[minor].ulClock;  if (!clock)    rtems_fatal_error_occurred(RTEMS_INVALID_NUMBER);  /*   *  Formula is Code = round(ClockFrequency / Baud - 1).   *   *  Since this is integer math, we will divide by twice the baud and   *  check the remaining odd bit.   */  tmp_code = (clock / baud_requested) - 1;  /*   *  From section 12.7, "Keep C>100 for best receiver operation."   *  That is 100 cycles which is not a lot of instructions.  It is   *  reasonable to think that the Mongoose-V could not keep   *  up with C < 100.   */  if ( tmp_code < 100 )    return RTEMS_INVALID_NUMBER;  /*   *  upper word is receiver baud and lower word is transmitter baud   */  *code = (tmp_code << 16) | tmp_code;  return 0;}/* *  mg5uart_enable_interrupts * *  This function enables specific interrupt sources on the DUART. */MG5UART_STATIC void mg5uart_enable_interrupts(  int minor,  int mask){  unsigned32            pMG5UART;  unsigned32		maskSave;  unsigned32            shift;  rtems_interrupt_level  Irql;  pMG5UART = Console_Port_Tbl[minor].ulCtrlPort1;  /*   *  Enable interrupts on RX and TX -- not break   */  if ( Console_Port_Tbl[minor].ulDataPort == MG5UART_UART0 )    shift = MONGOOSEV_UART0_IRQ_SHIFT;  else    shift = MONGOOSEV_UART1_IRQ_SHIFT;  rtems_interrupt_disable(Irql);  maskSave = MG5UART_GETREG( pMG5UART, MG5UART_INTERRUPT_MASK_REGISTER );  MG5UART_SETREG(     pMG5UART,     MG5UART_INTERRUPT_MASK_REGISTER,     (maskSave & ~(MONGOOSEV_UART_ALL_STATUS_BITS << shift)) | (mask << shift) );  rtems_interrupt_enable(Irql);}/* * Flow control is only supported when using interrupts */console_fns mg5uart_fns ={  libchip_serial_default_probe,   /* deviceProbe */  mg5uart_open,                   /* deviceFirstOpen */  NULL,                           /* deviceLastClose */  NULL,                           /* deviceRead */  mg5uart_write_support_int,      /* deviceWrite */  mg5uart_initialize_interrupts,  /* deviceInitialize */  mg5uart_write_polled,           /* deviceWritePolled */  mg5uart_set_attributes,         /* deviceSetAttributes */  TRUE                            /* deviceOutputUsesInterrupts */};console_fns mg5uart_fns_polled ={  libchip_serial_default_probe,        /* deviceProbe */  mg5uart_open,                        /* deviceFirstOpen */  mg5uart_close,                       /* deviceLastClose */  mg5uart_inbyte_nonblocking_polled,   /* deviceRead */  mg5uart_write_support_polled,        /* deviceWrite */  mg5uart_init,                        /* deviceInitialize */  mg5uart_write_polled,                /* deviceWritePolled */  mg5uart_set_attributes,              /* deviceSetAttributes */  FALSE,                               /* deviceOutputUsesInterrupts */};

⌨️ 快捷键说明

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