sci.c
来自「RTEMS (Real-Time Executive for Multiproc」· C语言 代码 · 共 1,681 行 · 第 1/4 页
C
1,681 行
// HARDWARE LEVEL ROUTINES////////////////////////////////////////////////////////////////////////////////***************************************************************************** Func: SciSetBaud* Desc: setup the uart based on the termios modules requests* Inputs: baud rate* Outputs: none* Errors: none* Scope: private****************************************************************************/static void SciSetBaud(unsigned32 rate){ unsigned16 value; unsigned16 save_sccr1;// when you open the console you need to set the termio struct baud rate// it has a default value of 9600, when someone calls tcsetattr it reverts! SciBaud = rate; // save the rate // calculate the register value as a float and convert to an int // set baud rate - you must define the system clock constant // see efi332.h for an example value = ( (unsigned16) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff ); save_sccr1 = *SCCR1; // save register // also turns off the xmtr and rcvr *SCCR1 &= SCI_DISABLE_INT_ALL; // disable interrupts *SCCR0 = value; // write the register *SCCR1 = save_sccr1; // restore register return;}/***************************************************************************** Func: SciSetParity* Desc: setup the uart based on the termios modules requests* Inputs: parity* Outputs: none* Errors: none* Scope: private****************************************************************************/static void SciSetParity(unsigned16 parity){ unsigned16 value; value = *SCCR1; // get the register if (parity == SCI_PARITY_ODD) { value |= SCI_PARITY_ENABLE; // parity enabled value |= SCI_PARITY_ODD; // parity odd } else if (parity == SCI_PARITY_EVEN) { value |= SCI_PARITY_ENABLE; // parity enabled value &= ~SCI_PARITY_ODD; // parity even } else if (parity == SCI_PARITY_NONE) { value &= ~SCI_PARITY_ENABLE; // disabled, most common } /* else no changes */ *SCCR1 = value; // write the register return;}/***************************************************************************** Func: SciSetDataBits* Desc: setup the uart based on the termios modules requests* Inputs: data bits* Outputs: none* Errors: none* Scope: private****************************************************************************/static void SciSetDataBits(unsigned16 bits){ unsigned16 value; value = *SCCR1; // get the register /* note - the parity setting affects the number of data bits */ if (bits == SCI_9_DATA_BITS) { value |= SCI_9_DATA_BITS; // 9 data bits } else if (bits == SCI_8_DATA_BITS) { value &= SCI_8_DATA_BITS; // 8 data bits } /* else no changes */ *SCCR1 = value; // write the register return;}/***************************************************************************** Func: SciDisableAllInterrupts* Func: SciEnableTransmitInterrupts* Func: SciEnableReceiveInterrupts* Desc: handles generation of interrupts by the sci module* Inputs: none* Outputs: none* Errors: none* Scope: private****************************************************************************/static void inline SciDisableAllInterrupts( void ){ // this also turns off the xmtr and rcvr *SCCR1 &= SCI_DISABLE_INT_ALL;}static void inline SciEnableReceiveInterrupts( void ){ *SCCR1 |= SCI_ENABLE_INT_RX;}static void inline SciDisableReceiveInterrupts( void ){ *SCCR1 &= SCI_DISABLE_INT_RX;}static void inline SciEnableTransmitInterrupts( void ){ *SCCR1 |= SCI_ENABLE_INT_TX;}static void inline SciDisableTransmitInterrupts( void ){ *SCCR1 &= SCI_DISABLE_INT_TX;}/***************************************************************************** Func: SciEnableTransmitter, SciDisableTransmitter* Func: SciEnableReceiver, SciDisableReceiver* Desc: turns the transmitter and receiver on and off* Inputs: none* Outputs: none* Errors: none* Scope: private****************************************************************************/static void inline SciEnableTransmitter( void ){ *SCCR1 |= SCI_ENABLE_XMTR;}static void inline SciDisableTransmitter( void ){ *SCCR1 &= SCI_DISABLE_XMTR;}static void inline SciEnableReceiver( void ){ *SCCR1 |= SCI_ENABLE_RCVR;}static void inline SciDisableReceiver( void ){ *SCCR1 &= SCI_DISABLE_RCVR;}/***************************************************************************** Func: SciWriteCharWait* Desc: wait for room in the fifo and then put a char in* Inputs: a byte to send* Outputs: none* Errors: none* Scope: public****************************************************************************/void SciWriteCharWait(unsigned8 c){ // poll the fifo, waiting for room for another character while ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) { /* Either we are writing to the fifo faster than * the uart can clock bytes out onto the cable, * or we are in flow control (actually no, we * are ignoring flow control from the other end). * In the first case, higher baud rates will help. */ /* relinquish processor while waiting */ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); } *SCDR = c; // send the charcter SciBytesOut++; // increment the counter return;}/***************************************************************************** Func: SciWriteCharNoWait* Desc: if no room in the fifo throw the char on the floor* Inputs: a byte to send* Outputs: none* Errors: none* Scope: public****************************************************************************/void SciWriteCharNoWait(unsigned8 c){ if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) { return; // no room, throw it away } *SCDR = c; // put the char in the fifo SciBytesOut++; // increment the counter return;}/***************************************************************************** Func: SciReadCharWait* Desc: read a character, waiting for one to show up, if need be* Inputs: none* Outputs: a character* Errors: none* Scope: public****************************************************************************/unsigned8 inline SciReadCharWait( void ){ unsigned8 ch; while ( SciCharAvailable() == 0 ) // anything there? { /* relinquish processor while waiting */ rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); } // if you have rcv ints enabled, then the isr will probably // get the character before you will unless you turn off ints // ie polling and ints don't mix that well ch = *SCDR; // get the charcter SciBytesIn++; // increment the counter return ch; // return the char}/***************************************************************************** Func: SciReadCharNoWait* Desc: try to get a char but dont wait for one* Inputs: none* Outputs: a character or -1 if none* Errors: none* Scope: public****************************************************************************/unsigned8 inline SciReadCharNoWait( void ){ unsigned8 ch; if ( SciCharAvailable() == 0 ) // anything there? return -1; ch = *SCDR; // get the character SciBytesIn++; // increment the count return ch; // return the char}/***************************************************************************** Func: SciCharAvailable* Desc: is there a receive character in the data register* Inputs: none* Outputs: false if no char available, else true* Errors: none* Scope: public****************************************************************************/unsigned8 inline SciCharAvailable( void ){ return ( *SCSR & SCI_RCVR_READY ); // char in data register?}/***************************************************************************** Func: SciSendBreak* Desc: send 1 or tow breaks (all zero bits)* Inputs: none* Outputs: none* Errors: none* Scope: public****************************************************************************/void SciSendBreak( void ){ // From the Motorola QSM reference manual - // "if SBK is toggled by writing it first to a one and then immediately // to a zero (in less than one serial frame interval), the transmitter // sends only one or two break frames before reverting to mark (idle) // or before commencing to send more data" *SCCR1 |= SCI_SEND_BREAK; // set the bit *SCCR1 &= ~SCI_SEND_BREAK; // clear the bit return;}///////////////////////////////////////////////////////////////////////////////// SECTION 6// TEST CODE////////////////////////////////////////////////////////////////////////////////***************************************************************************** Func: SciUnitTest* Desc: test the device driver* Inputs: nothing* Outputs: nothing* Scope: public****************************************************************************/#if 0#define O_RDWR LIBIO_FLAGS_READ_WRITE // dont like this but...void SciUnitTest(){ unsigned8 byte; // a character unsigned16 fd; // file descriptor for device unsigned16 result; // result of ioctl fd = open("/dev/sci",O_RDWR); // open the deviceprintk("SCI open fd=%d\r\n",fd); result = write(fd, "abcd\r\n", 6); // send a stringprintk("SCI write result=%d\r\n",result); result = read(fd, &byte, 1); // read a byteprintk("SCI read result=%d,byte=%x\r\n",result,byte); return;}#endif/***************************************************************************** Func: SciPrintStats* Desc: print out some driver information* Inputs: nothing* Outputs: nothing* Scope: public****************************************************************************/void SciPrintStats ( void ){ printk("\r\n"); printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 ); printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 ); printk( "SCI Uart chars in %8d\r\n", SciBytesIn ); printk( "SCI Uart chars out %8d\r\n", SciBytesOut ); printk( "SCI Uart framing errors %8d\r\n", SciErrorsFraming ); printk( "SCI Uart parity errors %8d\r\n", SciErrorsParity ); printk( "SCI Uart overrun errors %8d\r\n", SciErrorsOverrun ); printk( "SCI Uart noise errors %8d\r\n", SciErrorsNoise ); return;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?