📄 console.c
字号:
/* * 68340/68349 console serial I/O. * * Author: * Geoffroy Montel * France Telecom - CNET/DSM/TAM/CAT * 4, rue du Clos Courtel * 35512 CESSON-SEVIGNE * FRANCE * * e-mail: g_montel@yahoo.com * * COPYRIGHT (c) 1989-1999. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * * http://www.rtems.com/license/LICENSE. * * $Id: console.c,v 1.6.2.1 2003/09/04 18:44:25 joel Exp $ */#include <termios.h>#include <bsp.h>#include <rtems/libio.h>#include <m68340.h>#include <m340uart.h>#include <m340timer.h>#include <stdarg.h>#include <stdio.h>#include <stdlib.h>#define CONSOLE_VECTOR 121#define CONSOLE_IRQ_LEVEL 3#define CONSOLE_INTERRUPT_ARBITRATION 2static void *ttypA; /* to remember which tty has been opened on channel A used when interrupts are enabled */static void *ttypB; /* to remember which tty has been opened on channel B used when interrupts are enabled */unsigned char DUIER_mirror = 0 ; /* reflects the state of IER register, which is Write Only */unsigned char Error_Status_A = 0; /* error status on Channel A */unsigned char Error_Status_B = 0; /* error status on Channel A *//* * Device-specific routines */#define USE_INTERRUPTS_A (m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS)#define USE_INTERRUPTS_B (m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS)#define CHANNEL_ENABLED_A m340_uart_config[UART_CHANNEL_A].enable#define CHANNEL_ENABLED_B m340_uart_config[UART_CHANNEL_B].enable#define set_DUIER(a) DUIER_mirror |= (a); DUIER = DUIER_mirror#define unset_DUIER(a) DUIER_mirror &= ~(a); DUIER = DUIER_mirror#define Enable_Interrupts_Tx_A if (USE_INTERRUPTS_A) set_DUIER(m340_TxRDYA)#define Disable_Interrupts_Tx_A if (USE_INTERRUPTS_A) unset_DUIER(m340_TxRDYA)#define Enable_Interrupts_Tx_B if (USE_INTERRUPTS_B) set_DUIER(m340_TxRDYB)#define Disable_Interrupts_Tx_B if (USE_INTERRUPTS_B) unset_DUIER(m340_TxRDYB)/****************************************************** Name: InterruptHandler Input parameters: vector number Output parameters: - Description: UART ISR Routine, called by _RTEMS_ISR *****************************************************/rtems_isrInterruptHandler (rtems_vector_number v){ char ch; /***************************************************************************** ** CHANNEL A ** *****************************************************************************/ /* check Received Break*/ if (DUSRA & m340_RB) { Error_Status_A |= m340_RB; /* reset error status */ DUCRA = m340_Reset_Error_Status; } /* buffer received ? */ if (DUSRA & m340_Rx_RDY) { do { /* error encountered? */ if (DUSRA & (m340_OE | m340_PE | m340_FE | m340_RB)) { Error_Status_A |= DUSRA; /* reset error status */ DUCRA = m340_Reset_Error_Status; /* all the characters in the queue may not be good */ while (DUSRA & m340_Rx_RDY) /* push them in a trash */ ch = DURBA; } else { /* this is necessary, otherwise it blocks when FIFO is full */ ch = DURBA; rtems_termios_enqueue_raw_characters(ttypA,&ch,1); } } while (DUSRA & m340_Rx_RDY); Restart_Fifo_Full_A_Timer(); /* only if necessary (pointer to a fake function if not in FIFO full mode) */ } else /* if no character has been received */ Restart_Check_A_Timer(); /* same remark */ /* ready to accept a character ? */ if (DUISR & DUIER_mirror & m340_TxRDYA) { Disable_Interrupts_Tx_A; /* one character has been transmitted */ rtems_termios_dequeue_characters(ttypA,1); } /***************************************************************************** ** CHANNEL B ** *****************************************************************************/ /* check Received Break*/ if (DUSRB & m340_RB) { Error_Status_B |= m340_RB; /* reset error status */ DUCRB = m340_Reset_Error_Status; } /* buffer received ? */ if (DUSRB & m340_Rx_RDY) { do { if (DUSRB & (m340_OE | m340_PE | m340_FE | m340_RB)) { Error_Status_B |= DUSRB; /* reset error status */ DUCRB = m340_Reset_Error_Status; /* all the characters in the queue may not be good */ while (DUSRB & m340_Rx_RDY) /* push them in a trash */ ch = DURBB; } else { ch = DURBB; rtems_termios_enqueue_raw_characters(ttypB,&ch,1); } } while (DUSRB & m340_Rx_RDY); Restart_Fifo_Full_B_Timer(); } else /* if no character has been received */ Restart_Check_B_Timer(); /* ready to accept a character ? */ if (DUISR & DUIER_mirror & m340_TxRDYB) { Disable_Interrupts_Tx_B; /* one character has been transmitted */ rtems_termios_dequeue_characters(ttypB,1); }}/****************************************************** Name: InterruptWrite Input parameters: minor = channel, pointer to buffer, and length of buffer to transmit Output parameters: - Description: write the first character of buf only may be called by either console_write or rtems_termios_enqueue_raw_characters *****************************************************/static intInterruptWrite (int minor, const char *buf, int len){ if (minor==UART_CHANNEL_A) { if (len>0) (char)DUTBA=*buf; Enable_Interrupts_Tx_A; } else if (minor==UART_CHANNEL_B) { if (len>0) (char)DUTBB=*buf; Enable_Interrupts_Tx_B; } return 0;}/****************************************************** Name: dbug_out_char Input parameters: channel, character to emit Output parameters: - Description: wait for the UART to be ready to emit a character and send it *****************************************************/void dbug_out_char( int minor, int ch ){ if (minor==UART_CHANNEL_A) { while (!(DUSRA & m340_Tx_RDY)) continue; DUTBA=ch; } else if (minor==UART_CHANNEL_B) { while (!(DUSRB & m340_Tx_RDY)) continue; DUTBB=ch; }}/****************************************************** Name: dbug_in_char Input parameters: - Output parameters: received character Description: return the character in the UART *****************************************************/int dbug_in_char( int minor ){ if (minor==UART_CHANNEL_A) { return DURBA; } else if (minor==UART_CHANNEL_B) { return DURBB; } return 0;}/****************************************************** Name: dbug_char_present Input parameters: channel # Output parameters: TRUE or FALSE Description: return whether there's a character in the receive buffer *****************************************************/int dbug_char_present( int minor ){ if (minor==UART_CHANNEL_A) { return (DUSRA & m340_Rx_RDY); } else if (minor==UART_CHANNEL_B) { return (DUSRB & m340_Rx_RDY); } return 0;}/****************************************************** Name: dbugInitialise Input parameters: - Output parameters: - Description: Init the UART *****************************************************/static voiddbugInitialise (){ t_baud_speed_table uart_config; /* configuration of UARTS */ /* * Reset Receiver */ DUCRA = m340_Reset_Receiver; DUCRB = m340_Reset_Receiver; /* * Reset Transmitter */ DUCRA = m340_Reset_Transmitter; DUCRB = m340_Reset_Transmitter; /* * Enable serial module for normal operation, ignore FREEZE, select the crystal clock, * supervisor/user serial registers unrestricted * interrupt arbitration at priority CONSOLE_INTERRUPT_ARBITRATION * WARNING : 8 bits access only on this UART! */ DUMCRH = 0x00; DUMCRL = CONSOLE_INTERRUPT_ARBITRATION; /* * Interrupt level register */ DUILR = CONSOLE_IRQ_LEVEL; /* sets the IVR */ DUIVR = CONSOLE_VECTOR; /* search for a correct m340 uart configuration */ uart_config = Find_Right_m340_UART_Config(m340_uart_config[UART_CHANNEL_A].rx_baudrate, m340_uart_config[UART_CHANNEL_A].tx_baudrate, CHANNEL_ENABLED_A, m340_uart_config[UART_CHANNEL_B].rx_baudrate, m340_uart_config[UART_CHANNEL_B].tx_baudrate, CHANNEL_ENABLED_B); /***************************************************************************** ** CHANNEL A ** *****************************************************************************/ if (CHANNEL_ENABLED_A) { if (USE_INTERRUPTS_A) { rtems_isr_entry old_handler; rtems_status_code sc; extern void _Debug_ISR_Handler_Console(void); sc = rtems_interrupt_catch (InterruptHandler, CONSOLE_VECTOR, &old_handler); /* uncomment this if you want to pass control to your own ISR handler it may be usefull to do so to check for performances with an oscilloscope */ /* { proc_ptr ignored; _CPU_ISR_install_raw_handler( CONSOLE_VECTOR, _Debug_ISR_Handler_Console, &ignored ); } */ /* * Interrupt Enable Register * Enable Interrupts on Channel A Receiver Ready */ set_DUIER(m340_RxRDYA); } else { /* * Disable Interrupts on channel A */ unset_DUIER(m340_RxRDYA&m340_TxRDYA); } /* * Change set of baud speeds * disable input control */ /* no good uart configuration ? */ if (uart_config.nb<1) rtems_fatal_error_occurred (-1); if (uart_config.baud_speed_table[UART_CHANNEL_A].set==1) DUACR = m340_BRG_Set1; else DUACR = m340_BRG_Set2; /* * make OPCR an auxiliary function serving the communication channels */ DUOPCR = m340_OPCR_Aux; /* poll the XTAL_RDY bit until it is cleared to ensure that an unstable crystal input is not applied to the baud rate generator */ while (DUISR & m340_XTAL_RDY) continue; /* * Serial Channel Baud Speed */ DUCSRA = (uart_config.baud_speed_table[UART_CHANNEL_A].rcs << 4) | (uart_config.baud_speed_table[UART_CHANNEL_A].tcs);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -