![]() |
|
|||
File indexing completed on 2025-05-11 08:23:47
0001 /***************************************************************************** 0002 * File: sci.c 0003 * 0004 * Desc: This file contains the console IO routines for the SCI port. 0005 * There are two interfaces in this module. One is for the rtems 0006 * termios/console code and the other is a device driver interface. 0007 * This module works together with the termio module which is 0008 * sometimes referred to as the "line disciplines" which implements 0009 * terminal i/o processing like tabs, backspaces, and newlines. 0010 * The rtems printf uses interrupt io and the rtems printk routine 0011 * uses polled io which is better for debugging. 0012 * 0013 * Index: Documentation 0014 * Section A - Include Files 0015 * Section B - Manifest Constants 0016 * Section C - External Data 0017 * Section D - External Functions 0018 * Section E - Local Functions 0019 * Section F - Local Variables 0020 * Section G - A circular data buffer for rcv chars 0021 * Section H - RTEMS termios callbacks for the interrupt api 0022 * Section I - RTEMS termios callbacks for the polled api 0023 0024 * Section 0 - Miscellaneous routines 0025 * Section 1 - Routines to manipulate the circular buffer 0026 * Section 2 - Interrupt based entry points for the termios module 0027 * Section 3 - Polling based entry points for the termios module 0028 * Section 4 - Device driver public api entry points 0029 * Section 5 - Hardware level routines 0030 * Section 6 - Testing and debugging code 0031 * 0032 * Refer: Motorola QSM Reference Manual - Chapter 5 - SCI sub-module 0033 * 0034 * Note: See bsp.h,confdefs.h,system.h for installing drivers into RTEMS. 0035 * 0036 *****************************************************************************/ 0037 0038 /***************************************************************************** 0039 Overview of serial port console terminal input/output 0040 *****************************************************************************/ 0041 0042 /* 0043 +-----------+ +---------+ 0044 | app | | app | 0045 +-----------+ +---------+ 0046 | | 0047 | (printf,scanf,etc.) | 0048 v | 0049 +-----------+ | 0050 | libc | | 0051 +-----------+ | 0052 | | 0053 | | 0054 | (open,close,read,write,ioctl) | 0055 ======|==========================================|======================== 0056 | /dev/console | /dev/sci 0057 | (stdin,stdout,stderr) | 0058 ======|==========================================|======================== 0059 | | 0060 | | 0061 v v 0062 +-----------+ +-----------+ +---------+ 0063 | console | <---> | termios | <---> | sci | 0064 | driver | | module | | driver | 0065 +-----------+ +-----------+ +---------+ 0066 | 0067 | 0068 v 0069 +---------+ 0070 | | 0071 | uart | 0072 | | 0073 +---------+ 0074 */ 0075 0076 0077 /***************************************************************************** 0078 Section A - Include Files 0079 *****************************************************************************/ 0080 0081 #include <rtems.h> 0082 #include <bsp.h> 0083 #include <rtems/bspIo.h> 0084 #include <stdio.h> 0085 #include <rtems/libio.h> 0086 #include <libchip/serial.h> 0087 #include <libchip/sersupp.h> 0088 #include "sci.h" 0089 #include <rtems/m68k/qsm.h> 0090 #include <inttypes.h> 0091 /*#include "../misc/include/cpu332.h" */ 0092 0093 /***************************************************************************** 0094 Section B - Manifest Constants 0095 *****************************************************************************/ 0096 0097 #define SCI_MINOR 0 /* minor device number */ 0098 0099 /* IMPORTANT - if the device driver api is opened, it means the sci is being 0100 * used for direct hardware access, so other users (like termios) get ignored 0101 */ 0102 #define DRIVER_CLOSED 0 /* the device driver api is closed */ 0103 #define DRIVER_OPENED 1 /* the device driver api is opened */ 0104 0105 /* system clock definitions, i dont have documentation on this... */ 0106 0107 #if 0 /* Not needed, this is provided in mrm332.h */ 0108 #define XTAL 32768.0 /* crystal frequency in Hz */ 0109 #define NUMB_W 0 /* system clock parameters */ 0110 #define NUMB_X 1 0111 #define NUMB_Y 0x38 /* for 14.942 Mhz */ 0112 #define NUMB_Y 0x3F /* for 16.777 Mhz */ 0113 0114 #define SYS_CLOCK (XTAL * 4.0 * (NUMB_Y+1) * (1 << (2 * NUMB_W + NUMB_X))) 0115 0116 #endif 0117 0118 0119 /***************************************************************************** 0120 Section C - External Data 0121 *****************************************************************************/ 0122 0123 0124 0125 /***************************************************************************** 0126 Section D - External Functions 0127 *****************************************************************************/ 0128 0129 0130 0131 /***************************************************************************** 0132 Section E - Local Functions 0133 *****************************************************************************/ 0134 0135 void SCI_output_char(char c); 0136 0137 /*rtems_isr SciIsr( rtems_vector_number vector ); interrupt handler */ 0138 0139 const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ); 0140 0141 rtems_device_driver SciInitialize( /* device driver api */ 0142 rtems_device_major_number, rtems_device_minor_number, void *); 0143 rtems_device_driver SciOpen( /* device driver api */ 0144 rtems_device_major_number, rtems_device_minor_number, void *); 0145 rtems_device_driver SciClose( /* device driver api */ 0146 rtems_device_major_number, rtems_device_minor_number, void *); 0147 rtems_device_driver SciRead( /* device driver api */ 0148 rtems_device_major_number, rtems_device_minor_number, void *); 0149 rtems_device_driver SciWrite( /* device driver api */ 0150 rtems_device_major_number, rtems_device_minor_number, void *); 0151 rtems_device_driver SciControl( /* device driver api */ 0152 rtems_device_major_number, rtems_device_minor_number, void *); 0153 rtems_device_driver SciRead ( 0154 rtems_device_major_number, rtems_device_minor_number, void *); 0155 0156 rtems_isr SciIsr( rtems_vector_number vector ); 0157 0158 int SciInterruptOpen(int, int, void *); /* termios api */ 0159 int SciInterruptClose(int, int, void *); /* termios api */ 0160 ssize_t SciInterruptWrite(int, const char *, size_t); /* termios api */ 0161 0162 int SciSetAttributes(int, const struct termios*); /* termios api */ 0163 int SciPolledOpen(int, int, void *); /* termios api */ 0164 int SciPolledClose(int, int, void *); /* termios api */ 0165 int SciPolledRead(int); /* termios api */ 0166 ssize_t SciPolledWrite(int, const char *, size_t); /* termios api */ 0167 0168 static void SciSetBaud(uint32_t rate); /* hardware routine */ 0169 static void SciSetDataBits(uint16_t bits); /* hardware routine */ 0170 static void SciSetParity(uint16_t parity); /* hardware routine */ 0171 0172 static void inline SciDisableAllInterrupts( void ); /* hardware routine */ 0173 static void inline SciDisableTransmitInterrupts( void );/* hardware routine */ 0174 static void inline SciDisableReceiveInterrupts( void ); /* hardware routine */ 0175 0176 static void inline SciEnableTransmitInterrupts( void ); /* hardware routine */ 0177 static void inline SciEnableReceiveInterrupts( void ); /* hardware routine */ 0178 0179 static void inline SciDisableReceiver( void ); /* hardware routine */ 0180 static void inline SciDisableTransmitter( void ); /* hardware routine */ 0181 0182 static void inline SciEnableReceiver( void ); /* hardware routine */ 0183 static void inline SciEnableTransmitter( void ); /* hardware routine */ 0184 0185 void SciWriteCharWait ( uint8_t ); /* hardware routine */ 0186 void SciWriteCharNoWait( uint8_t ); /* hardware routine */ 0187 0188 uint8_t inline SciCharAvailable( void ); /* hardware routine */ 0189 0190 static uint8_t inline SciReadCharWait( void ); /* hardware routine */ 0191 static uint8_t inline SciReadCharNoWait( void ); /* hardware routine */ 0192 0193 void SciSendBreak( void ); /* test routine */ 0194 0195 static int8_t SciRcvBufGetChar(void); /* circular rcv buf */ 0196 static void SciRcvBufPutChar( uint8_t); /* circular rcv buf */ 0197 #if 0 0198 static void SciRcvBufFlush( void ); /* unused routine */ 0199 #endif 0200 0201 void SciUnitTest(void); /* test routine */ 0202 void SciPrintStats(void); /* test routine */ 0203 0204 0205 /***************************************************************************** 0206 Section F - Local Variables 0207 *****************************************************************************/ 0208 0209 static struct rtems_termios_tty *SciTermioTty; 0210 0211 static uint8_t SciInited = 0; /* has the driver been inited */ 0212 0213 static uint8_t SciOpened; /* has the driver been opened */ 0214 0215 static uint8_t SciMajor; /* major device number */ 0216 0217 static uint16_t SciBaud; /* current value in baud register */ 0218 0219 static uint32_t SciBytesIn = 0; /* bytes received */ 0220 static uint32_t SciBytesOut = 0; /* bytes transmitted */ 0221 0222 static uint32_t SciErrorsParity = 0; /* error counter */ 0223 static uint32_t SciErrorsNoise = 0; /* error counter */ 0224 static uint32_t SciErrorsFraming = 0; /* error counter */ 0225 static uint32_t SciErrorsOverrun = 0; /* error counter */ 0226 0227 #if defined(CONSOLE_SCI) 0228 0229 /* this is what rtems printk uses to do polling based output */ 0230 0231 BSP_output_char_function_type BSP_output_char = SCI_output_char; 0232 BSP_polling_getchar_function_type BSP_poll_char = NULL; 0233 0234 #endif 0235 0236 /***************************************************************************** 0237 Section G - A circular buffer for rcv chars when the driver interface is used. 0238 *****************************************************************************/ 0239 0240 /* it is trivial to wrap your buffer pointers when size is a power of two */ 0241 0242 #define SCI_RCV_BUF_SIZE 256 /* must be a power of 2 !!! */ 0243 0244 /* if someone opens the sci device using the device driver interface, 0245 * then the receive data interrupt handler will put characters in this buffer 0246 * instead of sending them up to the termios module for the console 0247 */ 0248 static uint8_t SciRcvBuffer[SCI_RCV_BUF_SIZE]; 0249 0250 static uint8_t SciRcvBufPutIndex = 0; /* array index to put in next char */ 0251 0252 static uint8_t SciRcvBufGetIndex = 0; /* array index to take out next char */ 0253 0254 static uint16_t SciRcvBufCount = 0; /* how many bytes are in the buffer */ 0255 0256 0257 0258 /***************************************************************************** 0259 Section H - RTEMS termios callbacks for the interrupt version of the driver 0260 *****************************************************************************/ 0261 0262 static const rtems_termios_callbacks SciInterruptCallbacks = 0263 { 0264 SciInterruptOpen, /* first open */ 0265 SciInterruptClose, /* last close */ 0266 NULL, /* polled read (not required) */ 0267 SciInterruptWrite, /* write */ 0268 SciSetAttributes, /* set attributes */ 0269 NULL, /* stop remote xmit */ 0270 NULL, /* start remote xmit */ 0271 TERMIOS_IRQ_DRIVEN /* output uses interrupts */ 0272 }; 0273 0274 /***************************************************************************** 0275 Section I - RTEMS termios callbacks for the polled version of the driver 0276 *****************************************************************************/ 0277 0278 static const rtems_termios_callbacks SciPolledCallbacks = 0279 { 0280 SciPolledOpen, /* first open */ 0281 SciPolledClose, /* last close */ 0282 SciPolledRead, /* polled read */ 0283 SciPolledWrite, /* write */ 0284 SciSetAttributes, /* set attributes */ 0285 NULL, /* stop remote xmit */ 0286 NULL, /* start remote xmit */ 0287 TERMIOS_POLLED /* output uses interrupts */ 0288 }; 0289 0290 0291 /* 0292 * SECTION 0 0293 * MISCELLANEOUS ROUTINES 0294 */ 0295 0296 /**************************************************************************** 0297 * Func: SCI_output_char 0298 * Desc: used by rtems printk function to send a char to the uart 0299 * Inputs: the character to transmit 0300 * Outputs: none 0301 * Errors: none 0302 * Scope: public 0303 ****************************************************************************/ 0304 0305 void SCI_output_char(char c) 0306 { 0307 /* ( minor device number, pointer to the character, length ) */ 0308 0309 SciPolledWrite( SCI_MINOR, &c, 1); 0310 0311 return; 0312 } 0313 0314 0315 /**************************************************************************** 0316 * Func: SciGetTermiosHandlers 0317 * Desc: returns a pointer to the table of serial io functions 0318 * this is called from console_open with polled set to false 0319 * Inputs: flag indicating whether we want polled or interrupt driven io 0320 * Outputs: pointer to function table 0321 * Errors: none 0322 * Scope: public 0323 ****************************************************************************/ 0324 0325 const rtems_termios_callbacks * SciGetTermiosHandlers( int32_t polled ) 0326 { 0327 if ( polled ) 0328 { 0329 return &SciPolledCallbacks; /* polling based */ 0330 } 0331 else 0332 { 0333 return &SciInterruptCallbacks; /* interrupt driven */ 0334 } 0335 } 0336 0337 0338 /**************************************************************************** 0339 * Func: SciIsr 0340 * Desc: interrupt handler for serial communications interface 0341 * Inputs: vector number - unused 0342 * Outputs: none 0343 * Errors: none 0344 * Scope: public API 0345 ****************************************************************************/ 0346 0347 rtems_isr SciIsr( rtems_vector_number vector ) 0348 { 0349 uint8_t ch; 0350 0351 if ( (*SCSR) & SCI_ERROR_PARITY ) SciErrorsParity ++; 0352 if ( (*SCSR) & SCI_ERROR_FRAMING ) SciErrorsFraming ++; 0353 if ( (*SCSR) & SCI_ERROR_NOISE ) SciErrorsNoise ++; 0354 if ( (*SCSR) & SCI_ERROR_OVERRUN ) SciErrorsOverrun ++; 0355 0356 /* see if it was a transmit interrupt */ 0357 /* data reg empty, xmt complete */ 0358 if ( ( *SCCR1 & SCI_ENABLE_INT_TX ) && ( (*SCSR) & SCI_XMTR_AVAILABLE ) ) 0359 { 0360 SciDisableTransmitInterrupts(); 0361 0362 /* tell termios module that the charcter was sent */ 0363 /* he will call us later to transmit more if there are any */ 0364 0365 if (rtems_termios_dequeue_characters( SciTermioTty, 1 )) 0366 { 0367 /* there are more bytes to transmit so enable TX interrupt */ 0368 0369 SciEnableTransmitInterrupts(); 0370 } 0371 } 0372 0373 /* see if it was a receive interrupt */ 0374 /* on the sci uart we just get one character per interrupt */ 0375 0376 while ( SciCharAvailable() ) /* char in data register? */ 0377 { 0378 ch = SciReadCharNoWait(); /* get the char from the uart */ 0379 0380 /* IMPORTANT!!! */ 0381 /* either send it to the termios module or keep it locally */ 0382 0383 if ( SciOpened == DRIVER_OPENED ) /* the driver is open */ 0384 { 0385 SciRcvBufPutChar(ch); /* keep it locally */ 0386 } 0387 else /* put in termios buffer */ 0388 { 0389 char c = (char) ch; 0390 rtems_termios_enqueue_raw_characters( SciTermioTty, &c, 1 ); 0391 } 0392 0393 *SCSR &= SCI_CLEAR_RX_INT; /* clear the interrupt */ 0394 } 0395 } 0396 0397 0398 /* 0399 * SECTION 1 0400 * ROUTINES TO MANIPULATE THE CIRCULAR BUFFER 0401 */ 0402 0403 /**************************************************************************** 0404 * Func: SciRcvBufGetChar 0405 * Desc: read a character from the circular buffer 0406 * make sure there is data before you call this! 0407 * Inputs: none 0408 * Outputs: the character or -1 0409 * Errors: none 0410 * Scope: private 0411 ****************************************************************************/ 0412 0413 static int8_t SciRcvBufGetChar(void) 0414 { 0415 rtems_interrupt_level level; 0416 uint8_t ch; 0417 0418 if ( SciRcvBufCount == 0 ) 0419 { 0420 rtems_fatal_error_occurred(0xDEAD); /* check the count first! */ 0421 } 0422 0423 rtems_interrupt_disable( level ); /* disable interrupts */ 0424 0425 ch = SciRcvBuffer[SciRcvBufGetIndex]; /* get next byte */ 0426 0427 SciRcvBufGetIndex++; /* bump the index */ 0428 0429 SciRcvBufGetIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ 0430 0431 SciRcvBufCount--; /* decrement counter */ 0432 0433 rtems_interrupt_enable( level ); /* restore interrupts */ 0434 0435 return ch; /* return the char */ 0436 } 0437 0438 0439 /**************************************************************************** 0440 * Func: SciRcvBufPutChar 0441 * Desc: put a character into the rcv data circular buffer 0442 * Inputs: the character 0443 * Outputs: none 0444 * Errors: none 0445 * Scope: private 0446 ****************************************************************************/ 0447 0448 static void SciRcvBufPutChar( uint8_t ch ) 0449 { 0450 rtems_interrupt_level level; 0451 0452 if ( SciRcvBufCount == SCI_RCV_BUF_SIZE ) /* is there room? */ 0453 { 0454 return; /* no, throw it away */ 0455 } 0456 0457 rtems_interrupt_disable( level ); /* disable interrupts */ 0458 0459 SciRcvBuffer[SciRcvBufPutIndex] = ch; /* put it in the buf */ 0460 0461 SciRcvBufPutIndex++; /* bump the index */ 0462 0463 SciRcvBufPutIndex &= SCI_RCV_BUF_SIZE - 1; /* and wrap it */ 0464 0465 SciRcvBufCount++; /* increment counter */ 0466 0467 rtems_interrupt_enable( level ); /* restore interrupts */ 0468 0469 return; /* return */ 0470 } 0471 0472 0473 /**************************************************************************** 0474 * Func: SciRcvBufFlush 0475 * Desc: completely reset and clear the rcv buffer 0476 * Inputs: none 0477 * Outputs: none 0478 * Errors: none 0479 * Scope: private 0480 ****************************************************************************/ 0481 0482 #if 0 /* prevents compiler warning */ 0483 static void SciRcvBufFlush( void ) 0484 { 0485 rtems_interrupt_level level; 0486 0487 rtems_interrupt_disable( level ); /* disable interrupts */ 0488 0489 memset( SciRcvBuffer, 0, sizeof(SciRcvBuffer) ); 0490 0491 SciRcvBufPutIndex = 0; /* clear */ 0492 0493 SciRcvBufGetIndex = 0; /* clear */ 0494 0495 SciRcvBufCount = 0; /* clear */ 0496 0497 rtems_interrupt_enable( level ); /* restore interrupts */ 0498 0499 return; /* return */ 0500 } 0501 #endif 0502 0503 0504 /* 0505 * 0506 * SECTION 2 0507 * INTERRUPT BASED ENTRY POINTS FOR THE TERMIOS MODULE 0508 */ 0509 0510 /**************************************************************************** 0511 * Func: SciInterruptOpen 0512 * Desc: open routine for the interrupt based device driver 0513 * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit. ?? 0514 **CHANGED** Default baud rate is now 19200, 8N1 0515 * called from rtems_termios_open which is called from console_open 0516 * Inputs: major - device number 0517 * minor - device number 0518 * args - points to terminal info 0519 * Outputs: success/fail 0520 * Errors: none 0521 * Scope: public API 0522 ****************************************************************************/ 0523 0524 int SciInterruptOpen( 0525 int major, 0526 int minor, 0527 void *arg 0528 ) 0529 { 0530 rtems_libio_open_close_args_t * args = arg; 0531 rtems_isr_entry old_vector; 0532 0533 if ( minor != SCI_MINOR ) /* check minor device num */ 0534 { 0535 return -1; 0536 } 0537 0538 if ( !args ) /* must have args */ 0539 { 0540 return -1; 0541 } 0542 0543 SciTermioTty = args->iop->data1; /* save address of struct */ 0544 0545 SciDisableAllInterrupts(); /* turn off sci interrupts */ 0546 0547 /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ 0548 /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ 0549 0550 /* SciSetBaud(115200); set the baud rate */ 0551 /* SciSetBaud( 57600); set the baud rate */ 0552 /* SciSetBaud( 38400); set the baud rate */ 0553 /* SciSetBaud( 19200); set the baud rate */ 0554 SciSetBaud( 9600); /* set the baud rate */ 0555 0556 SciSetParity(SCI_PARITY_NONE); /* set parity to none */ 0557 0558 SciSetDataBits(SCI_8_DATA_BITS); /* set data bits to 8 */ 0559 0560 /* Install our interrupt handler into RTEMS. */ 0561 /* 68 is an unused user-defined vector. Note that the vector must be */ 0562 /* even - it sets the low bit for SPI interrupts, and clears it for */ 0563 /* SCI interrupts. Also note that vector 66 is used by CPU32bug on */ 0564 /* the mrm332. */ 0565 0566 rtems_interrupt_catch( SciIsr, 68, &old_vector ); 0567 0568 *QSMCR = (*QSMCR & ~IARB) | 1; // Is 1 a good value for qsm iarb? 0569 *QIVR = 68; 0570 *QILR &= 0xf8; 0571 *QILR |= 0x06 & 0x07; 0572 0573 SciEnableTransmitter(); /* enable the transmitter */ 0574 0575 SciEnableReceiver(); /* enable the receiver */ 0576 0577 SciEnableReceiveInterrupts(); /* enable rcv interrupts */ 0578 0579 return RTEMS_SUCCESSFUL; 0580 } 0581 0582 0583 /**************************************************************************** 0584 * Func: SciInterruptClose 0585 * Desc: close routine called by the termios module 0586 * Inputs: major - device number 0587 * minor - device number 0588 * args - unused 0589 * Outputs: success/fail 0590 * Errors: none 0591 * Scope: public - termio entry point 0592 ****************************************************************************/ 0593 0594 int SciInterruptClose( 0595 int major, 0596 int minor, 0597 void *arg 0598 ) 0599 { 0600 SciDisableAllInterrupts(); 0601 0602 return RTEMS_SUCCESSFUL; 0603 } 0604 0605 0606 /**************************************************************************** 0607 * Func: SciInterruptWrite 0608 * Desc: writes data to the uart using transmit interrupts 0609 * Inputs: minor - device number 0610 * buf - points to the data 0611 * len - number of bytes to send 0612 * Outputs: success/fail 0613 * Errors: none 0614 * Scope: public API 0615 ****************************************************************************/ 0616 0617 ssize_t SciInterruptWrite( 0618 int minor, 0619 const char *buf, 0620 size_t len 0621 ) 0622 { 0623 /* We are using interrupt driven output so termios only sends us */ 0624 /* one character at a time. The sci does not have a fifo. */ 0625 0626 if ( !len ) /* no data? */ 0627 { 0628 return -1; /* return error */ 0629 } 0630 0631 if ( minor != SCI_MINOR ) /* check the minor dev num */ 0632 { 0633 return -1; /* return error */ 0634 } 0635 0636 if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ 0637 { 0638 return -1; /* yep, throw this away */ 0639 } 0640 0641 SciWriteCharNoWait(*buf); /* try to send a char */ 0642 0643 *SCSR &= SCI_CLEAR_TDRE; /* clear tx data reg empty flag */ 0644 0645 SciEnableTransmitInterrupts(); /* enable the tx interrupt */ 0646 0647 return 0; /* return success */ 0648 } 0649 0650 0651 /**************************************************************************** 0652 * Func: SciSetAttributes 0653 * Desc: setup the uart based on the termios modules requests 0654 * Inputs: minor - device number 0655 * t - pointer to the termios info struct 0656 * Outputs: none 0657 * Errors: none 0658 * Scope: public API 0659 ****************************************************************************/ 0660 0661 int SciSetAttributes( 0662 int minor, 0663 const struct termios *t 0664 ) 0665 { 0666 uint32_t baud_requested; 0667 uint32_t sci_rate = 0; 0668 uint16_t sci_parity = 0; 0669 uint16_t sci_databits = 0; 0670 0671 if ( minor != SCI_MINOR ) /* check the minor dev num */ 0672 { 0673 return -1; /* return error */ 0674 } 0675 0676 /* if you look closely you will see this is the only thing we use */ 0677 /* set the baud rate */ 0678 0679 baud_requested = t->c_ospeed; /* baud rate */ 0680 0681 if (!baud_requested) 0682 { 0683 baud_requested = B9600; /* default to 9600 baud */ 0684 /* baud_requested = B19200; default to 19200 baud */ 0685 } 0686 0687 sci_rate = rtems_termios_baud_to_number( baud_requested ); 0688 0689 /* parity error detection */ 0690 0691 if (t->c_cflag & PARENB) /* enable parity detection? */ 0692 { 0693 if (t->c_cflag & PARODD) 0694 { 0695 sci_parity = SCI_PARITY_ODD; /* select odd parity */ 0696 } 0697 else 0698 { 0699 sci_parity = SCI_PARITY_EVEN; /* select even parity */ 0700 } 0701 } 0702 else 0703 { 0704 sci_parity = SCI_PARITY_NONE; /* no parity, most common */ 0705 } 0706 0707 /* set the number of data bits, 8 is most common */ 0708 0709 if (t->c_cflag & CSIZE) /* was it specified? */ 0710 { 0711 switch (t->c_cflag & CSIZE) 0712 { 0713 case CS8: sci_databits = SCI_8_DATA_BITS; break; 0714 default : sci_databits = SCI_9_DATA_BITS; break; 0715 } 0716 } 0717 else 0718 { 0719 sci_databits = SCI_8_DATA_BITS; /* default to 8 data bits */ 0720 } 0721 0722 /* the number of stop bits; always 1 for SCI */ 0723 0724 if (t->c_cflag & CSTOPB) 0725 { 0726 /* do nothing */ 0727 } 0728 0729 /* setup the hardware with these serial port parameters */ 0730 0731 SciSetBaud(sci_rate); /* set the baud rate */ 0732 SciSetParity(sci_parity); /* set the parity type */ 0733 SciSetDataBits(sci_databits); /* set the data bits */ 0734 0735 return RTEMS_SUCCESSFUL; 0736 } 0737 0738 0739 /* 0740 * 0741 * SECTION 3 0742 * POLLING BASED ENTRY POINTS FOR THE TERMIOS MODULE 0743 */ 0744 0745 /**************************************************************************** 0746 * Func: SciPolledOpen 0747 * Desc: open routine for the polled i/o version of the driver 0748 * called from rtems_termios_open which is called from console_open 0749 * Inputs: major - device number 0750 * minor - device number 0751 * args - points to terminal info struct 0752 * Outputs: success/fail 0753 * Errors: none 0754 * Scope: public - termios entry point 0755 ****************************************************************************/ 0756 0757 int SciPolledOpen( 0758 int major, 0759 int minor, 0760 void *arg 0761 ) 0762 { 0763 rtems_libio_open_close_args_t * args = arg; 0764 0765 if ( minor != SCI_MINOR ) /* check minor device num */ 0766 { 0767 return -1; 0768 } 0769 0770 if ( !args ) /* must have args */ 0771 { 0772 return -1; 0773 } 0774 0775 SciTermioTty = args->iop->data1; /* Store tty pointer */ 0776 0777 SciDisableAllInterrupts(); /* don't generate interrupts */ 0778 0779 /* THIS IS ACTUALLY A BAD THING - SETTING LINE PARAMETERS HERE */ 0780 /* IT SHOULD BE DONE THROUGH TCSETATTR() WHEN THE CONSOLE IS OPENED!!! */ 0781 0782 /* SciSetBaud(115200); set the baud rate */ 0783 /* SciSetBaud( 57600); set the baud rate */ 0784 /* SciSetBaud( 38400); set the baud rate */ 0785 /* SciSetBaud( 19200); * set the baud rate */ 0786 SciSetBaud( 9600); /* set the baud rate */ 0787 0788 SciSetParity(SCI_PARITY_NONE); /* set no parity */ 0789 0790 SciSetDataBits(SCI_8_DATA_BITS); /* set 8 data bits */ 0791 0792 SciEnableTransmitter(); /* enable the xmitter */ 0793 0794 SciEnableReceiver(); /* enable the rcvr */ 0795 0796 return RTEMS_SUCCESSFUL; 0797 } 0798 0799 0800 /**************************************************************************** 0801 * Func: SciPolledClose 0802 * Desc: close routine for the device driver, same for both 0803 * Inputs: major - device number 0804 * minor - device number 0805 * args - unused 0806 * Outputs: success/fail 0807 * Errors: none 0808 * Scope: public termios API 0809 ****************************************************************************/ 0810 0811 int SciPolledClose( 0812 int major, 0813 int minor, 0814 void *arg 0815 ) 0816 { 0817 SciDisableAllInterrupts(); 0818 0819 return RTEMS_SUCCESSFUL; 0820 } 0821 0822 0823 /**************************************************************************** 0824 * Func: SciPolledRead 0825 * Desc: polling based read routine for the uart 0826 * Inputs: minor - device number 0827 * Outputs: error or the character read 0828 * Errors: none 0829 * Scope: public API 0830 ****************************************************************************/ 0831 0832 int SciPolledRead( 0833 int minor 0834 ) 0835 { 0836 if ( minor != SCI_MINOR ) /* check the type-punned dev num */ 0837 { 0838 return -1; /* return error */ 0839 } 0840 0841 if ( SciCharAvailable() ) /* if a char is available */ 0842 { 0843 return SciReadCharNoWait(); /* read the rx data register */ 0844 } 0845 0846 return -1; /* return error */ 0847 } 0848 0849 0850 /**************************************************************************** 0851 * Func: SciPolledWrite 0852 * Desc: writes out characters in polled mode, waiting for the uart 0853 * check in console_open, but we only seem to use interrupt mode 0854 * Inputs: minor - device number 0855 * buf - points to the data 0856 * len - how many bytes 0857 * Outputs: error or number of bytes written 0858 * Errors: none 0859 * Scope: public termios API 0860 ****************************************************************************/ 0861 0862 ssize_t SciPolledWrite( 0863 int minor, 0864 const char *buf, 0865 size_t len 0866 ) 0867 { 0868 ssize_t written = 0; 0869 0870 if ( minor != SCI_MINOR ) /* check minor device num */ 0871 { 0872 return -1; 0873 } 0874 0875 if ( SciOpened == DRIVER_OPENED ) /* is the driver api open? */ 0876 { 0877 return -1; /* toss the data */ 0878 } 0879 0880 /* send each byte in the string out the port */ 0881 0882 while ( written < len ) 0883 { 0884 SciWriteCharWait(*buf++); /* send a byte */ 0885 0886 written++; /* increment counter */ 0887 } 0888 0889 return written; /* return count */ 0890 } 0891 0892 0893 /* 0894 * 0895 * SECTION 4 0896 * DEVICE DRIVER PUBLIC API ENTRY POINTS 0897 */ 0898 0899 /**************************************************************************** 0900 * Func: SciInit 0901 * Desc: Initialize the lasers device driver and hardware 0902 * Inputs: major - the major device number which is assigned by rtems 0903 * minor - the minor device number which is undefined at this point 0904 * arg - ????? 0905 * Outputs: RTEMS_SUCCESSFUL 0906 * Errors: None. 0907 * Scope: public API 0908 ****************************************************************************/ 0909 0910 rtems_device_driver SciInitialize ( 0911 rtems_device_major_number major, 0912 rtems_device_minor_number minor, 0913 void * arg 0914 ) 0915 { 0916 /* rtems_status_code status; */ 0917 0918 /*printk("%s\r\n", __FUNCTION__); */ 0919 0920 /* register the SCI device name for termios console i/o 0921 * this is done over in console.c which doesn't seem exactly right 0922 * but there were problems doing it here... 0923 */ 0924 0925 /* status = rtems_io_register_name( "/dev/sci", major, 0 ); */ 0926 0927 /* if (status != RTEMS_SUCCESSFUL) */ 0928 /* rtems_fatal_error_occurred(status); */ 0929 0930 SciMajor = major; /* save the rtems major number */ 0931 0932 SciOpened = DRIVER_CLOSED; /* initial state is closed */ 0933 0934 /* if you have an interrupt handler, install it here */ 0935 0936 SciInited = 1; /* set the inited flag */ 0937 0938 return RTEMS_SUCCESSFUL; 0939 } 0940 0941 0942 /**************************************************************************** 0943 * Func: SciOpen 0944 * Desc: device driver open routine 0945 * you must open a device before you can anything else 0946 * only one process can have the device opened at a time 0947 * you could look at the task id to restrict access if you want 0948 * Inputs: major - the major device number assigned by rtems 0949 * minor - the minor device number assigned by us 0950 * arg - ????? 0951 * Outputs: see below 0952 * Errors: none 0953 * Scope: public API 0954 ****************************************************************************/ 0955 0956 rtems_device_driver SciOpen ( 0957 rtems_device_major_number major, 0958 rtems_device_minor_number minor, 0959 void * arg 0960 ) 0961 { 0962 /*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ 0963 0964 if (SciInited == 0) /* must be initialized first! */ 0965 { 0966 return RTEMS_NOT_CONFIGURED; 0967 } 0968 0969 if (minor != SCI_MINOR) 0970 { 0971 return RTEMS_INVALID_NAME; /* verify minor number */ 0972 } 0973 0974 if (SciOpened == DRIVER_OPENED) 0975 { 0976 return RTEMS_RESOURCE_IN_USE; /* already opened! */ 0977 } 0978 0979 SciOpened = DRIVER_OPENED; /* set the opened flag */ 0980 0981 return RTEMS_SUCCESSFUL; 0982 } 0983 0984 0985 /**************************************************************************** 0986 * Func: SciClose 0987 * Desc: device driver close routine 0988 * the device must be opened before you can close it 0989 * the device must be closed before someone (else) can open it 0990 * Inputs: major - the major device number 0991 * minor - the minor device number 0992 * arg - ????? 0993 * Outputs: see below 0994 * Errors: none 0995 * Scope: public API 0996 ****************************************************************************/ 0997 0998 rtems_device_driver SciClose ( 0999 rtems_device_major_number major, 1000 rtems_device_minor_number minor, 1001 void * arg 1002 ) 1003 { 1004 /*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ 1005 1006 if (minor != SCI_MINOR) 1007 { 1008 return RTEMS_INVALID_NAME; /* check the minor number */ 1009 } 1010 1011 if (SciOpened != DRIVER_OPENED) 1012 { 1013 return RTEMS_INCORRECT_STATE; /* must be opened first */ 1014 } 1015 1016 SciOpened = DRIVER_CLOSED; /* set the flag */ 1017 1018 return RTEMS_SUCCESSFUL; 1019 } 1020 1021 1022 /**************************************************************************** 1023 * Func: SciRead 1024 * Desc: device driver read routine 1025 * this function is not meaningful for the laser devices 1026 * Inputs: major - the major device number 1027 * minor - the minor device number 1028 * arg - read/write arguments 1029 * Outputs: see below 1030 * Errors: none 1031 * Scope: public API 1032 ****************************************************************************/ 1033 1034 rtems_device_driver SciRead ( 1035 rtems_device_major_number major, 1036 rtems_device_minor_number minor, 1037 void *arg 1038 ) 1039 { 1040 rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ 1041 char *buffer; 1042 1043 rw_args = (rtems_libio_rw_args_t *) arg; /* arguments to read() */ 1044 1045 if (minor != SCI_MINOR) 1046 { 1047 return RTEMS_INVALID_NAME; /* check the minor number */ 1048 } 1049 1050 if (SciOpened == DRIVER_CLOSED) 1051 { 1052 return RTEMS_INCORRECT_STATE; /* must be opened first */ 1053 } 1054 1055 buffer = rw_args->buffer; /* points to user's buffer */ 1056 1057 /* *buffer = SciReadCharWait(); wait for a character */ 1058 1059 /* if there isn't a character available, wait until one shows up */ 1060 /* or the timeout period expires, which ever happens first */ 1061 1062 if ( SciRcvBufCount == 0 ) /* no chars */ 1063 { 1064 /* wait for someone to wake me up... */ 1065 /*rtems_task_wake_after(SciReadTimeout); */ 1066 } 1067 1068 if ( SciRcvBufCount ) /* any characters locally? */ 1069 { 1070 *buffer = SciRcvBufGetChar(); /* get the character */ 1071 1072 rw_args->bytes_moved = 1; /* how many we actually read */ 1073 } 1074 1075 return RTEMS_SUCCESSFUL; 1076 } 1077 1078 1079 /**************************************************************************** 1080 * Func: SciWrite 1081 * Desc: device driver write routine 1082 * this function is not meaningful for the laser devices 1083 * Inputs: major - the major device number 1084 * minor - the minor device number 1085 * arg - read/write arguments 1086 * Outputs: see below 1087 * Errors: non3 1088 * Scope: public API 1089 ****************************************************************************/ 1090 1091 rtems_device_driver SciWrite ( 1092 rtems_device_major_number major, 1093 rtems_device_minor_number minor, 1094 void * arg 1095 ) 1096 { 1097 rtems_libio_rw_args_t *rw_args; /* ptr to argument struct */ 1098 uint8_t *buffer; 1099 size_t length; 1100 1101 rw_args = (rtems_libio_rw_args_t *) arg; 1102 1103 if (minor != SCI_MINOR) 1104 { 1105 return RTEMS_INVALID_NAME; /* check the minor number */ 1106 } 1107 1108 if (SciOpened == DRIVER_CLOSED) 1109 { 1110 return RTEMS_INCORRECT_STATE; /* must be opened first */ 1111 } 1112 1113 buffer = (uint8_t*)rw_args->buffer; /* points to data */ 1114 1115 length = rw_args->count; /* how many bytes */ 1116 1117 while (length--) 1118 { 1119 SciWriteCharWait(*buffer++); /* send the bytes out */ 1120 } 1121 1122 rw_args->bytes_moved = rw_args->count; /* how many we wrote */ 1123 1124 return RTEMS_SUCCESSFUL; 1125 } 1126 1127 1128 /**************************************************************************** 1129 * Func: SciControl 1130 * Desc: device driver control routine 1131 * see below for an example of how to use the ioctl interface 1132 * Inputs: major - the major device number 1133 * minor - the minor device number 1134 * arg - io control args 1135 * Outputs: see below 1136 * Errors: none 1137 * Scope: public API 1138 ****************************************************************************/ 1139 1140 rtems_device_driver SciControl ( 1141 rtems_device_major_number major, 1142 rtems_device_minor_number minor, 1143 void * arg 1144 ) 1145 { 1146 rtems_libio_ioctl_args_t *args = arg; /* rtems arg struct */ 1147 uint16_t command; /* the cmd to execute */ 1148 1149 /*printk("%s major=%d minor=%d\r\n", __FUNCTION__,major,minor); */ 1150 1151 /* do some sanity checking */ 1152 1153 if (minor != SCI_MINOR) 1154 { 1155 return RTEMS_INVALID_NAME; /* check the minor number */ 1156 } 1157 1158 if (SciOpened == DRIVER_CLOSED) 1159 { 1160 return RTEMS_INCORRECT_STATE; /* must be open first */ 1161 } 1162 1163 if (args == 0) 1164 { 1165 return RTEMS_INVALID_ADDRESS; /* must have args */ 1166 } 1167 1168 args->ioctl_return = -1; /* assume an error */ 1169 1170 command = args->command; /* get the command */ 1171 1172 if (command == SCI_SEND_BREAK) /* process the command */ 1173 { 1174 SciSendBreak(); /* send break char */ 1175 } 1176 1177 args->ioctl_return = 0; /* return status */ 1178 1179 return RTEMS_SUCCESSFUL; 1180 } 1181 1182 1183 /* 1184 * 1185 * SECTION 5 1186 * HARDWARE LEVEL ROUTINES 1187 */ 1188 1189 /**************************************************************************** 1190 * Func: SciSetBaud 1191 * Desc: setup the uart based on the termios modules requests 1192 * Inputs: baud rate 1193 * Outputs: none 1194 * Errors: none 1195 * Scope: private 1196 ****************************************************************************/ 1197 1198 static void SciSetBaud(uint32_t rate) 1199 { 1200 uint16_t value; 1201 uint16_t save_sccr1; 1202 1203 /* when you open the console you need to set the termio struct baud rate */ 1204 /* it has a default value of 9600, when someone calls tcsetattr it reverts! */ 1205 1206 SciBaud = rate; /* save the rate */ 1207 1208 /* calculate the register value as a float and convert to an int */ 1209 /* set baud rate - you must define the system clock constant */ 1210 /* see mrm332.h for an example */ 1211 1212 value = ( (uint16_t) ( SYS_CLOCK / rate / 32.0 + 0.5 ) & 0x1fff ); 1213 1214 save_sccr1 = *SCCR1; /* save register */ 1215 1216 /* also turns off the xmtr and rcvr */ 1217 1218 *SCCR1 &= SCI_DISABLE_INT_ALL; /* disable interrupts */ 1219 1220 *SCCR0 = value; /* write the register */ 1221 1222 *SCCR1 = save_sccr1; /* restore register */ 1223 1224 return; 1225 } 1226 1227 1228 /**************************************************************************** 1229 * Func: SciSetParity 1230 * Desc: setup the uart based on the termios modules requests 1231 * Inputs: parity 1232 * Outputs: none 1233 * Errors: none 1234 * Scope: private 1235 ****************************************************************************/ 1236 1237 static void SciSetParity(uint16_t parity) 1238 { 1239 uint16_t value; 1240 1241 value = *SCCR1; /* get the register */ 1242 1243 if (parity == SCI_PARITY_ODD) 1244 { 1245 value |= SCI_PARITY_ENABLE; /* parity enabled */ 1246 value |= SCI_PARITY_ODD; /* parity odd */ 1247 } 1248 1249 else if (parity == SCI_PARITY_EVEN) 1250 { 1251 value |= SCI_PARITY_ENABLE; /* parity enabled */ 1252 value &= ~SCI_PARITY_ODD; /* parity even */ 1253 } 1254 1255 else if (parity == SCI_PARITY_NONE) 1256 { 1257 value &= ~SCI_PARITY_ENABLE; /* disabled, most common */ 1258 } 1259 1260 /* else no changes */ 1261 1262 *SCCR1 = value; /* write the register */ 1263 1264 return; 1265 } 1266 1267 1268 /**************************************************************************** 1269 * Func: SciSetDataBits 1270 * Desc: setup the uart based on the termios modules requests 1271 * Inputs: data bits 1272 * Outputs: none 1273 * Errors: none 1274 * Scope: private 1275 ****************************************************************************/ 1276 1277 static void SciSetDataBits(uint16_t bits) 1278 { 1279 uint16_t value; 1280 1281 value = *SCCR1; /* get the register */ 1282 1283 /* note - the parity setting affects the number of data bits */ 1284 1285 if (bits == SCI_9_DATA_BITS) 1286 { 1287 value |= SCI_9_DATA_BITS; /* 9 data bits */ 1288 } 1289 1290 else if (bits == SCI_8_DATA_BITS) 1291 { 1292 value &= SCI_8_DATA_BITS; /* 8 data bits */ 1293 } 1294 1295 /* else no changes */ 1296 1297 *SCCR1 = value; /* write the register */ 1298 1299 return; 1300 } 1301 1302 1303 /**************************************************************************** 1304 * Func: SciDisableAllInterrupts 1305 * Func: SciEnableTransmitInterrupts 1306 * Func: SciEnableReceiveInterrupts 1307 * Desc: handles generation of interrupts by the sci module 1308 * Inputs: none 1309 * Outputs: none 1310 * Errors: none 1311 * Scope: private 1312 ****************************************************************************/ 1313 1314 static void inline SciDisableAllInterrupts( void ) 1315 { 1316 /* this also turns off the xmtr and rcvr */ 1317 1318 *SCCR1 &= SCI_DISABLE_INT_ALL; 1319 } 1320 1321 static void inline SciEnableReceiveInterrupts( void ) 1322 { 1323 *SCCR1 |= SCI_ENABLE_INT_RX; 1324 } 1325 1326 static void inline SciDisableReceiveInterrupts( void ) 1327 { 1328 *SCCR1 &= SCI_DISABLE_INT_RX; 1329 } 1330 1331 static void inline SciEnableTransmitInterrupts( void ) 1332 { 1333 *SCCR1 |= SCI_ENABLE_INT_TX; 1334 } 1335 1336 static void inline SciDisableTransmitInterrupts( void ) 1337 { 1338 *SCCR1 &= SCI_DISABLE_INT_TX; 1339 } 1340 1341 1342 /**************************************************************************** 1343 * Func: SciEnableTransmitter, SciDisableTransmitter 1344 * Func: SciEnableReceiver, SciDisableReceiver 1345 * Desc: turns the transmitter and receiver on and off 1346 * Inputs: none 1347 * Outputs: none 1348 * Errors: none 1349 * Scope: private 1350 ****************************************************************************/ 1351 1352 static void inline SciEnableTransmitter( void ) 1353 { 1354 *SCCR1 |= SCI_ENABLE_XMTR; 1355 } 1356 1357 static void inline SciDisableTransmitter( void ) 1358 { 1359 *SCCR1 &= SCI_DISABLE_XMTR; 1360 } 1361 1362 static void inline SciEnableReceiver( void ) 1363 { 1364 *SCCR1 |= SCI_ENABLE_RCVR; 1365 } 1366 1367 static void inline SciDisableReceiver( void ) 1368 { 1369 *SCCR1 &= SCI_DISABLE_RCVR; 1370 } 1371 1372 1373 /**************************************************************************** 1374 * Func: SciWriteCharWait 1375 * Desc: wait for room in the fifo and then put a char in 1376 * Inputs: a byte to send 1377 * Outputs: none 1378 * Errors: none 1379 * Scope: public 1380 ****************************************************************************/ 1381 1382 void SciWriteCharWait(uint8_t c) 1383 { 1384 /* poll the fifo, waiting for room for another character */ 1385 1386 while ( ( *SCSR & SCI_XMTR_AVAILABLE ) != SCI_XMTR_AVAILABLE ) 1387 { 1388 /* Either we are writing to the fifo faster than 1389 * the uart can clock bytes out onto the cable, 1390 * or we are in flow control (actually no, we 1391 * are ignoring flow control from the other end). 1392 * In the first case, higher baud rates will help. 1393 */ 1394 /* relinquish processor while waiting */ 1395 rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); 1396 } 1397 1398 *SCDR = c; /* send the charcter */ 1399 1400 SciBytesOut++; /* increment the counter */ 1401 1402 return; 1403 } 1404 1405 /**************************************************************************** 1406 * Func: SciWriteCharNoWait 1407 * Desc: if no room in the fifo throw the char on the floor 1408 * Inputs: a byte to send 1409 * Outputs: none 1410 * Errors: none 1411 * Scope: public 1412 ****************************************************************************/ 1413 1414 void SciWriteCharNoWait(uint8_t c) 1415 { 1416 if ( ( *SCSR & SCI_XMTR_AVAILABLE ) == 0 ) 1417 { 1418 return; /* no room, throw it away */ 1419 } 1420 1421 *SCDR = c; /* put the char in the fifo */ 1422 1423 SciBytesOut++; /* increment the counter */ 1424 1425 return; 1426 } 1427 1428 1429 /**************************************************************************** 1430 * Func: SciReadCharWait 1431 * Desc: read a character, waiting for one to show up, if need be 1432 * Inputs: none 1433 * Outputs: a character 1434 * Errors: none 1435 * Scope: public 1436 ****************************************************************************/ 1437 1438 static uint8_t inline SciReadCharWait( void ) 1439 { 1440 uint8_t ch; 1441 1442 while ( SciCharAvailable() == 0 ) /* anything there? */ 1443 { 1444 /* relinquish processor while waiting */ 1445 rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); 1446 } 1447 1448 /* if you have rcv ints enabled, then the isr will probably */ 1449 /* get the character before you will unless you turn off ints */ 1450 /* ie polling and ints don't mix that well */ 1451 1452 ch = *SCDR; /* get the charcter */ 1453 1454 SciBytesIn++; /* increment the counter */ 1455 1456 return ch; /* return the char */ 1457 } 1458 1459 /**************************************************************************** 1460 * Func: SciReadCharNoWait 1461 * Desc: try to get a char but dont wait for one 1462 * Inputs: none 1463 * Outputs: a character or -1 if none 1464 * Errors: none 1465 * Scope: public 1466 ****************************************************************************/ 1467 1468 static uint8_t inline SciReadCharNoWait( void ) 1469 { 1470 uint8_t ch; 1471 1472 if ( SciCharAvailable() == 0 ) /* anything there? */ 1473 return -1; 1474 1475 ch = *SCDR; /* get the character */ 1476 1477 SciBytesIn++; /* increment the count */ 1478 1479 return ch; /* return the char */ 1480 } 1481 1482 1483 /**************************************************************************** 1484 * Func: SciCharAvailable 1485 * Desc: is there a receive character in the data register 1486 * Inputs: none 1487 * Outputs: false if no char available, else true 1488 * Errors: none 1489 * Scope: public 1490 ****************************************************************************/ 1491 1492 uint8_t inline SciCharAvailable( void ) 1493 { 1494 return ( *SCSR & SCI_RCVR_READY ); /* char in data register? */ 1495 } 1496 1497 1498 /**************************************************************************** 1499 * Func: SciSendBreak 1500 * Desc: send 1 or tow breaks (all zero bits) 1501 * Inputs: none 1502 * Outputs: none 1503 * Errors: none 1504 * Scope: public 1505 ****************************************************************************/ 1506 1507 void SciSendBreak( void ) 1508 { 1509 /* From the Motorola QSM reference manual - */ 1510 1511 /* "if SBK is toggled by writing it first to a one and then immediately */ 1512 /* to a zero (in less than one serial frame interval), the transmitter */ 1513 /* sends only one or two break frames before reverting to mark (idle) */ 1514 /* or before commencing to send more data" */ 1515 1516 *SCCR1 |= SCI_SEND_BREAK; /* set the bit */ 1517 1518 *SCCR1 &= ~SCI_SEND_BREAK; /* clear the bit */ 1519 1520 return; 1521 } 1522 1523 1524 /* 1525 * 1526 * SECTION 6 1527 * TEST CODE 1528 */ 1529 1530 /**************************************************************************** 1531 * Func: SciUnitTest 1532 * Desc: test the device driver 1533 * Inputs: nothing 1534 * Outputs: nothing 1535 * Scope: public 1536 ****************************************************************************/ 1537 1538 #if 0 1539 void SciUnitTest() 1540 { 1541 uint8_t byte; /* a character */ 1542 uint16_t fd; /* file descriptor for device */ 1543 uint16_t result; /* result of ioctl */ 1544 1545 fd = open("/dev/sci",O_RDWR); /* open the device */ 1546 1547 printk("SCI open fd=%d\r\n",fd); 1548 1549 result = write(fd, "abcd\r\n", 6); /* send a string */ 1550 1551 printk("SCI write result=%d\r\n",result); 1552 1553 result = read(fd, &byte, 1); /* read a byte */ 1554 1555 printk("SCI read result=%d,byte=%x\r\n",result,byte); 1556 1557 return; 1558 } 1559 #endif 1560 1561 1562 /**************************************************************************** 1563 * Func: SciPrintStats 1564 * Desc: print out some driver information 1565 * Inputs: nothing 1566 * Outputs: nothing 1567 * Scope: public 1568 ****************************************************************************/ 1569 1570 void SciPrintStats ( void ) 1571 { 1572 printk("\r\n"); 1573 1574 printk( "SYS_CLOCK is %2.6f Mhz\r\n\n", SYS_CLOCK / 1000000.0 ); 1575 1576 printk( "Current baud rate is %d bps or %d cps\r\n\n", SciBaud, SciBaud / 10 ); 1577 1578 printk( "SCI Uart chars in %8" PRIu32 "\r\n", SciBytesIn ); 1579 printk( "SCI Uart chars out %8" PRIu32 "\r\n", SciBytesOut ); 1580 printk( "SCI Uart framing errors %8" PRIu32 "\r\n", SciErrorsFraming ); 1581 printk( "SCI Uart parity errors %8" PRIu32 "\r\n", SciErrorsParity ); 1582 printk( "SCI Uart overrun errors %8" PRIu32 "\r\n", SciErrorsOverrun ); 1583 printk( "SCI Uart noise errors %8" PRIu32 "\r\n", SciErrorsNoise ); 1584 1585 return; 1586 }
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |