Exemplo n.º 1
0
Arquivo: events.c Projeto: Gussy/sam0
enum status_code events_allocate(
		struct events_resource *resource,
		struct events_config *config)
{
	uint8_t new_channel;

	Assert(resource);

	new_channel = _events_find_first_free_channel_and_allocate();

	if(new_channel == EVENTS_INVALID_CHANNEL) {
		return STATUS_ERR_NOT_FOUND;
	}

	resource->channel = new_channel;

	if (config->path != EVENTS_PATH_ASYNCHRONOUS) {
		/* Set up a GLCK channel to use with the specific channel */
		struct system_gclk_chan_config gclk_chan_conf;

		system_gclk_chan_get_config_defaults(&gclk_chan_conf);
		gclk_chan_conf.source_generator =
				(enum gclk_generator)config->clock_source;
		system_gclk_chan_set_config(EVSYS_GCLK_ID_0 + new_channel, &gclk_chan_conf);
		system_gclk_chan_enable(EVSYS_GCLK_ID_0 + new_channel);
	}

	/* Save channel setting and configure it after user multiplexer */
	resource->channel_reg = EVSYS_CHANNEL_EVGEN(config->generator)           |
			EVSYS_CHANNEL_PATH(config->path)                                 |
			((uint32_t)config->run_in_standby << EVSYS_CHANNEL_RUNSTDBY_Pos) |
			((uint32_t)config->on_demand << EVSYS_CHANNEL_ONDEMAND_Pos) |
			EVSYS_CHANNEL_EDGSEL(config->edge_detect);

	return STATUS_OK;
}
Exemplo n.º 2
0
Arquivo: cal.c Projeto: gmarsh/thin18
void cal_init(void) {
	
	// CONFIGURE EIC
	
	// configure PA21 (INT from RTC, EXTINT5) input as EIC interrupt
	PORT->Group[0].PMUX[21/2].bit.PMUXO = PORT_PMUX_PMUXO_A_Val;
	PORT->Group[0].PINCFG[21].bit.PMUXEN = 1;
	
	// enable EIC clock
	PM->APBAMASK.reg |= PM_APBAMASK_EIC;
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(EIC_GCLK_ID) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);
	
	// configure EXTINT5 to pass through EXTINT5 without any filtering/retiming
	EIC->CONFIG[0].bit.FILTEN5 = 0;
	EIC->CONFIG[0].bit.SENSE5 = EIC_CONFIG_SENSE5_HIGH_Val;
	// enable event for this interrupt
	EIC->EVCTRL.bit.EXTINTEO5 = 1;

	// enable EIC!
	EIC->CTRL.reg = EIC_CTRL_ENABLE;
	
	
	// CONFIGURE EVENT SYSTEM
	
	// enable event system clock
	PM->APBCMASK.reg |= PM_APBCMASK_EVSYS;
	
	// enable event channel 0 CLK
	// use GCLK generator 0 for now, we'll change this to GCLK1 later
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_EVSYS_CHANNEL_0;
	
	// event generator 0x11 is EXTINT5 and is a copy of what's on the IO pin.
	// resynchronize to the local GCLK and detect a falling edge.
	EVSYS->CHANNEL.reg =	EVSYS_CHANNEL_EDGSEL_FALLING_EDGE |
							EVSYS_CHANNEL_PATH_RESYNCHRONIZED |
							EVSYS_CHANNEL_EVGEN(0x11) |
							EVSYS_CHANNEL_CHANNEL(0);
	
	// event user 0x02 is TC2
	// note that EVSYS_USER_CHANNEL(1) actually configures channel 0!
	EVSYS->USER.reg = EVSYS_USER_CHANNEL(1) | EVSYS_USER_USER(0x02);
	
	
	// CONFIGURE TC2
	
	// Use GCLK0 to clock timer while we configure it, we'll change it to GCLK1 later
	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TC2_TC3;
	// enable APB clock (also enable TC3 clock, though it's probably not needed)
	PM->APBCMASK.reg |= PM_APBCMASK_TC2 | PM_APBCMASK_TC3;
	
	// 32 bit mode, top=CC0
	TC2->COUNT32.CTRLA.reg = TC_CTRLA_RUNSTDBY | TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_WAVEGEN_MFRQ | TC_CTRLA_MODE_COUNT32 | (0<<TC_CTRLA_ENABLE_Pos);
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// overflow every 16M samples, this makes subtracting time easy.
	TC2->COUNT32.CC[0].reg = CAPTURE_VALUE_MASK;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// zero counter
	TC2->COUNT32.COUNT.reg = 0;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// clear ONESHOT and DIR bits, so we count upwards and repeat
	TC2->COUNT32.CTRLBCLR.reg = TC_CTRLBCLR_ONESHOT | TC_CTRLBCLR_DIR;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// enable capture channel 1
	TC2->COUNT32.CTRLC.reg = TC_CTRLC_CPTEN1;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// enable event input
	TC2->COUNT32.EVCTRL.reg = TC_EVCTRL_TCEI | TC_EVCTRL_EVACT_OFF;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// clear any pending interrupt flags
	TC2->COUNT32.INTFLAG.reg = TC_INTFLAG_MC1 | TC_INTFLAG_OVF | TC_INTFLAG_SYNCRDY;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// and fire away!
	TC2->COUNT32.CTRLA.bit.ENABLE = 1;
	while(TC2->COUNT32.STATUS.bit.SYNCBUSY);
	
	// now switch GCLKs for event and timer to GCLK1
	//GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TC2_TC3;
	//GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_EVSYS_CHANNEL_0;
	
	
}