summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/gen68340/timer/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k/gen68340/timer/timer.c')
-rw-r--r--c/src/lib/libbsp/m68k/gen68340/timer/timer.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/m68k/gen68340/timer/timer.c b/c/src/lib/libbsp/m68k/gen68340/timer/timer.c
new file mode 100644
index 0000000000..a2bc2186fb
--- /dev/null
+++ b/c/src/lib/libbsp/m68k/gen68340/timer/timer.c
@@ -0,0 +1,287 @@
+/*
+ * Timer_init()
+ *
+ * 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-1998.
+ * On-Line Applications Research Corporation (OAR).
+ * Copyright assigned to U.S. Government, 1994.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ */
+
+#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 (*Restart_Check_A_Timer)();
+void (*Restart_Fifo_Full_B_Timer)();
+void (*Restart_Check_B_Timer)();
+
+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_Timer_initialize
+ Input parameters: -
+ Output parameters: -
+ Description: initialize Timer 1 for FIFO full mode
+ *****************************************************/
+void Fifo_Full_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;
+
+ proc_ptr ignored;
+ 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 */
+ /*
+ _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: Timer_initialize
+ Input parameters: -
+ Output parameters: -
+ Description: init Timer for timing test suites
+ *****************************************************/
+void 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: Read_timer
+ Input parameters: -
+ Output parameters: -
+ Description: Return timer value in microsecond units
+ *****************************************************/
+int
+Read_timer (void)
+{
+ /* there's CLOCK_SPEED / 16 micro seconds between two timer register decrement */
+ return (((0xFFFF - TCNTR2) * CLOCK_SPEED) / 16);
+}
+
+/******************************************************
+ Name: Empty_function
+ Input parameters: -
+ Output parameters: -
+ Description: Empty function call used in loops to
+ measure basic cost of looping
+ in Timing Test Suite.
+ *****************************************************/
+rtems_status_code
+Empty_function (void)
+{
+ return RTEMS_SUCCESSFUL;
+}
+
+/******************************************************
+ Name: Set_find_average_overhead
+ Input parameters: -
+ Output parameters: -
+ Description: -
+ *****************************************************/
+void
+Set_find_average_overhead(rtems_boolean find_flag)
+{
+}