static int m8xx_scc_set_attributes (int minor, const struct termios *t) { int baud, brg=0; uint16_t csize=0, cstopb, parenb, parodd; /* Baud rate */ switch (t->c_cflag & CBAUD) { default: baud = -1; break; case B50: baud = 50; break; case B75: baud = 75; break; case B110: baud = 110; break; case B134: baud = 134; break; case B150: baud = 150; break; case B200: baud = 200; break; case B300: baud = 300; break; case B600: baud = 600; break; case B1200: baud = 1200; break; case B1800: baud = 1800; break; case B2400: baud = 2400; break; case B4800: baud = 4800; break; case B9600: baud = 9600; break; case B19200: baud = 19200; break; case B38400: baud = 38400; break; case B57600: baud = 57600; break; case B115200: baud = 115200; break; case B230400: baud = 230400; break; case B460800: baud = 460800; break; } if (baud > 0) { brg = m8xx_get_brg( M8260_SCC_BRGS, baud*16 ); m8260.cmxscr &= ~(0xFF000000 >> (8*(minor-SCC1_MINOR)) ); m8260.cmxscr |= ((brg<<(3+8*(3-(minor-SCC1_MINOR)))) & (brg<<(8*(3-(minor-SCC1_MINOR))))); }
/* * Initialize the SCC hardware * Configure I/O ports for SCC3 * Internal Tx clock, External Rx clock */ static void m8260_scc_initialize_hardware (struct m8260_hdlc_struct *sc) { int i; int brg; rtems_status_code status; /* RxD PB14 */ m8260.pparb |= 0x00020000; m8260.psorb &= ~0x00020000; m8260.pdirb &= ~0x00020000; /* RxC (CLK5) PC27 */ m8260.pparc |= 0x00000010; m8260.psorc &= ~0x00000010; m8260.pdirc &= ~0x00000010; /* TxD PD24 and TxC PD10 (BRG4) */ m8260.ppard |= 0x00200080; m8260.psord |= 0x00200000; m8260.psord &= ~0x00000080; m8260.pdird |= 0x00200080; /* External Rx Clock from CLK5 */ if( m8xx_get_clk( M8xx_CLK_5 ) == -1 ) printk( "Error allocating CLK5 for network device.\n" ); else m8260.cmxscr |= 0x00002000; /* Internal Tx Clock from BRG4 */ if( (brg = m8xx_get_brg(M8xx_BRG_4, 8000000 )) == -1 ) printk( "Error allocating BRG for network device\n" ); else m8260.cmxscr |= ((unsigned)brg << 8); /* * Allocate mbuf pointers */ sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT); sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT); if (!sc->rxMbuf || !sc->txMbuf) rtems_panic ("No memory for mbuf pointers"); /* * Set receiver and transmitter buffer descriptor bases */ sc->rxBdBase = m8xx_bd_allocate (sc->rxBdCount); sc->txBdBase = m8xx_bd_allocate (sc->txBdCount); m8260.scc3p.rbase = (char *)sc->rxBdBase - (char *)&m8260; m8260.scc3p.tbase = (char *)sc->txBdBase - (char *)&m8260; /* * Send "Init parameters" command */ m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC3 ); /* * Set receive and transmit function codes */ m8260.scc3p.rfcr = M8260_RFCR_MOT | M8260_RFCR_60X_BUS; m8260.scc3p.tfcr = M8260_TFCR_MOT | M8260_TFCR_60X_BUS; /* * Set maximum receive buffer length */ m8260.scc3p.mrblr = RBUF_SIZE; m8260.scc3p.un.hdlc.c_mask = 0xF0B8; m8260.scc3p.un.hdlc.c_pres = 0xFFFF; m8260.scc3p.un.hdlc.disfc = 0; m8260.scc3p.un.hdlc.crcec = 0; m8260.scc3p.un.hdlc.abtsc = 0; m8260.scc3p.un.hdlc.nmarc = 0; m8260.scc3p.un.hdlc.retrc = 0; m8260.scc3p.un.hdlc.rfthr = 1; m8260.scc3p.un.hdlc.mflr = RBUF_SIZE; m8260.scc3p.un.hdlc.hmask = 0x0000; /* promiscuous */ m8260.scc3p.un.hdlc.haddr1 = 0xFFFF; /* Broadcast address */ m8260.scc3p.un.hdlc.haddr2 = 0xFFFF; /* Station address */ m8260.scc3p.un.hdlc.haddr3 = 0xFFFF; /* Dummy */ m8260.scc3p.un.hdlc.haddr4 = 0xFFFF; /* Dummy */ /* * Send "Init parameters" command */ /* m8xx_cp_execute_cmd (M8260_CR_OP_INIT_RX_TX | M8260_CR_SCC3 ); */ /* * Set up receive buffer descriptors */ for (i = 0 ; i < sc->rxBdCount ; i++) { (sc->rxBdBase + i)->status = 0; } /* * Set up transmit buffer descriptors */ for (i = 0 ; i < sc->txBdCount ; i++) { (sc->txBdBase + i)->status = 0; sc->txMbuf[i] = NULL; } sc->txBdHead = sc->txBdTail = 0; sc->txBdActiveCount = 0; m8260.scc3.sccm = 0; /* No interrupts unmasked till necessary */ /* * Clear any outstanding events */ m8260.scc3.scce = 0xFFFF; /* * Set up interrupts */ status = BSP_install_rtems_irq_handler (&hdlcSCC3IrqData); /* printk( "status = %d, Success = %d\n", status, RTEMS_SUCCESSFUL ); */ if (status != 1 /*RTEMS_SUCCESSFUL*/ ) { rtems_panic ("Can't attach M8260 SCC3 interrupt handler: %s\n", rtems_status_text (status)); } m8260.scc3.sccm = 0; /* No interrupts unmasked till necessary */ m8260.scc3.gsmr_h = 0; m8260.scc3.gsmr_l = 0x10000000; m8260.scc3.dsr = 0x7E7E; /* flag character */ m8260.scc3.psmr = 0x2000; /* 2 flags between Tx'd frames */ /* printk("scc3 init\n" ); */ m8260.scc3.gsmr_l |= 0x00000030; /* Set ENR and ENT to enable Rx and Tx */ }
/* * Hardware-dependent portion of tcsetattr(). */ static int m8xx_smc_set_attributes (int minor, const struct termios *t) { int baud, brg=0, csize=0, ssize, psize; uint16_t clen=0, cstopb, parenb, parodd, cread; /* Baud rate */ switch (t->c_cflag & CBAUD) { default: baud = -1; break; case B50: baud = 50; break; case B75: baud = 75; break; case B110: baud = 110; break; case B134: baud = 134; break; case B150: baud = 150; break; case B200: baud = 200; break; case B300: baud = 300; break; case B600: baud = 600; break; case B1200: baud = 1200; break; case B1800: baud = 1800; break; case B2400: baud = 2400; break; case B4800: baud = 4800; break; case B9600: baud = 9600; break; case B19200: baud = 19200; break; case B38400: baud = 38400; break; case B57600: baud = 57600; break; case B115200: baud = 115200; break; case B230400: baud = 230400; break; case B460800: baud = 460800; break; } if (baud > 0) { switch( minor ) { case SMC1_MINOR: /* SMC1 can only choose between BRG1 and 7 */ brg = m8xx_get_brg( M8260_SMC1_BRGS, baud*16 ) + 1; m8260.cmxsmr &= ~0x30; m8260.cmxsmr |= (brg==1? 0x00: 0x10 ); break; case SMC2_MINOR: /* SMC2 can only choose between BRG2 and 8 */ brg = m8xx_get_brg( M8260_SMC2_BRGS, baud*16 ) + 1; m8260.cmxsmr &= ~0x30; m8260.cmxsmr |= (brg==2? 0x00: 0x01 ); break; } } /* Number of data bits */ switch ( t->c_cflag & CSIZE ) { case CS5: csize = 5; break; case CS6: csize = 6; break; case CS7: csize = 7; break; case CS8: csize = 8; break; } /* Stop bits */ if ( t->c_cflag & CSTOPB ) { cstopb = 0x0400; /* Two stop bits */ ssize = 2; } else { cstopb = 0x0000; /* One stop bit */ ssize = 1; } /* Parity */ if ( t->c_cflag & PARENB ) { parenb = 0x0200; /* Parity enabled on Tx and Rx */ psize = 1; } else { parenb = 0x0000; /* No parity on Tx and Rx */ psize = 0; } if ( t->c_cflag & PARODD ) parodd = 0x0000; /* Odd parity */ else parodd = 0x0100; /* * Character Length = start + data + parity + stop - 1 */ switch ( 1 + csize + psize + ssize - 1 ) { case 6: clen = 0x3000; break; case 7: clen = 0x3800; break; case 8: clen = 0x4000; break; case 9: clen = 0x4800; break; case 10: clen = 0x5000; break; case 11: clen = 0x5800; break; } if ( t->c_cflag & CREAD ) cread = 0x0023; /* UART normal operation, enable Rx and Tx */ else cread = 0x0021; /* UART normal operation, enable Tx */ /* Write the SIMODE/SMCMR registers */ switch (minor) { case SMC1_MINOR: /* m8xx.simode = ( (m8xx.simode & 0xffff8fff) | (brg << 12) ); */ m8260.smc1.smcmr = clen | cstopb | parenb | parodd | cread; break; case SMC2_MINOR: /* CHECK THIS */ /* m8xx.simode = ( (m8xx.simode & 0x8fffffff) | (brg << 28) ); */ m8260.smc2.smcmr = clen | cstopb | parenb | parodd | cread; break; } return 0; }