Esempio n. 1
0
static void
avr_timer_configure(
		avr_timer_t * p,
		uint32_t clock,
		uint32_t top,
		uint8_t reset)
{
	p->tov_cycles = 0;
	p->tov_top = top;

	p->tov_cycles = clock * (top+1);

	AVR_LOG(p->io.avr, LOG_TRACE, "TIMER: %s-%c TOP %.2fHz = %d cycles = %dusec\n",
			__FUNCTION__, p->name, (p->io.avr->frequency / (float)p->tov_cycles),
			(int)p->tov_cycles, (int)avr_cycles_to_usec(p->io.avr, p->tov_cycles));

	for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
		if (!p->comp[compi].r_ocr)
			continue;
		uint32_t ocr = _timer_get_ocr(p, compi);
		uint32_t comp_cycles = clock * (ocr + 1);

		p->comp[compi].comp_cycles = 0;

		if (p->trace & (avr_timer_trace_compa << compi))
			printf("%s-%c clock %f top %d OCR%c %d\n", __FUNCTION__, p->name,
				(float)(p->io.avr->frequency / clock), top, 'A'+compi, ocr);

		if (ocr && ocr <= top) {
			p->comp[compi].comp_cycles = comp_cycles; // avr_hz_to_cycles(p->io.avr, fa);

			if (p->trace & (avr_timer_trace_compa << compi)) printf(
					"TIMER: %s-%c %c %.2fHz = %d cycles\n",
					__FUNCTION__, p->name,
					'A'+compi, (float)(p->io.avr->frequency / ocr),
					(int)p->comp[compi].comp_cycles);
		}
	}

	if (p->tov_cycles > 1) {
		if (reset)
		{
			avr_cycle_timer_register(p->io.avr, p->tov_cycles, avr_timer_tov, p);
			// calling it once, with when == 0 tells it to arm the A/B/C timers if needed
			p->tov_base = 0;
			avr_timer_tov(p->io.avr, p->io.avr->cycle, p);
		}
		else
		{
			uint64_t orig_tov_base = p->tov_base;
			avr_cycle_timer_register(p->io.avr, p->tov_cycles - (p->io.avr->cycle - orig_tov_base), avr_timer_tov, p);
			// calling it once, with when == 0 tells it to arm the A/B/C timers if needed
			p->tov_base = 0;
			avr_timer_tov(p->io.avr, orig_tov_base, p);
		}
	}
}
Esempio n. 2
0
static void avr_timer_tcnt_write(struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param)
{
	avr_timer_t * p = (avr_timer_t *)param;
	avr_core_watch_write(avr, addr, v);
	uint16_t tcnt = _timer_get_tcnt(p);

	if (!p->tov_top)
		return;
		
	if (tcnt >= p->tov_top)
		tcnt = 0;
	
	// this involves some magicking
	// cancel the current timers, recalculate the "base" we should be at, reset the
	// timer base as it should, and re-schedule the timers using that base.
	
	avr_cycle_timer_cancel(avr, avr_timer_tov, p);
	avr_cycle_timer_cancel(avr, avr_timer_compa, p);
	avr_cycle_timer_cancel(avr, avr_timer_compb, p);
	avr_cycle_timer_cancel(avr, avr_timer_compc, p);

	uint64_t cycles = (tcnt * p->tov_cycles) / p->tov_top;

//	printf("%s-%c %d/%d -- cycles %d/%d\n", __FUNCTION__, p->name, tcnt, p->tov_top, (uint32_t)cycles, (uint32_t)p->tov_cycles);

	// this reset the timers bases to the new base
	if (p->tov_cycles > 1) {
		avr_cycle_timer_register(avr, p->tov_cycles - cycles, avr_timer_tov, p);
		p->tov_base = 0;
		avr_timer_tov(avr, avr->cycle - cycles, p);
	}

//	tcnt = ((avr->cycle - p->tov_base) * p->tov_top) / p->tov_cycles;
//	printf("%s-%c new tnt derive to %d\n", __FUNCTION__, p->name, tcnt);	
}
Esempio n. 3
0
static void avr_timer_configure(avr_timer_t * p, uint32_t clock, uint32_t top)
{
	float t = clock / (float)(top+1);
	float frequency = p->io.avr->frequency;

	p->tov_cycles = 0;
	p->tov_top = top;

	p->tov_cycles = frequency / t; // avr_hz_to_cycles(frequency, t);

	AVR_LOG(p->io.avr, LOG_TRACE, "TIMER: %s-%c TOP %.2fHz = %d cycles = %dusec\n",
			__FUNCTION__, p->name, t, (int)p->tov_cycles,
			(int)avr_cycles_to_usec(p->io.avr, p->tov_cycles));

	for (int compi = 0; compi < AVR_TIMER_COMP_COUNT; compi++) {
		if (!p->comp[compi].r_ocr)
			continue;
		uint32_t ocr = _timer_get_ocr(p, compi);
		float fc = clock / (float)(ocr+1);

		p->comp[compi].comp_cycles = 0;
	//	printf("%s-%c clock %d top %d OCR%c %d\n", __FUNCTION__, p->name, clock, top, 'A'+compi, ocr);

		if (ocr && ocr <= top) {
			p->comp[compi].comp_cycles = frequency / fc; // avr_hz_to_cycles(p->io.avr, fa);
			AVR_LOG(p->io.avr, LOG_TRACE, "TIMER: %s-%c %c %.2fHz = %d cycles\n", 
					__FUNCTION__, p->name,
					'A'+compi, fc, (int)p->comp[compi].comp_cycles);
		}
	}

	if (p->tov_cycles > 1) {
		avr_cycle_timer_register(p->io.avr, p->tov_cycles, avr_timer_tov, p);
		// calling it once, with when == 0 tells it to arm the A/B/C timers if needed
		p->tov_base = 0;
		avr_timer_tov(p->io.avr, p->io.avr->cycle, p);
	}
}