Changeset 4106f7f in rtems
- Timestamp:
- Oct 23, 1997, 6:47:43 PM (23 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 51961e4
- Parents:
- aa239a7
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libbsp/m68k/gen68360/console/console.c
raa239a7 r4106f7f 1 1 /* 2 * Initialize SMC1 for console IO. 3 * 4 * Based on the `gen68302' board support package, and covered by the 5 * original distribution terms. 6 * 7 * W. Eric Norum 8 * Saskatchewan Accelerator Laboratory 9 * University of Saskatchewan 10 * Saskatoon, Saskatchewan, CANADA 11 * eric@skatter.usask.ca 12 * 13 * $Id$ 14 */ 15 16 /* 2 * SMC1 raw console serial I/O. 3 * 4 * This driver is an example of `POLLING' or `INTERRUPT' input. 5 * 6 * To compile with interrupt-driven input, define M360_SMC1_INTERRUPT 7 * in the make customization file for this bsp (gen68360.cfg). 8 * 9 * Author: 10 * W. Eric Norum 11 * Saskatchewan Accelerator Laboratory 12 * University of Saskatchewan 13 * Saskatoon, Saskatchewan, CANADA 14 * eric@skatter.usask.ca 17 15 * 18 16 * COPYRIGHT (c) 1989-1997. … … 22 20 * The license and distribution terms for this file may be 23 21 * found in the file LICENSE in this distribution or at 22 * 24 23 * http://www.OARcorp.com/rtems/license.html. 25 */ 26 27 #define GEN68360_INIT 28 24 * 25 * $Id$ 26 */ 27 28 #include <termios.h> 29 29 #include <bsp.h> 30 30 #include <rtems/libio.h> 31 31 #include "m68360.h" 32 32 33 /* console_initialize 34 * 35 * This routine initializes the console IO driver. 36 * 37 * Input parameters: NONE 38 * 39 * Output parameters: NONE 40 * 41 * Return values: 42 */ 43 44 /* 45 * I/O buffers can be in ordindary RAM 46 */ 47 static volatile char rxBuf, txBuf; 48 static volatile m360BufferDescriptor_t *consoleRxBd, *consoleTxBd; 49 33 #if (defined (M360_SMC1_INTERRUPT)) 34 # define RXBUFSIZE 16 35 static void *smc1ttyp; 36 #else 37 # define RXBUFSIZE 1 38 #endif 39 40 /* 41 * I/O buffers and pointers to buffer descriptors 42 */ 43 static volatile char rxBuf[RXBUFSIZE], txBuf; 44 static volatile m360BufferDescriptor_t *smcRxBd, *smcTxBd; 45 46 /* 47 * Device-specific routines 48 */ 49 #if (defined (M360_SMC1_INTERRUPT)) 50 static rtems_isr 51 smc1InterruptHandler (rtems_vector_number v) 52 { 53 /* 54 * Buffer received? 55 */ 56 if (m360.smc1.smce & 0x1) { 57 m360.smc1.smce = 0x1; 58 while ((smcRxBd->status & M360_BD_EMPTY) == 0) { 59 rtems_termios_enqueue_raw_characters (smc1ttyp, 60 (char *)smcRxBd->buffer, 61 smcRxBd->length); 62 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; 63 } 64 } 65 m360.cisr = 1UL << 4; /* Clear SMC1 interrupt-in-service bit */ 66 } 67 68 #endif 69 70 static void 71 smc1Initialize (void) 72 { 73 /* 74 * Allocate buffer descriptors 75 */ 76 smcRxBd = M360AllocateBufferDescriptors (1); 77 smcTxBd = M360AllocateBufferDescriptors (1); 78 79 /* 80 * Configure port B pins to enable SMTXD1 and SMRXD1 pins 81 */ 82 m360.pbpar |= 0xC0; 83 m360.pbdir &= ~0xC0; 84 m360.pbodr &= ~0xC0; 85 86 /* 87 * Set up BRG1 (9,600 baud) 88 */ 89 m360.brgc1 = M360_BRG_RST; 90 m360.brgc1 = M360_BRG_EN | M360_BRG_EXTC_BRGCLK | M360_BRG_9600; 91 92 /* 93 * Put SMC1 in NMSI mode, connect SMC1 to BRG1 94 */ 95 m360.simode |= M360_SI_SMC1_BRG1; 96 97 /* 98 * Set up SMC1 parameter RAM common to all protocols 99 */ 100 m360.smc1p.rbase = (char *)smcRxBd - (char *)&m360; 101 m360.smc1p.tbase = (char *)smcTxBd - (char *)&m360; 102 m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; 103 m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; 104 m360.smc1p.mrblr = RXBUFSIZE; 105 106 /* 107 * Set up SMC1 parameter RAM UART-specific parameters 108 */ 109 m360.smc1p.un.uart.max_idl = 10; 110 m360.smc1p.un.uart.brklen = 0; 111 m360.smc1p.un.uart.brkec = 0; 112 m360.smc1p.un.uart.brkcr = 0; 113 114 /* 115 * Set up the Receive Buffer Descriptor 116 */ 117 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP | M360_BD_INTERRUPT; 118 smcRxBd->length = 0; 119 smcRxBd->buffer = rxBuf; 120 121 /* 122 * Setup the Transmit Buffer Descriptor 123 */ 124 smcTxBd->status = M360_BD_WRAP; 125 smcTxBd->length = 1; 126 smcTxBd->buffer = &txBuf; 127 128 /* 129 * Set up SMC1 general and protocol-specific mode registers 130 */ 131 m360.smc1.smce = ~0; /* Clear any pending events */ 132 m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ 133 m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; 134 135 /* 136 * Send "Init parameters" command 137 */ 138 M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); 139 140 /* 141 * Enable receiver and transmitter 142 */ 143 m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; 144 145 #if (defined (M360_SMC1_INTERRUPT)) 146 { 147 rtems_isr_entry old_handler; 148 rtems_status_code sc; 149 150 sc = rtems_interrupt_catch (smc1InterruptHandler, 151 (m360.cicr & 0xE0) | 0x04, 152 &old_handler); 153 m360.smc1.smcm = 1; /* Enable SMC1 receiver interrupt */ 154 m360.cimr |= 1UL << 4; /* Enable SMC1 interrupts */ 155 } 156 #endif 157 } 158 159 static int 160 smc1Read (int minor) 161 { 162 unsigned char c; 163 164 if (smcRxBd->status & M360_BD_EMPTY) 165 return -1; 166 c = rxBuf[0]; 167 smcRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; 168 return c; 169 } 170 171 static int 172 smc1Write (int minor, char *buf, int len) 173 { 174 int nwrite = 0; 175 176 while (nwrite < len) { 177 while (smcTxBd->status & M360_BD_READY) 178 continue; 179 txBuf = *buf++; 180 smcTxBd->status = M360_BD_READY | M360_BD_WRAP; 181 nwrite++; 182 } 183 return nwrite; 184 } 185 186 /* 187 *************** 188 * BOILERPLATE * 189 *************** 190 */ 191 192 /* 193 * Initialize and register the device 194 */ 50 195 rtems_device_driver console_initialize( 51 196 rtems_device_major_number major, … … 57 202 58 203 /* 59 * Allocate buffer descriptors 60 */ 61 consoleRxBd = M360AllocateBufferDescriptors (1); 62 consoleTxBd = M360AllocateBufferDescriptors (1); 63 64 /* 65 * Configure port B pins to enable SMTXD1 and SMRXD1 pins 66 */ 67 m360.pbpar |= 0xC0; 68 m360.pbdir &= ~0xC0; 69 m360.pbodr &= ~0xC0; 70 71 /* 72 * Set up BRG1 (9,600 baud) 73 */ 74 m360.brgc1 = M360_BRG_RST; 75 m360.brgc1 = M360_BRG_EN | M360_BRG_EXTC_BRGCLK | M360_BRG_9600; 76 77 /* 78 * Put SMC1 in NMSI mode, connect SMC1 to BRG1 79 */ 80 m360.simode |= M360_SI_SMC1_BRG1; 81 82 /* 83 * Set up SMC1 parameter RAM common to all protocols 84 */ 85 m360.smc1p.rbase = (char *)consoleRxBd - (char *)&m360; 86 m360.smc1p.tbase = (char *)consoleTxBd - (char *)&m360; 87 m360.smc1p.rfcr = M360_RFCR_MOT | M360_RFCR_DMA_SPACE; 88 m360.smc1p.tfcr = M360_TFCR_MOT | M360_TFCR_DMA_SPACE; 89 m360.smc1p.mrblr = 1; 90 91 /* 92 * Set up SMC1 parameter RAM UART-specific parameters 93 */ 94 m360.smc1p.un.uart.max_idl = 0; 95 m360.smc1p.un.uart.brklen = 0; 96 m360.smc1p.un.uart.brkec = 0; 97 m360.smc1p.un.uart.brkcr = 0; 98 99 /* 100 * Set up the Receive Buffer Descriptor 101 */ 102 consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; 103 consoleRxBd->length = 0; 104 consoleRxBd->buffer = &rxBuf; 105 106 /* 107 * Setup the Transmit Buffer Descriptor 108 */ 109 consoleTxBd->length = 1; 110 consoleTxBd->status = M360_BD_WRAP; 111 consoleTxBd->buffer = &txBuf; 112 113 /* 114 * Set up SMC1 general and protocol-specific mode registers 115 */ 116 m360.smc1.smce = ~0; /* Clear any pending events */ 117 m360.smc1.smcm = 0; /* Mask all interrupt/event sources */ 118 m360.smc1.smcmr = M360_SMCMR_CLEN(9) | M360_SMCMR_SM_UART; 119 120 /* 121 * Send "Init parameters" command 122 */ 123 M360ExecuteRISC (M360_CR_OP_INIT_RX_TX | M360_CR_CHAN_SMC1); 124 125 /* 126 * Enable receiver and transmitter 127 */ 128 m360.smc1.smcmr |= M360_SMCMR_TEN | M360_SMCMR_REN; 129 130 status = rtems_io_register_name( 131 "/dev/console", 132 major, 133 (rtems_device_minor_number)0); 204 * Set up TERMIOS 205 */ 206 rtems_termios_initialize (); 207 208 /* 209 * Do device-specific initialization 210 */ 211 smc1Initialize (); 212 213 /* 214 * Register the device 215 */ 216 status = rtems_io_register_name ("/dev/console", major, 0); 134 217 if (status != RTEMS_SUCCESSFUL) 135 rtems_fatal_error_occurred (status);218 rtems_fatal_error_occurred (status); 136 219 return RTEMS_SUCCESSFUL; 137 220 } 138 221 139 /* is_character_ready 140 * 141 * Check to see if a character is available on the console port. If so, 142 * then return a TRUE (along with the character). Otherwise return FALSE. 143 * 144 * Input parameters: pointer to location in which to return character 145 * 146 * Output parameters: character (if available) 147 * 148 * Return values: TRUE - character available 149 * FALSE - no character available 150 */ 151 152 rtems_boolean is_character_ready( 153 char *ch /* -> character */ 154 ) 155 { 156 if (consoleRxBd->status & M360_BD_EMPTY) 157 return FALSE; 158 *ch = rxBuf; 159 consoleRxBd->status = M360_BD_EMPTY | M360_BD_WRAP; 160 return TRUE; 161 } 162 163 164 /* inbyte 165 * 166 * Receive a character from the console port 167 * 168 * Input parameters: NONE 169 * 170 * Output parameters: NONE 171 * 172 * Return values: character read 173 */ 174 175 char inbyte( void ) 176 { 177 char ch; 178 179 while (is_character_ready (&ch) == FALSE) 180 continue; 181 return ch; 182 } 183 184 185 /* outbyte 186 * 187 * Transmit a character to the console serial port 188 * 189 * Input parameters: 190 * ch - character to be transmitted 191 * 192 * Output parameters: NONE 193 */ 194 195 void outbyte( 196 char ch 197 ) 198 { 199 if (ch == '\n') 200 outbyte('\r'); 201 while (consoleTxBd->status & M360_BD_READY) 202 continue; 203 txBuf = ch; 204 consoleTxBd->status = M360_BD_READY | M360_BD_WRAP; 205 } 206 207 /* 208 * Open entry point 209 */ 210 222 /* 223 * Open the device 224 */ 211 225 rtems_device_driver console_open( 212 226 rtems_device_major_number major, … … 215 229 ) 216 230 { 217 return RTEMS_SUCCESSFUL; 231 rtems_status_code sc; 232 233 #if (defined (M360_SMC1_INTERRUPT)) 234 rtems_libio_open_close_args_t *args = arg; 235 236 sc = rtems_termios_open (major, minor, arg, 237 NULL, 238 NULL, 239 NULL, 240 smc1Write); 241 smc1ttyp = args->iop->data1; 242 #else 243 sc = rtems_termios_open (major, minor, arg, 244 NULL, 245 NULL, 246 smc1Read, 247 smc1Write); 248 #endif 249 return sc; 218 250 } 219 251 220 252 /* 221 * Close entry point 222 */ 223 253 * Close the device 254 */ 224 255 rtems_device_driver console_close( 225 256 rtems_device_major_number major, … … 228 259 ) 229 260 { 230 return RTEMS_SUCCESSFUL; 231 } 232 233 /* 234 * read bytes from the serial port. We only have stdin. 235 */ 236 261 return rtems_termios_close (arg); 262 } 263 264 /* 265 * Read from the device 266 */ 237 267 rtems_device_driver console_read( 238 268 rtems_device_major_number major, … … 241 271 ) 242 272 { 243 rtems_libio_rw_args_t *rw_args; 244 char *buffer; 245 int maximum; 246 int count = 0; 247 248 rw_args = (rtems_libio_rw_args_t *) arg; 249 250 buffer = rw_args->buffer; 251 maximum = rw_args->count; 252 253 for (count = 0; count < maximum; count++) { 254 buffer[ count ] = inbyte(); 255 if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { 256 buffer[ count++ ] = '\n'; 257 break; 258 } 259 } 260 261 rw_args->bytes_moved = count; 262 return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; 263 } 264 265 /* 266 * write bytes to the serial port. Stdout and stderr are the same. 267 */ 268 273 return rtems_termios_read (arg); 274 } 275 276 /* 277 * Write to the device 278 */ 269 279 rtems_device_driver console_write( 270 280 rtems_device_major_number major, … … 273 283 ) 274 284 { 275 int count; 276 int maximum; 277 rtems_libio_rw_args_t *rw_args; 278 char *buffer; 279 280 rw_args = (rtems_libio_rw_args_t *) arg; 281 282 buffer = rw_args->buffer; 283 maximum = rw_args->count; 284 285 for (count = 0; count < maximum; count++) { 286 if ( buffer[ count ] == '\n') { 287 outbyte('\r'); 288 } 289 outbyte( buffer[ count ] ); 290 } 291 292 rw_args->bytes_moved = maximum; 293 return 0; 294 } 295 296 /* 297 * IO Control entry point 298 */ 299 285 return rtems_termios_write (arg); 286 } 287 288 /* 289 * Handle ioctl request. 290 * Should set hardware line speed, bits/char, etc. 291 */ 300 292 rtems_device_driver console_control( 301 293 rtems_device_major_number major, … … 303 295 void * arg 304 296 ) 305 { 306 return RTEMS_SUCCESSFUL;307 } 297 { 298 return rtems_termios_ioctl (arg); 299 }
Note: See TracChangeset
for help on using the changeset viewer.