📄 console-generic.c
字号:
break;#endif } /* * Set up SDMA */ m8xx.sdcr = 0x01; /* as per section 16.10.2.1 MPC821UM/AD */ /* * Set up the SCC parameter RAM. */ sccparms->rbase = (char *)RxBd[minor] - (char *)&m8xx; sccparms->tbase = (char *)TxBd[minor] - (char *)&m8xx; sccparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0); sccparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0); if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) sccparms->mrblr = RXBUFSIZE; /* Maximum Rx buffer size */ else sccparms->mrblr = 1; /* Maximum Rx buffer size */ sccparms->un.uart.max_idl = 10; /* Set nb of idle chars to close buffer */ sccparms->un.uart.brkcr = 0; /* Set nb of breaks to send for STOP Tx */ sccparms->un.uart.parec = 0; /* Clear parity error counter */ sccparms->un.uart.frmec = 0; /* Clear framing error counter */ sccparms->un.uart.nosec = 0; /* Clear noise counter */ sccparms->un.uart.brkec = 0; /* Clear break counter */ sccparms->un.uart.uaddr[0] = 0; /* Not in multidrop mode, so clear */ sccparms->un.uart.uaddr[1] = 0; /* Not in multidrop mode, so clear */ sccparms->un.uart.toseq = 0; /* Tx Out-Of-SEQuence--no XON/XOFF now */ sccparms->un.uart.character[0] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[1] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[2] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[3] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[4] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[5] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[6] = 0x8000; /* Entry is invalid */ sccparms->un.uart.character[7] = 0x8000; /* Entry is invalid */ sccparms->un.uart.rccm = 0xc0ff; /* No masking */ /* * Set up the Receive Buffer Descriptor */ RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT; RxBd[minor]->length = 0; RxBd[minor]->buffer = rxBuf[minor]; /* * Setup the Transmit Buffer Descriptor */ TxBd[minor]->status = M8xx_BD_WRAP; /* * Set up SCCx general and protocol-specific mode registers */ sccregs->gsmr_h = 0x00000020; /* RFW=low latency operation */ sccregs->gsmr_l = 0x00028004; /* TDCR=RDCR=16x clock mode, MODE=uart*/ sccregs->scce = ~0; /* Clear any pending event */ sccregs->sccm = 0; /* Mask all interrupt/event sources */ sccregs->psmr = 0x3000; /* Normal operation & mode, 1 stop bit, 8 data bits, no parity */ sccregs->dsr = 0x7E7E; /* No fractional stop bits */ sccregs->gsmr_l = 0x00028034; /* ENT=enable Tx, ENR=enable Rx */ /* * Initialize the Rx and Tx with the new parameters. */ switch (minor) { case SCC2_MINOR: m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC2); break;#ifdef mpc860 case SCC3_MINOR: m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC3); break; case SCC4_MINOR: m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SCC4); break;#endif } if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) { consoleIrqData.on = m8xx_scc_enable; consoleIrqData.off = m8xx_scc_disable; consoleIrqData.isOn = m8xx_scc_isOn; switch (minor) { case SCC2_MINOR: consoleIrqData.name = BSP_CPM_IRQ_SCC2; consoleIrqData.hdl = m8xx_scc2_interrupt_handler; break;#ifdef mpc860 case SCC3_MINOR: consoleIrqData.name = BSP_CPM_IRQ_SCC3; consoleIrqData.hdl = m8xx_scc3_interrupt_handler; break; case SCC4_MINOR: consoleIrqData.name = BSP_CPM_IRQ_SCC4; consoleIrqData.hdl = m8xx_scc4_interrupt_handler; break;#endif /* mpc860 */ } if (!BSP_install_rtems_irq_handler (&consoleIrqData)) { printk("Unable to connect SCC Irq handler\n"); rtems_fatal_error_occurred(1); } }}void m8xx_smc_enable(const rtems_irq_connect_data* ptr){ volatile m8xxSMCRegisters_t *smcregs = 0; switch (ptr->name) { case BSP_CPM_IRQ_SMC1 : smcregs = &m8xx.smc1; break; case BSP_CPM_IRQ_SMC2_OR_PIP : smcregs = &m8xx.smc2; break; default: break; } smcregs->smcm = 3;}void m8xx_smc_disable(const rtems_irq_connect_data* ptr){ volatile m8xxSMCRegisters_t *smcregs = 0; switch (ptr->name) { case BSP_CPM_IRQ_SMC1 : smcregs = &m8xx.smc1; break; case BSP_CPM_IRQ_SMC2_OR_PIP : smcregs = &m8xx.smc2; break; default: break; } smcregs->smcm &= (~3);}int m8xx_smc_isOn(const rtems_irq_connect_data* ptr){ return BSP_irq_enabled_at_cpm (ptr->name);}voidm8xx_uart_smc_initialize (int minor){ unsigned char brg; volatile m8xxSMCparms_t *smcparms = 0; volatile m8xxSMCRegisters_t *smcregs = 0; /* * Check that minor number is valid */ if ( (minor < SMC1_MINOR) || (minor > SMC2_MINOR) ) return; m8xx.sdcr = 0x01; /* as per section 16.10.2.1 MPC821UM/AD */ /* Get the simode clock source bit values for 9600 bps */ brg = m8xx_get_brg_clk(9600); /* * Allocate buffer descriptors */ RxBd[minor] = m8xx_bd_allocate (1); TxBd[minor] = m8xx_bd_allocate (1); /* * Get the address of the parameter RAM for the specified port, * configure I/O port B and put SMC in NMSI mode, connect the * SMC to the appropriate BRG. * * SMC2 RxD is shared with port B bit 20 * SMC2 TxD is shared with port B bit 21 * SMC1 RxD is shared with port B bit 24 * SMC1 TxD is shared with port B bit 25 */ switch (minor) { case SMC1_MINOR: smcparms = &m8xx.smc1p; smcregs = &m8xx.smc1; m8xx.pbpar |= 0x000000C0; /* PB24 & PB25 are dedicated peripheral pins */ m8xx.pbdir &= ~0x000000C0; /* PB24 & PB25 must not drive UART lines */ m8xx.pbodr &= ~0x000000C0; /* PB24 & PB25 are not open drain */ m8xx.simode &= 0xFFFF0FFF; /* Clear SMC1CS & SMC1 for NMSI mode */ m8xx.simode |= brg << 12; /* SMC1CS = brg */ break; case SMC2_MINOR: smcparms = &m8xx.smc2p; smcregs = &m8xx.smc2; m8xx.pbpar |= 0x00000C00; /* PB20 & PB21 are dedicated peripheral pins */ m8xx.pbdir &= ~0x00000C00; /* PB20 & PB21 must not drive the UART lines */ m8xx.pbodr &= ~0x00000C00; /* PB20 & PB21 are not open drain */ m8xx.simode &= 0x0FFFFFFF; /* Clear SMC2CS & SMC2 for NMSI mode */ m8xx.simode |= brg << 28; /* SMC2CS = brg */ break; } /* * Set up SMC1 parameter RAM common to all protocols */ smcparms->rbase = (char *)RxBd[minor] - (char *)&m8xx; smcparms->tbase = (char *)TxBd[minor] - (char *)&m8xx; smcparms->rfcr = M8xx_RFCR_MOT | M8xx_RFCR_DMA_SPACE(0); smcparms->tfcr = M8xx_TFCR_MOT | M8xx_TFCR_DMA_SPACE(0); if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) smcparms->mrblr = RXBUFSIZE; /* Maximum Rx buffer size */ else smcparms->mrblr = 1; /* Maximum Rx buffer size */ /* * Set up SMC1 parameter RAM UART-specific parameters */ smcparms->un.uart.max_idl = 10; /* Set nb of idle chars to close buffer */ smcparms->un.uart.brkcr = 0; /* Set nb of breaks to send for STOP Tx */ smcparms->un.uart.brkec = 0; /* Clear break counter */ /* * Set up the Receive Buffer Descriptor */ RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT; RxBd[minor]->length = 0; RxBd[minor]->buffer = rxBuf[minor]; /* * Setup the Transmit Buffer Descriptor */ TxBd[minor]->status = M8xx_BD_WRAP; /* * Set up SMCx general and protocol-specific mode registers */ smcregs->smce = ~0; /* Clear any pending events */ smcregs->smcm = 0; /* Enable SMC Rx & Tx interrupts */ smcregs->smcmr = M8xx_SMCMR_CLEN(9) | M8xx_SMCMR_SM_UART; /* * Send "Init parameters" command */ switch (minor) { case SMC1_MINOR: m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC1); break; case SMC2_MINOR: m8xx_cp_execute_cmd (M8xx_CR_OP_INIT_RX_TX | M8xx_CR_CHAN_SMC2); break; } /* * Enable receiver and transmitter */ smcregs->smcmr |= M8xx_SMCMR_TEN | M8xx_SMCMR_REN; if ( (mbx8xx_console_get_configuration() & 0x06) == 0x02 ) { consoleIrqData.on = m8xx_smc_enable; consoleIrqData.off = m8xx_smc_disable; consoleIrqData.isOn = m8xx_smc_isOn; switch (minor) { case SMC1_MINOR: consoleIrqData.name = BSP_CPM_IRQ_SMC1; consoleIrqData.hdl = m8xx_smc1_interrupt_handler; break; case SMC2_MINOR: consoleIrqData.name = BSP_CPM_IRQ_SMC2_OR_PIP; consoleIrqData.hdl = m8xx_smc2_interrupt_handler; break; } if (!BSP_install_rtems_irq_handler (&consoleIrqData)) { printk("Unable to connect SMC Irq handler\n"); rtems_fatal_error_occurred(1); } }}voidm8xx_uart_initialize(void){ int i; for (i=0; i < 4; i++) { brg_spd[i] = 0; brg_used[i] = 0; }}intm8xx_uart_pollRead( int minor){ unsigned char c; if (RxBd[minor]->status & M8xx_BD_EMPTY) { return -1; } rtems_cache_invalidate_multiple_data_lines( (const void *) RxBd[minor]->buffer, RxBd[minor]->length ); c = ((char *)RxBd[minor]->buffer)[0]; RxBd[minor]->status = M8xx_BD_EMPTY | M8xx_BD_WRAP; return c;}/* * TODO: Get a free buffer and set it up. */int m8xx_uart_write( int minor, const char *buf, int len){ rtems_cache_flush_multiple_data_lines( buf, len ); TxBd[minor]->buffer = (char *) buf; TxBd[minor]->length = len; TxBd[minor]->status = M8xx_BD_READY | M8xx_BD_WRAP | M8xx_BD_INTERRUPT; return 0;} intm8xx_uart_pollWrite( int minor, const char *buf, int len){ while (len--) { while (TxBd[minor]->status & M8xx_BD_READY) continue; txBuf[minor] = *buf++; rtems_cache_flush_multiple_data_lines( (void *)&txBuf[minor], 1 ); TxBd[minor]->buffer = &txBuf[minor]; TxBd[minor]->length = 1; TxBd[minor]->status = M8xx_BD_READY | M8xx_BD_WRAP; } return 0;}voidm8xx_uart_reserve_resources( rtems_configuration_table *configuration){ rtems_termios_reserve_resources (configuration, NUM_PORTS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -