summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/m68k/gen68340/timer/timer.c
blob: 3331385976a0e1806ccb061e9407352db8a536a1 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
  











                                                                               
  










                             
                                                               

                                                         
                            
                                                    


                                                           
                                         



















                                            



                                        







                                                       
                                                 













































                                                                                                                                                                                      
                                            



                                                       
                                                








                                          
                                          















                                                                                  

                                                                                                                                






                                                                               
                                     























                                                     
         









                                                                              








                                                                                        



                                                                                              














                                                                                             
                                  



                                                       
                                      

























                                                                                  
                            




                                                       
                           





                                                                                  
                                                            




                                                       
                                                                    

 
/*
 * ATTENTION: AS MC68349 has no built-in Timer, the following code doesn't work
 * 	      in a MC68349. You can't use FIFO full mode for the moment, but
 *	      it should be easy to fix this by using an external timer
 *
 * Use TIMER 1 for TIMEOUT when using FIFO FULL mode in UART driver
 * Use TIMER 2 for timing test suites
 *
 * Geoffroy Montel
 * France Telecom - CNET/DSM/TAM/CAT
 * 4, rue du Clos Courtel
 * 35512 CESSON-SEVIGNE
 * FRANCE
 *
 * e-mail: g_montel@yahoo.com
 *
 *  $Id$
 */

/*
 *
 *  Input parameters:  NONE
 *
 *  Output parameters:  NONE
 *
 *  NOTE: It is important that the timer start/stop overhead be
 *        determined when porting or modifying this code.
 *
 *  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.
 */

#include <rtems.h>
#include <bsp.h>
#include <m340uart.h>
#include <m340timer.h>
#include <m68340.h>

#define TIMER1_VECTOR 122
#define TIMER1_IRQ_LEVEL 5
#define TIMER1_INTERRUPT_ARBITRATION 5

#define TIMER2_VECTOR 123
#define TIMER2_IRQ_LEVEL 4
#define TIMER2_INTERRUPT_ARBITRATION 4

#define CLOCK_SPEED 25		/* in Mhz */

#define max(a,b) (((a)>(b)) ? (a) : (b))

void (*Restart_Fifo_Full_A_Timer)(void);
void (*Restart_Check_A_Timer)(void);
void (*Restart_Fifo_Full_B_Timer)(void);
void (*Restart_Check_B_Timer)(void);

int preload = 0;

/******************************************************
  Name: __Restart_Fifo_Full_Timer
  Input parameters: -
  Output parameters: -
  Description: when a character is received, sets
               the TIMER to raise an interrupt at
	       TIMEOUT.
	       It's necessary to prevent from not
	       getting n-1 characters (with n the
               Uart Fifo size)
 *****************************************************/
void __Restart_Fifo_Full_Timer (void)
{
 TSR1 |= m340_TO;
 TCR1 &= ~m340_CPE;
 WPREL11 = preload;
 TCR1 |= m340_CPE;
}

/******************************************************
  Name: __Restart_Fifo_Full_Timer
  Input parameters: -
  Output parameters: -
  Description: when no character has been received
               recently, check now and then if whether
	       a there's a character in the FIFO
 *****************************************************/
void __Restart_Check_Timer (void)
{
 TSR1 |= m340_TO;
 TCR1 &= ~m340_CPE;
 WPREL11 = 0xFFFF;
 TCR1 |= m340_CPE;
}

/******************************************************
  Name: __do_nothing
  Input parameters: -
  Output parameters: -
  Description: we always restart the fifo full timer
	       with a call to Restart_*_Timer
	       if we do not use FIFO full, Restart_*_Timer
	       are set to do __do_nothing
 *****************************************************/
void __do_nothing (void)
{
}

#define Fifo_Full_on_A (m340_uart_config[UART_CHANNEL_A].rx_mode==UART_FIFO_FULL && m340_uart_config[UART_CHANNEL_A].enable && m340_uart_config[UART_CHANNEL_A].mode==UART_INTERRUPTS)
#define Fifo_Full_on_B (m340_uart_config[UART_CHANNEL_B].rx_mode==UART_FIFO_FULL && m340_uart_config[UART_CHANNEL_B].enable && m340_uart_config[UART_CHANNEL_B].mode==UART_INTERRUPTS)

/******************************************************
  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;

	 extern void _Debug_ISR_Handler_Console(void);

	 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: benchmark_timer_initialize
  Input parameters: -
  Output parameters: -
  Description: init Timer for timing test suites
 *****************************************************/
void benchmark_timer_initialize (void)
{
	/* Disable the timer */
	TCR2 &= ~m340_SWR;

	/* Reset the interrupts */
	TSR2 &= ~(m340_TO | m340_TG | m340_TC);

	/* Init the stop bit for normal operation, ignore FREEZE, user privileges,
	   set interrupt arbitration */
	TMCR1 = TIMER2_INTERRUPT_ARBITRATION;

	/* interrupt priority level and interrupt vector */
	TIR1 = TIMER2_VECTOR | (TIMER2_IRQ_LEVEL << 8);

	/* Init the stop bit for normal operation, ignore FREEZE, user privileges,
	   set interrupt arbitration */
	TMCR2 = TIMER2_INTERRUPT_ARBITRATION;

	/* Preload register 1 */
	WPREL21 = 0xFFFF;

	/* Input Capture/Output Compare (ICOC) */
	TCR2 = m340_SWR | m340_ICOC | m340_PSE | m340_Divide_by_16 | m340_CPE;
}

/******************************************************
  Name: benchmark_timer_read
  Input parameters: -
  Output parameters: -
  Description: Return timer value in microsecond units
 *****************************************************/
int
benchmark_timer_read (void)
{
 /* there's CLOCK_SPEED / 16 micro seconds between two timer register decrement */
 return (((0xFFFF - TCNTR2) * CLOCK_SPEED) / 16);
}

/******************************************************
  Name: benchmark_timer_disable_subtracting_average_overhead
  Input parameters: -
  Output parameters: -
  Description: -
 *****************************************************/
void
benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
{
}