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

📄 mc68681.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif     ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);     if(!--iTimeout) {       break;     }  }  /*   * transmit character   */  (*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);}/* *  mc68681_isr * *  This is the single interrupt entry point which parcels interrupts *  out to the various ports. */MC68681_STATIC rtems_isr mc68681_isr(  rtems_vector_number vector){  int     minor;  for(minor=0 ; minor<Console_Port_Count ; minor++) {    if(Console_Port_Tbl[minor].ulIntVector == vector &&        Console_Port_Tbl[minor].deviceType == SERIAL_MC68681 ) {      mc68681_process(minor);    }  }}/* *  mc68681_initialize_interrupts * *  This routine initializes the console's receive and transmit *  ring buffers and loads the appropriate vectors to handle the interrupts. */MC68681_STATIC void mc68681_initialize_interrupts(int minor){  mc68681_init(minor);  Console_Port_Data[minor].bActive = FALSE;  set_vector(mc68681_isr, Console_Port_Tbl[minor].ulIntVector, 1);  mc68681_enable_interrupts(minor,MC68681_IMR_ENABLE_ALL_EXCEPT_TX);}/*  *  mc68681_write_support_int * *  Console Termios output entry point when using interrupt driven output. */MC68681_STATIC int mc68681_write_support_int(  int         minor,   const char *buf,   int         len){  unsigned32      Irql;  unsigned32      pMC68681_port;  setRegister_f   setReg;  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;  setReg        = Console_Port_Tbl[minor].setRegister;  /*   *  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);    if ( Console_Port_Data[minor].bActive == FALSE ) {      Console_Port_Data[minor].bActive = TRUE;      mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL);    }    (*setReg)(pMC68681_port, MC68681_TX_BUFFER, *buf);  rtems_interrupt_enable(Irql);  return 1;}/*  *  mc68681_write_support_polled * *  Console Termios output entry point when using polled output. * */MC68681_STATIC int mc68681_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) {    /*     * transmit character     */    mc68681_write_polled(minor, *buf++);    nwrite++;  }  /*   * return the number of bytes written.   */  return nwrite;}/*  *  mc68681_inbyte_nonblocking_polled  * *  Console Termios polling input entry point. */MC68681_STATIC int mc68681_inbyte_nonblocking_polled(   int minor ){  unsigned32           pMC68681_port;  unsigned char        ucLineStatus;  unsigned char        cChar;  getRegister_f        getReg;  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;  getReg        = Console_Port_Tbl[minor].getRegister;  ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);  if(ucLineStatus & MC68681_RX_READY) {    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);    return (int)cChar;  } else {    return -1;  }}/* *  mc68681_baud_rate */MC68681_STATIC int mc68681_baud_rate(  int           minor,  int           baud,  unsigned int *baud_mask_p,  unsigned int *acr_bit_p,  unsigned int *command){  unsigned int           baud_mask;  unsigned int           acr_bit;  int                    status;  int                    is_extended;  int                    baud_requested;  mc68681_baud_table_t  *baud_tbl;  baud_mask = 0;  acr_bit = 0;  status = 0;  if (Console_Port_Tbl[minor].ulDataPort & MC68681_DATA_BAUD_RATE_SET_2)  {    acr_bit = 1;  }  is_extended = 0;  switch (Console_Port_Tbl[minor].ulDataPort & MC68681_XBRG_MASK) {    case MC68681_XBRG_IGNORED:      *command = 0x00;      break;    case MC68681_XBRG_ENABLED:      *command = 0x80;      is_extended = 1;      break;    case MC68681_XBRG_DISABLED:      *command = 0x90;      break;  }  baud_requested = baud & CBAUD;  if (!baud_requested)    baud_requested = B9600;              /* default to 9600 baud */    baud_requested = termios_baud_to_index( baud_requested );  baud_tbl = (mc68681_baud_table_t *) Console_Port_Tbl[minor].ulClock;  if (!baud_tbl)    rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS);  if ( is_extended )    baud_mask = (unsigned int)baud_tbl[ acr_bit + 2 ][ baud_requested ];  else    baud_mask = baud_tbl[ acr_bit ][ baud_requested ];  if ( baud_mask == MC68681_BAUD_NOT_VALID )    status = -1;  /*   *  upper nibble is receiver and lower nibble is transmitter   */  *baud_mask_p = (baud_mask << 4) | baud_mask;  *acr_bit_p   = acr_bit;  return status;}/* *  mc68681_process * *  This routine is the per port console interrupt handler. */MC68681_STATIC void mc68681_process(  int  minor){  unsigned32              pMC68681;  unsigned32              pMC68681_port;  volatile unsigned8      ucLineStatus;   volatile unsigned8      ucISRStatus;   unsigned char           cChar;  getRegister_f           getReg;  setRegister_f           setReg;  pMC68681      = Console_Port_Tbl[minor].ulCtrlPort1;  pMC68681_port = Console_Port_Tbl[minor].ulCtrlPort2;  getReg        = Console_Port_Tbl[minor].getRegister;  setReg        = Console_Port_Tbl[minor].setRegister;  /* Get ISR at the beginning of the IT routine */   ucISRStatus = (*getReg)(pMC68681, MC68681_INTERRUPT_STATUS_REG);    /* Get good ISR a or b channel */  if (pMC68681 != pMC68681_port){    ucISRStatus >>= 4;  }      /* See if is usefull to call rtems_termios_dequeue */  if(Console_Port_Data[minor].bActive == FALSE) {		ucISRStatus = ucISRStatus & ~MC68681_IR_TX_READY;  }  /*   * Deal with any received characters   */  while(TRUE) {    ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);    if(!(ucLineStatus & MC68681_RX_READY)) {      break;    }    /*     *  If there is a RX error, then dump all the data.     */    if ( ucLineStatus & MC68681_RX_ERRORS ) {      do {        cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);        ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);      } while ( ucLineStatus & MC68681_RX_READY );      continue;    }    cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);    rtems_termios_enqueue_raw_characters(       Console_Port_Data[minor].termios_data,      &cChar,       1     );  }  /*   *  Deal with the transmitter   */  if (ucISRStatus & MC68681_IR_TX_READY) {    if (!rtems_termios_dequeue_characters(          Console_Port_Data[minor].termios_data, 1)) {	  /* If no more char to send, disable TX interrupt */      Console_Port_Data[minor].bActive = FALSE;      mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL_EXCEPT_TX);    }  }}/* *  mc68681_build_imr * *  This function returns the value for the interrupt mask register for this *  DUART.  Since this is a shared register, we must look at the other port *  on this chip to determine whether or not it is using interrupts. */MC68681_STATIC unsigned int mc68681_build_imr(  int  minor,  int  enable_flag){  int              mate;  int              is_a;  unsigned int     mask;  unsigned int     mate_mask;  unsigned int     pMC68681;  unsigned int     pMC68681_port;  mc68681_context *pmc68681Context;  mc68681_context *mateContext;    pMC68681        = Console_Port_Tbl[minor].ulCtrlPort1;  pMC68681_port   = Console_Port_Tbl[minor].ulCtrlPort2;  pmc68681Context = (mc68681_context *) Console_Port_Data[minor].pDeviceContext;  mate            = pmc68681Context->mate;  mask = 0;  mate_mask = 0;  is_a = (pMC68681 == pMC68681_port);   /*   *  If there is a mate for this port, get its IMR mask.   */  if ( mate != -1 ) {    mateContext = Console_Port_Data[mate].pDeviceContext;        if (mateContext)      mate_mask = mateContext->imr;  }  /*   *  Calculate this port's IMR mask and save it in the context area.   */  if ( Console_Port_Tbl[minor].pDeviceFns->deviceOutputUsesInterrupts )    mask = enable_flag;  pmc68681Context->imr = mask;  /*   *  Now return the full IMR value   */  if (is_a)    return (mate_mask << 4) | mask;  return (mask << 4) | mate_mask;}/* *  mc68681_enable_interrupts * *  This function enables specific interrupt sources on the DUART. */MC68681_STATIC void mc68681_enable_interrupts(  int minor,  int imr_mask){  unsigned32            pMC68681;  setRegister_f         setReg;  pMC68681 = Console_Port_Tbl[minor].ulCtrlPort1;  setReg   = Console_Port_Tbl[minor].setRegister;  /*   *  Enable interrupts on RX and TX -- not break   */  (*setReg)(     pMC68681,     MC68681_INTERRUPT_MASK_REG,     mc68681_build_imr(minor, imr_mask)  );}

⌨️ 快捷键说明

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