/****************************************************** Name: Fifo_Full_benchmark_timer_initialize Input parameters: - Output parameters: - Description: initialize Timer 1 for FIFO full mode *****************************************************/ void Fifo_Full_benchmark_timer_initialize (void) { float max_baud_rate; int prescaler_output_tap = -1; int nb_of_clock_ticks = 0; /* * USE TIMER 1 for UART FIFO FULL mode */ if ( Fifo_Full_on_A || Fifo_Full_on_B ) { /* Disable the timer */ TCR1 &= ~m340_SWR; /* Reset the interrupts */ TSR1 &= ~(m340_TO | m340_TG | m340_TC); /* Init the stop bit for normal operation, ignore FREEZE, user privileges, set interrupt arbitration */ TMCR1 = TIMER1_INTERRUPT_ARBITRATION; /* interrupt priority level and interrupt vector */ TIR1 = TIMER1_VECTOR | (TIMER1_IRQ_LEVEL << 8); /* compute prescaler */ if ( Fifo_Full_on_A && Fifo_Full_on_B) max_baud_rate = max(m340_uart_config[UART_CHANNEL_A].rx_baudrate, m340_uart_config[UART_CHANNEL_B].rx_baudrate); else if ( Fifo_Full_on_A ) max_baud_rate = m340_uart_config[UART_CHANNEL_A].rx_baudrate; else max_baud_rate = m340_uart_config[UART_CHANNEL_B].rx_baudrate; /* find out config */ nb_of_clock_ticks = (10/max_baud_rate)*(CLOCK_SPEED*1000000)*1.2; if (nb_of_clock_ticks < 0xFFFF) { preload = nb_of_clock_ticks; prescaler_output_tap = -1; } else if (nb_of_clock_ticks/2 < 0xFFFF) { preload = nb_of_clock_ticks/2; prescaler_output_tap = m340_Divide_by_2; } else if (nb_of_clock_ticks/4 < 0xFFFF) { preload = nb_of_clock_ticks/4; prescaler_output_tap = m340_Divide_by_4; } else if (nb_of_clock_ticks/8 < 0xFFFF) { preload = nb_of_clock_ticks/8; prescaler_output_tap = m340_Divide_by_16; } else if (nb_of_clock_ticks/16 < 0xFFFF) { preload = nb_of_clock_ticks/16; prescaler_output_tap = m340_Divide_by_16; } else if (nb_of_clock_ticks/32 < 0xFFFF) { preload = nb_of_clock_ticks/32; prescaler_output_tap = m340_Divide_by_32; } else if (nb_of_clock_ticks/64 < 0xFFFF) { preload = nb_of_clock_ticks/64; prescaler_output_tap = m340_Divide_by_64; } else if (nb_of_clock_ticks/128 < 0xFFFF) { preload = nb_of_clock_ticks/128; prescaler_output_tap = m340_Divide_by_128; } else if (nb_of_clock_ticks/256 < 0xFFFF) { preload = nb_of_clock_ticks/256; prescaler_output_tap = m340_Divide_by_256; } /* Input Capture/Output Compare (ICOC) */ TCR1 = m340_SWR | m340_TO_Enabled | m340_ICOC; if (prescaler_output_tap!=-1) TCR1 |= prescaler_output_tap | m340_PSE; /* install interrupt vector */ { rtems_isr_entry old_handler; rtems_status_code sc; sc = rtems_interrupt_catch (InterruptHandler, TIMER1_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( TIMER1_VECTOR, _Debug_ISR_Handler_Console, &ignored ); } */ } } /* fifo full mode on a uart */ /* install routines */ Restart_Check_A_Timer = Fifo_Full_on_A ? __Restart_Check_Timer : __do_nothing; Restart_Fifo_Full_A_Timer = Fifo_Full_on_A ? __Restart_Fifo_Full_Timer : __do_nothing; Restart_Check_B_Timer = Fifo_Full_on_B ? __Restart_Check_Timer : __do_nothing; Restart_Fifo_Full_B_Timer = Fifo_Full_on_B ? __Restart_Fifo_Full_Timer : __do_nothing; /* start checking timer */ Restart_Check_A_Timer(); Restart_Check_B_Timer(); }
/****************************************************** Name: InterruptHandler Input parameters: vector number Output parameters: - Description: UART ISR Routine, called by _RTEMS_ISR *****************************************************/ rtems_isr InterruptHandler (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); } }