sci.c
来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 1,681 行 · 第 1/4 页
C
1,681 行
if (rtems_termios_dequeue_characters( SciTermioTty, 1 )) { // there are more bytes to transmit so enable TX interrupt SciEnableTransmitInterrupts(); } } // see if it was a receive interrupt // on the sci uart we just get one character per interrupt while ( SciCharAvailable() ) // char in data register? { ch = SciReadCharNoWait(); // get the char from the uart // IMPORTANT!!! // either send it to the termios module or keep it locally if ( SciOpened == DRIVER_OPENED ) // the driver is open { SciRcvBufPutChar(ch); // keep it locally } else // put in termios buffer { rtems_termios_enqueue_raw_characters( SciTermioTty, &ch, 1 ); } *SCSR &= SCI_CLEAR_RX_INT; // clear the interrupt }}///////////////////////////////////////////////////////////////////////////////// SECTION 1// ROUTINES TO MANIPULATE THE CIRCULAR BUFFER////////////////////////////////////////////////////////////////////////////////***************************************************************************** Func: SciRcvBufGetChar* Desc: read a character from the circular buffer* make sure there is data before you call this!* Inputs: none* Outputs: the character or -1* Errors: none* Scope: private****************************************************************************/static signed8 SciRcvBufGetChar(){ rtems_interrupt_level level; unsigned8 ch; if ( SciRcvBufCount == 0 ) { rtems_fatal_error_occurred(0xDEAD); // check the count first! } rtems_interrupt_disable( level ); // disable interrupts ch = SciRcvBuffer[SciRcvBufGetIndex]; // get next byte SciRcvBufGetIndex++; // bump the index SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; // and wrap it SciRcvBufCount--; // decrement counter rtems_interrupt_enable( level ); // restore interrupts return ch; // return the char}/***************************************************************************** Func: SciRcvBufPutChar* Desc: put a character into the rcv data circular buffer* Inputs: the character* Outputs: none* Errors: none* Scope: private****************************************************************************/static void SciRcvBufPutChar( unsigned8 ch ){ rtems_interrupt_level level; if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) // is there room? { return; // no, throw it away } rtems_interrupt_disable( level ); // disable interrupts SciRcvBuffer[SciRcvBufPutIndex] = ch; // put it in the buf SciRcvBufPutIndex++; // bump the index SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; // and wrap it SciRcvBufCount++; // increment counter rtems_interrupt_enable( level ); // restore interrupts return; // return}/***************************************************************************** Func: SciRcvBufFlush* Desc: completely reset and clear the rcv buffer* Inputs: none* Outputs: none* Errors: none* Scope: private****************************************************************************/#if 0 // prevents compiler warningstatic void SciRcvBufFlush( void ){ rtems_interrupt_level level; rtems_interrupt_disable( level ); // disable interrupts memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) ); SciRcvBufPutIndex = 0; // clear SciRcvBufGetIndex = 0; // clear SciRcvBufCount = 0; // clear rtems_interrupt_enable( level ); // restore interrupts return; // return}#endif///////////////////////////////////////////////////////////////////////////////// SECTION 2// INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE////////////////////////////////////////////////////////////////////////////////***************************************************************************** Func: SciInterruptOpen* Desc: open routine for the interrupt based device driver* Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ??**CHANGED** Default baud rate is now 19200, 8N1* called from rtems_termios_open which is called from console_open* Inputs: major - device number* minor - device number* args - points to terminal info* Outputs: success/fail* Errors: none* Scope: public API****************************************************************************/signed32 SciInterruptOpen( signed32 major, signed32 minor, void *arg){ rtems_libio_open_close_args_t * args = arg; rtems_isr_entry old_vector; if ( minor != SCI_MINOR ) // check minor device num { return -1; } if ( !args ) // must have args { return -1; } SciTermioTty = args->iop->data1; // save address of struct SciDisableAllInterrupts(); // turn off sci interrupts // THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE // IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!!// SciSetBaud(115200); // set the baud rate// SciSetBaud( 57600); // set the baud rate// SciSetBaud( 38400); // set the baud rateSciSetBaud( 19200); // set the baud rate// SciSetBaud( 9600); // set the baud rate SciSetParity(SCI_PARITY_NONE); // set parity to none SciSetDataBits(SCI_8_DATA_BITS); // set data bits to 8 // Install our interrupt handler into RTEMS, where does 66 come from? rtems_interrupt_catch( SciIsr, 66, &old_vector ); *QIVR = 66; *QIVR &= 0xf8; *QILR |= 0x06 & 0x07; SciEnableTransmitter(); // enable the transmitter SciEnableReceiver(); // enable the receiver SciEnableReceiveInterrupts(); // enable rcv interrupts return RTEMS_SUCCESSFUL;}/***************************************************************************** Func: SciInterruptClose* Desc: close routine called by the termios module* Inputs: major - device number* minor - device number* args - unused* Outputs: success/fail* Errors: none* Scope: public - termio entry point****************************************************************************/signed32 SciInterruptClose( signed32 major, signed32 minor, void *arg){ SciDisableAllInterrupts(); return RTEMS_SUCCESSFUL;}/***************************************************************************** Func: SciInterruptWrite* Desc: writes data to the uart using transmit interrupts* Inputs: minor - device number* buf - points to the data* len - number of bytes to send* Outputs: success/fail* Errors: none* Scope: public API****************************************************************************/signed32 SciInterruptWrite( signed32 minor, const char *buf, signed32 len){ // We are using interrupt driven output so termios only sends us // one character at a time. The sci does not have a fifo. if ( !len ) // no data? { return 0; // return error } if ( minor != SCI_MINOR ) // check the minor dev num { return 0; // return error } if ( SciOpened == DRIVER_OPENED ) // is the driver api open? { return 1; // yep, throw this away } SciWriteCharNoWait(*buf); // try to send a char *SCSR &= SCI_CLEAR_TDRE; // clear tx data reg empty flag SciEnableTransmitInterrupts(); // enable the tx interrupt return 1; // return success}/***************************************************************************** Func: SciSetAttributes* Desc: setup the uart based on the termios modules requests* Inputs: minor - device number* t - pointer to the termios info struct* Outputs: none* Errors: none* Scope: public API****************************************************************************/signed32 SciSetAttributes( signed32 minor, const struct termios *t){ unsigned32 baud_requested; unsigned32 sci_rate = 0; unsigned16 sci_parity = 0; unsigned16 sci_databits = 0; if ( minor != SCI_MINOR ) // check the minor dev num { return -1; // return error } // if you look closely you will see this is the only thing we use // set the baud rate baud_requested = t->c_cflag & CBAUD; // baud rate if (!baud_requested) {// baud_requested = B9600; // default to 9600 baud baud_requested = B19200; // default to 19200 baud } sci_rate = termios_baud_to_number( baud_requested ); // parity error detection if (t->c_cflag & PARENB) // enable parity detection? { if (t->c_cflag & PARODD) { sci_parity = SCI_PARITY_ODD; // select odd parity } else { sci_parity = SCI_PARITY_EVEN; // select even parity } } else { sci_parity = SCI_PARITY_NONE; // no parity, most common } // set the number of data bits, 8 is most common if (t->c_cflag & CSIZE) // was it specified? { switch (t->c_cflag & CSIZE) { case CS8: sci_databits = SCI_8_DATA_BITS; break; default : sci_databits = SCI_9_DATA_BITS; break; } } else { sci_databits = SCI_8_DATA_BITS; // default to 8 data bits } // the number of stop bits; always 1 for SCI if (t->c_cflag & CSTOPB) { // do nothing } // setup the hardware with these serial port parameters SciSetBaud(sci_rate); // set the baud rate SciSetParity(sci_parity); // set the parity type SciSetDataBits(sci_databits); // set the data bits return RTEMS_SUCCESSFUL;}///////////////////////////////////////////////////////////////////////////////// SECTION 3// POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE////////////////////////////////////////////////////////////////////////////////***************************************************************************** Func: SciPolledOpen* Desc: open routine for the polled i/o version of the driver* called from rtems_termios_open which is called from console_open* Inputs: major - device number* minor - device number* args - points to terminal info struct* Outputs: success/fail* Errors: none* Scope: public - termios entry point****************************************************************************/signed32 SciPolledOpen( signed32 major, signed32 minor, void *arg){ rtems_libio_open_close_args_t * args = arg; if ( minor != SCI_MINOR ) // check minor device num { return -1; } if ( !args ) // must have args { return -1; } SciTermioTty = args->iop->data1; // Store tty pointer SciDisableAllInterrupts(); // don't generate interrupts
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?