Example #1
0
void fire( void ) {
    //fire
    REG[0] = FIRE;
    at91_tc_write ( & TC1_DESC, REG );

    //pause
    wait( SEC );
    wait( SEC );

    //c**k
    REG[0] = C**K;
    at91_tc_write ( & TC1_DESC, REG );
}
Example #2
0
int rt_request_timer (void (*handler)(void), unsigned tick, int use_apic)
{
	unsigned long flags;

	flags = rtai_critical_enter(NULL);

	__ipipe_mach_timerstolen = 1;		// no need to reprogram timer on timer_tick() call

	rt_times.tick_time = rtai_rdtsc();
	rt_times.linux_tick = __ipipe_mach_ticks_per_jiffy;
	if (tick > 0) {
		rt_periodic = 1;

		/* Periodic setup --
		Use the built-in Adeos service directly. */
		if (tick > __ipipe_mach_ticks_per_jiffy) {
			tick = __ipipe_mach_ticks_per_jiffy;
		}
		rt_times.intr_time = rt_times.tick_time + tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = tick;

		/* Prepare TCx to reload automaticly on RC compare */
		at91_tc_write(AT91_TC_CCR, AT91_TC_CLKDIS);
		at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3 | AT91_TC_WAVESEL_UP_AUTO | AT91_TC_WAVE);
		at91_tc_write(AT91_TC_RC, rt_times.periodic_tick);
		at91_tc_write(AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG);
	} else {
		rt_periodic = 0;

		/* Oneshot setup. */
		rt_times.intr_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.linux_time = rt_times.tick_time + rt_times.linux_tick;
		rt_times.periodic_tick = rt_times.linux_tick;

		/* Prepare TCx behaviour as oneshot timer */
		at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3);
		rt_set_timer_delay(rt_times.periodic_tick);
	}

        rt_release_irq(RTAI_TIMER_IRQ);

	rt_request_irq(RTAI_TIMER_IRQ, (rt_irq_handler_t)handler, NULL, 0);
	extern_timer_isr = rtai_timer_handler;	// shunt for ipipe.c __ipipe_grab_irq

	rtai_critical_exit(flags);

        return 0;
}
Example #3
0
//*----------------------------------------------------------------------------
//* Function Name       : at91_tc_wait_open
//* Object              : Stop the ARM core during <microsec> us
//* Input Parameters    : <wait_desc> = Wait Descriptor pointer.
//* Output Parameters   : None
//* Functions called    : 
//*----------------------------------------------------------------------------
void at91_wait_open ( WaitDesc *wait_desc )
//* Begin
{
    u_int   clock_select ;
    u_int   regs[4] ;

    switch ( wait_desc->mode )
    {
        case WAIT_DELAY :
        case WAIT_NEXT_EVENT_MAX_DELAY :
            //* Startup the Timer Counter Channel
            at91_tc_open ( wait_desc->tc_desc, TC_WAVE | TC_CPCDIS, FALSE, FALSE) ;
            //* Compute and Setup register C for period depending on master clock
            regs[RA] = 0 ;
            regs[RC] = wait_desc->period ;
            //* Setup registers according master clock and required timings 
            at91_tc_compute_microsec ( &regs[RC], &clock_select, wait_desc->mcki_khz ) ;
            regs[RB] = regs[RC] ;
            at91_tc_set_mode (wait_desc->tc_desc, clock_select, 1) ;
            at91_tc_write (wait_desc->tc_desc, regs ) ;
            //* Open the interrupt on the AIC
            at91_irq_open ( wait_desc->tc_desc->periph_id, 7, AIC_SRCTYPE_INT_EDGE_TRIGGERED, wait_desc->handler ) ;
            //* Enable the RC Compare interrupt
            wait_desc->tc_desc->tc_base->TC_IER = TC_CPCS ;
            //* Trig the timer
            at91_tc_trig_cmd ( wait_desc->tc_desc, TC_TRIG_CHANNEL ) ;
            break ;
    }
    
    switch ( wait_desc->mode )
    {
        case WAIT_DELAY :
        case WAIT_NEXT_EVENT :
            //* Enter Idle Mode
            at91_clock_set_mode ( PS_MODE_IDLE ) ;
            break ;

        case WAIT_NEXT_EVENT_MAX_DELAY :
            //* While the Timer Counter hasn't reached the end
            while (( wait_desc->tc_desc->tc_base->TC_SR & TC_CPCS ) == 0 ) 
                //* Enter Idle Mode
                at91_clock_set_mode ( PS_MODE_IDLE ) ;
            break ;         
    }

    switch ( wait_desc->mode )
    {
        case WAIT_DELAY :
        case WAIT_NEXT_EVENT_MAX_DELAY :
            //* Close the interrupt on the AIC
            at91_irq_close ( wait_desc->tc_desc->periph_id ) ;
            //* Close the Timer Counter Channel
            at91_tc_close ( wait_desc->tc_desc );
            break ;
    }
//* End
}
Example #4
0
void rt_free_timer (void)
{
	unsigned long flags;

	rt_periodic = 0;
	__ipipe_mach_timerstolen = 0;		// ipipe can reprogram timer for Linux now
	at91_tc_write(AT91_TC_CMR, AT91_TC_TIMER_CLOCK3); // back to oneshot mode
	rt_set_timer_delay(__ipipe_mach_ticks_per_jiffy); // regular timer delay
	rt_release_irq(RTAI_TIMER_IRQ);		// free this irq
	rtai_save_flags_and_cli(flags);		// critical section
	extern_timer_isr = NULL;		// let ipipe run as normally
	rtai_restore_flags(flags);		// end of critical section
}
Example #5
0
void servoInit(void) {
    u_int mode = TC_CLKS_MCK32    |
                 TC_EEVT_XC0               |
                 TC_CPCTRG                 |
                 TC_WAVE                   |
                 TC_ACPA_CLEAR_OUTPUT      |
                 TC_ACPC_SET_OUTPUT        |
                 TC_ASWTRG_SET_OUTPUT;

    //initialize/turn on servo
    at91_tc_open ( & TC1_DESC, mode, TRUE, FALSE );
    at91_tc_write ( & TC1_DESC, REG );
    at91_tc_trig_cmd ( & TC1_DESC, TC_TRIG_CHANNEL );

}
Example #6
0
void __init at91x40_timer_init(void)
{
	unsigned int v;

	at91_tc_write(AT91_TC_BCR, 0);
	v = at91_tc_read(AT91_TC_BMR);
	v = (v & ~AT91_TC_TC1XC1S) | AT91_TC_TC1XC1S_NONE;
	at91_tc_write(AT91_TC_BMR, v);

	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, AT91_TC_CLKDIS);
	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CMR, (AT91_TC_TIMER_CLOCK4 | AT91_TC_CPCTRG));
	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IDR, 0xffffffff);
	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_RC, (AT91X40_MASTER_CLOCK / 128) / HZ - 1);
	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_IER, (1<<4));

	setup_irq(AT91X40_ID_TC1, &at91x40_timer_irq);

	at91_tc_write(AT91_TC_CLK1BASE + AT91_TC_CCR, (AT91_TC_SWTRG | AT91_TC_CLKEN));
}
Example #7
0
void at91_ipipe_init(struct clock_event_device *host_timer)
{
	unsigned char tc_divisors[] = { 2, 8, 32, 128, 0, };
	unsigned master_freq, divisor = 0, divided_freq = 0;
	unsigned long long wrap_ns;
	int tc_timer_clock;
	unsigned short v;
	struct clk *clk;

#ifdef CONFIG_ARCH_AT91SAM9263
	clk = clk_get(NULL, "tcb_clk");
#elif defined(CONFIG_ARCH_AT91SAM9G45)
	clk = clk_get(NULL, "tcb0_clk");
#else /* not AT91SAM9263 or AT91SAM9G45*/
	clk = clk_get(NULL, "tc"__stringify(CONFIG_IPIPE_AT91_TC) "_clk");
#endif

	clk_enable(clk);

	/* Disable the channel */
	at91_tc_write(AT91_TC_CCR, AT91_TC_CLKDIS);

	/* Disable all interrupts. */
	at91_tc_write(AT91_TC_IDR, ~0ul);

	master_freq = clk_get_rate(clk_get(NULL, "mck"));
	/* Find the first frequency above 1 MHz */
	for (tc_timer_clock = ARRAY_SIZE(tc_divisors) - 1;
	     tc_timer_clock >= 0; tc_timer_clock--) {
		divisor = tc_divisors[tc_timer_clock];
		divided_freq = (divisor
				? master_freq / divisor : AT91_SLOW_CLOCK);
		if (divided_freq > 1000000)
			break;
	}

	wrap_ns = (unsigned long long) (AT91_TC_REG_MASK + 1) * NSEC_PER_SEC;
	do_div(wrap_ns, divided_freq);

	if (divided_freq < 1000000)
		printk(KERN_INFO "AT91 I-pipe warning: could not find a"
		       " frequency greater than 1MHz\n");

	printk(KERN_INFO "AT91 I-pipe timer: div: %u, freq: %u.%06u MHz, wrap: "
	       "%u.%06u ms\n", divisor,
	       divided_freq / 1000000, divided_freq % 1000000,
	       (unsigned) wrap_ns / 1000000, (unsigned) wrap_ns % 1000000);

	/* Add a 1ms margin. It means that when an interrupt occurs, update_tsc
	   must be called within 1ms. update_tsc is called by acktimer when no
	   higher domain handles the timer, and called through set_dec when a
	   higher domain handles the timer. */
	wrap_ns -= 1000000;
	/* Set up the interrupt. */

	if (host_timer && host_timer->features & CLOCK_EVT_FEAT_ONESHOT
	    && host_timer->max_delta_ns > wrap_ns)
		host_timer->max_delta_ns = wrap_ns;

	/* No Sync. */
	at91_tc_write(AT91_TC_BCR, 0);

	/* program NO signal on XCN */
	v = readl((void __iomem *) (AT91_VA_BASE_TCB0 + AT91_TC_BMR));
	v &= ~TCNXCNS(CONFIG_IPIPE_AT91_TC, 3);
	v |= TCNXCNS(CONFIG_IPIPE_AT91_TC, 1); /* AT91_TC_TCNXCNS_NONE */
	writel(v, (void __iomem *) (AT91_VA_BASE_TCB0 + AT91_TC_BMR));

	/* Use the clock selected as input clock. */
	at91_tc_write(AT91_TC_CMR, tc_timer_clock);

	/* Load the TC register C. */
	write_RC(0xffff);

	/* Enable the channel. */
	at91_tc_write(AT91_TC_CCR, AT91_TC_CLKEN | AT91_TC_SWTRG);

	at91_itimer.freq = divided_freq;
	at91_itimer.min_delay_ticks = ipipe_timer_ns2ticks(&at91_itimer, 2000);
	max_delta_ticks = ipipe_timer_ns2ticks(&at91_itimer, wrap_ns);
	ipipe_timer_register(&at91_itimer);

	tsc_info.freq = divided_freq;
	__ipipe_tsc_register(&tsc_info);

	at91_pic_muter_register();
}
Example #8
0
static void at91_tc_release(struct ipipe_timer *timer)
{
	/* Disable all interrupts. */
	at91_tc_write(AT91_TC_IDR, ~0ul);
}
Example #9
0
static void at91_tc_request(struct ipipe_timer *timer, int steal)
{
	/* Enable CPCS interrupt. */
	at91_tc_write(AT91_TC_IER, AT91_TC_CPCS);
}