Beispiel #1
0
void udd_disable(void)
{
	irqflags_t flags;
	flags = cpu_irq_save();
	udd_detach_device();
	// Disable interface
	USB_CTRLA = 0;
	USB_CTRLB = 0;
	sysclk_disable_usb();
	udd_sleep_mode(false);
#ifndef UDD_NO_SLEEP_MGR
	sleepmgr_unlock_mode(USBC_SLEEP_MODE_USB_SUSPEND);
#endif
	cpu_irq_restore(flags);
}
Beispiel #2
0
/**
 * \internal
 * \brief Disable a maskable module clock.
 * \param bus_id Bus index, given by the \c AVR32_PM_CLK_GRP_xxx definitions.
 * \param module_index Index of the module to be disabled. This is the
 * bit number in the corresponding xxxMASK register.
 */
void sysclk_priv_disable_module(unsigned int bus_id, unsigned int module_index)
{
	irqflags_t flags;
	uint32_t   mask;

	flags = cpu_irq_save();

	/* Disable the clock */
	mask = *(&AVR32_PM.cpumask + bus_id);
	mask &= ~(1U << module_index);
	AVR32_PM.unlock = 0xaa000020 + (4 * bus_id);
	*(&AVR32_PM.cpumask + bus_id) = mask;

	cpu_irq_restore(flags);
}
Beispiel #3
0
// Returns the number of times the timer has ticked (1000 Hz)
uint32_t getSystemTime(void) {
	uint32_t temp;
	irqflags_t irq_state;
	
	// Save and disable interrupts:
	irq_state = cpu_irq_save();

	// Get the system time:
	temp = system_time;
	
	// Restore the state of the interrupts:
	cpu_irq_restore(irq_state);
	
	return temp;
}
Beispiel #4
0
iram_size_t udi_cdc_multi_get_nb_received_data(uint8_t port)
{
	irqflags_t flags;
	uint16_t pos;
	iram_size_t nb_received;

#if UDI_CDC_PORT_NB == 1 // To optimize code
	port = 0;
#endif
	flags = cpu_irq_save();
	pos = udi_cdc_rx_pos[port];
	nb_received = udi_cdc_rx_buf_nb[port][udi_cdc_rx_buf_sel[port]] - pos;
	cpu_irq_restore(flags);
	return nb_received;
}
Beispiel #5
0
/**
 * \brief Get current time
 *
 * \return Current time value
 *
 * \note Due to errate, this can return old values shortly after waking up from
 * sleep.
 */
uint32_t rtc_get_time(void)
{
	irqflags_t flags;
	uint16_t   count_high;
	uint16_t   count_low;

	flags = cpu_irq_save();
	count_high = rtc_data.counter_high;
	count_low = RTC.CNT;
	// Test for possible pending increase of high count value
	if ((count_low == 0) && (RTC.INTFLAGS & RTC_OVFIF_bm))
		count_high++;
	cpu_irq_restore(flags);
	return ((uint32_t)count_high << 16) | count_low;
}
void dfll_enable_open_loop(const struct dfll_config *cfg,
		unsigned int dfll_id)
{
	irqflags_t flags;

	/* First, enable the DFLL, then configure it */
	flags = cpu_irq_save();
	AVR32_SCIF.unlock =
			( AVR32_SCIF_UNLOCK_KEY_VALUE << AVR32_SCIF_UNLOCK_KEY_OFFSET) |
			AVR32_SCIF_DFLL0CONF;
	AVR32_SCIF.dfll0conf = 1U << AVR32_SCIF_DFLL0CONF_EN;
	cpu_irq_restore(flags);
	dfll_write_reg(DFLL0CONF, cfg->conf | (1U << AVR32_SCIF_DFLL0CONF_EN));
	dfll_write_reg(DFLL0SSG, cfg->ssg);
}
Beispiel #7
0
/**
 * \brief Write DMA channel configuration to hardware
 *
 * This function will write the DMA channel configuration, provided by a
 * \ref dma_channel_config.
 *
 * \param num DMA channel number to write configuration to
 * \param config Pointer to a DMA channel config, given by a
 *               \ref dma_channel_config
 */
void dma_channel_write_config(dma_channel_num_t num,
		struct dma_channel_config *config)
{
	DMA_CH_t *channel = dma_get_channel_address_from_num(num);
	irqflags_t iflags = cpu_irq_save();

#ifdef CONFIG_HAVE_HUGEMEM
	channel->DESTADDR0 = (uint32_t)config->destaddr;
	channel->DESTADDR1 = (uint32_t)config->destaddr >> 8;
	channel->DESTADDR2 = (uint32_t)config->destaddr >> 16;
#else
	channel->DESTADDR0 = (uint32_t)config->destaddr16;
	channel->DESTADDR1 = (uint32_t)config->destaddr16 >> 8;
#  if XMEGA_A || XMEGA_AU
	channel->DESTADDR2 = 0;
#  endif
#endif

#ifdef CONFIG_HAVE_HUGEMEM
	channel->SRCADDR0 = (uint32_t)config->srcaddr;
	channel->SRCADDR1 = (uint32_t)config->srcaddr >> 8;
	channel->SRCADDR2 = (uint32_t)config->srcaddr >> 16;
#else
	channel->SRCADDR0 = (uint32_t)config->srcaddr16;
	channel->SRCADDR1 = (uint32_t)config->srcaddr16 >> 8;
#  if XMEGA_A || XMEGA_AU
	channel->SRCADDR2 = 0;
#  endif
#endif

	channel->ADDRCTRL = config->addrctrl;
	channel->TRIGSRC = config->trigsrc;
	channel->TRFCNT = config->trfcnt;
	channel->REPCNT = config->repcnt;

	channel->CTRLB = config->ctrlb;

	/* Make sure the DMA channel is not enabled before dma_channel_enable()
	 * is called.
	 */
#if XMEGA_A || XMEGA_AU
	channel->CTRLA = config->ctrla & ~DMA_CH_ENABLE_bm;
#else
	channel->CTRLA = config->ctrla & ~DMA_CH_CHEN_bm;
#endif

	cpu_irq_restore(iflags);
}
Beispiel #8
0
/**
 * Disable the UART and DMA
 */
static void disableUsartAndDma(void) {
    irqflags_t irq;

    irq = cpu_irq_save();
    USART_DA2S.idr = ~(uint32_t) 0;
    DMA_USART_DA2S_TX.idr = ~(uint32_t) 0;
    DMA_USART_DA2S_RX.idr = ~(uint32_t) 0;
    cpu_irq_restore(irq);
    DMA_USART_DA2S_TX.cr = AVR32_PDCA_CR_ECLR_MASK | AVR32_PDCA_CR_TDIS_MASK;
    DMA_USART_DA2S_RX.cr = AVR32_PDCA_CR_ECLR_MASK | AVR32_PDCA_CR_TDIS_MASK;
    DMA_USART_DA2S_TX.tcrr = 0;
    DMA_USART_DA2S_RX.tcrr = 0;
    DMA_USART_DA2S_TX.tcr = 0;
    DMA_USART_DA2S_RX.tcr = 0;
    USART_DA2S.cr = AVR32_USART_CR_RSTTX | AVR32_USART_CR_RSTRX;
}
Beispiel #9
0
void pdca_load_channel(uint8_t pdca_ch_number, volatile void *addr,
		uint32_t size)
{
	/* get the correct channel pointer */
	volatile avr32_pdca_channel_t *pdca_channel = pdca_get_handler(
			pdca_ch_number);

	irqflags_t flags = cpu_irq_save();

	pdca_channel->mar = (uint32_t)addr;
	pdca_channel->tcr = size;
	pdca_channel->cr = AVR32_PDCA_ECLR_MASK;
	pdca_channel->isr;

	cpu_irq_restore(flags);
}
Beispiel #10
0
static void udd_ctrl_send_zlp_in(void)
{
	irqflags_t flags;

	udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_IN_ZLP;

	// Validate and send empty IN packet on control endpoint
	flags = cpu_irq_save();
	// Send ZLP on IN endpoint
	udd_ack_in_send(0);
	udd_enable_in_send_interrupt(0);
	// To detect a protocol error, enable nak interrupt on data OUT phase
	udd_ack_nak_out(0);
	udd_enable_nak_out_interrupt(0);
	cpu_irq_restore(flags);
}
Beispiel #11
0
/**
 * \brief Enable a module clock derived from the PBB clock
 * \param index Index of the module clock in the PBBMASK register
 */
void sysclk_enable_pbb_module(unsigned int index)
{
	irqflags_t flags;

	/* Enable the bridge if necessary */
	flags = cpu_irq_save();

	if (!sysclk_pbb_refcount)
		sysclk_enable_hsb_module(SYSCLK_PBB_BRIDGE);
	sysclk_pbb_refcount++;

	cpu_irq_restore(flags);

	/* Enable the module */
	sysclk_priv_enable_module(AVR32_PM_CLK_GRP_PBB, index);
}
Beispiel #12
0
/**
 * \brief Disable a module clock derived from the PBB clock
 * \param module_index Index of the module clock in the PBBMASK register
 */
void sysclk_disable_pbb_module(uint32_t module_index)
{
	irqflags_t flags;

	/* Disable the module */
	sysclk_priv_disable_module(PM_CLK_GRP_PBB, module_index);

	/* Disable the bridge if possible */
	flags = cpu_irq_save();

	if (PM->PM_PBBMASK == 0) {
		sysclk_disable_hsb_module(SYSCLK_PBB_BRIDGE);
	}

	cpu_irq_restore(flags);
}
Beispiel #13
0
/**
 * \internal
 * \brief Disable a maskable module clock.
 * \param bus_id Bus index, given by the \c PM_CLK_GRP_xxx definitions.
 * \param module_index Index of the module to be disabled. This is the
 * bit number in the corresponding xxxMASK register.
 */
void sysclk_priv_disable_module(uint32_t bus_id, uint32_t module_index)
{
	irqflags_t flags;
	uint32_t   mask;

	flags = cpu_irq_save();

	/* Disable the clock */
	mask = *(&PM->PM_CPUMASK + bus_id);
	mask &= ~(1U << module_index);
	PM->PM_UNLOCK = PM_UNLOCK_KEY(0xAAu) |
		BPM_UNLOCK_ADDR(((uint32_t)&PM->PM_CPUMASK - (uint32_t)PM) + (4 * bus_id));
	*(&PM->PM_CPUMASK + bus_id) = mask;

	cpu_irq_restore(flags);
}
Beispiel #14
0
static void udi_cdc_ctrl_state_change(bool b_set, le16_t bit_mask)
{
	irqflags_t flags;

	// Update state
	flags = cpu_irq_save(); // Protect udi_cdc_state
	if (b_set) {
		udi_cdc_state |= bit_mask;
	} else {
		udi_cdc_state &= ~bit_mask;
	}
	cpu_irq_restore(flags);

	// Send it if possible and state changed
	udi_cdc_ctrl_state_notify();
}
Beispiel #15
0
void osc_priv_enable_osc32(void)
{
	irqflags_t flags;

	flags = cpu_irq_save();
	BSCIF->BSCIF_UNLOCK = BSCIF_UNLOCK_KEY(0xAAu)
		| BSCIF_UNLOCK_ADDR((uint32_t)&BSCIF->BSCIF_OSCCTRL32 - (uint32_t)BSCIF);
	BSCIF->BSCIF_OSCCTRL32 =
			OSC32_STARTUP_VALUE
			| BOARD_OSC32_SELCURR
			| OSC32_MODE_VALUE
			| BSCIF_OSCCTRL32_EN1K
			| BSCIF_OSCCTRL32_EN32K
			| BSCIF_OSCCTRL32_OSC32EN;
	cpu_irq_restore(flags);
}
Beispiel #16
0
void osc_priv_disable_rcfast(void)
{
	irqflags_t flags;
	uint32_t temp;
	flags = cpu_irq_save();
	// Let FCD and calibration value by default
	temp = SCIF->SCIF_RCFASTCFG;
	// Clear previous FRANGE value
	temp &= ~SCIF_RCFASTCFG_FRANGE_Msk;
	// Disalbe RCFAST
	temp &= ~SCIF_RCFASTCFG_EN;
	SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)
		| SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_RCFASTCFG - (uint32_t)SCIF);
	SCIF->SCIF_RCFASTCFG = temp;
	cpu_irq_restore(flags);
}
Beispiel #17
0
void osc_priv_enable_osc0(void)
{
	irqflags_t flags;

	flags = cpu_irq_save();
	SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAu)
		| SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_OSCCTRL0 - (uint32_t)SCIF);
	SCIF->SCIF_OSCCTRL0 =
			OSC0_STARTUP_VALUE
# if BOARD_OSC0_IS_XTAL == true
			| OSC0_GAIN_VALUE
#endif
			| OSC0_MODE_VALUE
			| SCIF_OSCCTRL0_OSCEN;
	cpu_irq_restore(flags);
}
Beispiel #18
0
/**
 * \brief Enable a module clock derived from the PBA clock
 * \param module_index Index of the module clock in the PBAMASK register
 */
void sysclk_enable_pba_module(uint32_t module_index)
{
	irqflags_t flags;

	/* Enable the bridge if necessary */
	flags = cpu_irq_save();

	if (PM->PM_PBAMASK == 0) {
		sysclk_enable_hsb_module(SYSCLK_PBA_BRIDGE);
	}

	cpu_irq_restore(flags);

	/* Enable the module */
	sysclk_priv_enable_module(PM_CLK_GRP_PBA, module_index);
}
Beispiel #19
0
/**
 * \internal
 *
 * \brief Get exclusive access to global TWI resources.
 *
 * Wait to acquire bus hardware interface and ISR variables.
 *
 * \param no_wait  Set \c true to return instead of doing busy-wait (spin-lock).
 *
 * \return STATUS_OK if the bus is acquired, else ERR_BUSY.
 */
static inline status_code_t twim_acquire(bool no_wait)
{
	while (transfer.locked) {

		if (no_wait) { return ERR_BUSY; }
	}

	irqflags_t const flags = cpu_irq_save ();

	transfer.locked = true;
	transfer.status = OPERATION_IN_PROGRESS;

	cpu_irq_restore (flags);

	return STATUS_OK;
}
Beispiel #20
0
/**
 * \brief Disable a module clock derived from the PBB clock
 * \param index Index of the module clock in the PBBMASK register
 */
void sysclk_disable_pbb_module(unsigned int index)
{
	irqflags_t flags;

	/* Disable the module */
	sysclk_priv_disable_module(AVR32_PM_CLK_GRP_PBB, index);

	/* Disable the bridge if possible */
	flags = cpu_irq_save();

	sysclk_pbb_refcount--;
	if (!sysclk_pbb_refcount)
		sysclk_disable_hsb_module(SYSCLK_PBB_BRIDGE);

	cpu_irq_restore(flags);
}
iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t size)
{
	irqflags_t flags;
	uint8_t buf_sel;
	uint16_t buf_nb;
	iram_size_t copy_nb;
	uint8_t *ptr_buf = (uint8_t *)buf;

#if UDI_CDC_PORT_NB == 1 // To optimize code
	port = 0;
#endif

	if (9 == udi_cdc_line_coding[port].bDataBits) {
		size *=2;
	}

udi_cdc_write_buf_loop_wait:
	// Check available space
	if (!udi_cdc_multi_is_tx_ready(port)) {
		if (!udi_cdc_data_running) {
			return size;
		}
		goto udi_cdc_write_buf_loop_wait;
	}

	// Write values
	flags = cpu_irq_save();
	buf_sel = udi_cdc_tx_buf_sel[port];
	buf_nb = udi_cdc_tx_buf_nb[port][buf_sel];
	copy_nb = UDI_CDC_TX_BUFFERS - buf_nb;
	if (copy_nb > size) {
		copy_nb = size;
	}
	memcpy(&udi_cdc_tx_buf[port][buf_sel][buf_nb], ptr_buf, copy_nb);
	udi_cdc_tx_buf_nb[port][buf_sel] = buf_nb + copy_nb;
	cpu_irq_restore(flags);

	// Update buffer pointer
	ptr_buf = ptr_buf + copy_nb;
	size -= copy_nb;

	if (size) {
		goto udi_cdc_write_buf_loop_wait;
	}

	return 0;
}
Beispiel #22
0
/**
 * \brief Initialize the twi master module
 *
 * \param twim              Base address of the TWIM (i.e. &AVR32_TWIM)
 * \param *opt              Options for initializing the twim module
 *                          (see \ref twim_options_t)
 * \retval STATUS_OK        Transaction is successful
 * \retval ERR_INVALID_ARG  Invalid arg resulting in wrong CWGR Exponential
 * \retval ERR_IO_ERROR     NACK is received or Bus Arbitration lost
 */
status_code_t twim_master_init (volatile avr32_twim_t *twim,
		const twim_options_t *opt)
{
	bool global_interrupt_enabled = cpu_irq_is_enabled ();
	// Initialize bus transfer status
	transfer_status = TWI_SUCCESS;
	// Disable TWI interrupts
	if (global_interrupt_enabled) {
		cpu_irq_disable ();
	}
	twim->idr = ~0UL;
	// Enable master transfer
	twim->cr = AVR32_TWIM_CR_MEN_MASK;
	// Reset TWI
	twim->cr = AVR32_TWIM_CR_SWRST_MASK;
	if (global_interrupt_enabled) {
		cpu_irq_enable ();
	}
	// Clear SR
	twim->scr = ~0UL;

	// register Register twim_master_interrupt_handler interrupt on level CONF_TWIM_IRQ_LEVEL
	irqflags_t flags = cpu_irq_save();
	irq_register_handler(twim_master_interrupt_handler,
			CONF_TWIM_IRQ_LINE, CONF_TWIM_IRQ_LEVEL);
	cpu_irq_restore(flags);
/*
	if (opt->smbus) {
		// Enable SMBUS Transfer
		twim->cr = AVR32_TWIM_CR_SMEN_MASK;
		twim->smbtr = (uint32_t) -1;
	}
*/
	// Select the speed
	if (twim_set_speed (twim, opt->speed, opt->pba_hz) ==
			ERR_INVALID_ARG) {
		return ERR_INVALID_ARG;
	}
	// Probe the component
	twim_probe (twim, opt->chip);
	//Check for nack and abitration
	if (transfer_status == TWI_RECEIVE_NACK
			|| transfer_status == TWI_ARBITRATION_LOST) {
		return ERR_IO_ERROR;
	}
	return STATUS_OK;
}
Beispiel #23
0
/**
 * \brief Test and clear expired flag for running timeout
 *
 * \param id      \ref timeout_id_t
 * \retval true   Timer have expired; clearing expired flag
 * \retval false  Timer still running
 */
bool timeout_test_and_clear_expired(timeout_id_t id)
{
	/* Check that ID within the TIMEOUT_COUNT range */
	if (id < TIMEOUT_COUNT) {
		irqflags_t flags;

		/* Check if timeout has expired */
		if (timeout_expired & (1 << id)) {
			flags = cpu_irq_save();
			timeout_expired &= ~(1 << id);
			cpu_irq_restore(flags);
			return true;
		}
	}

	return false;
}
Beispiel #24
0
void dfll_enable_open_loop(const struct dfll_config *cfg, uint32_t dfll_id)
{
	irqflags_t flags;

	UNUSED(dfll_id);

	/* First, enable the DFLL, then configure it */
	flags = cpu_irq_save();
	SCIF->SCIF_UNLOCK = SCIF_UNLOCK_KEY(0xAAUL)
		| SCIF_UNLOCK_ADDR((uint32_t)&SCIF->SCIF_DFLL0CONF - (uint32_t)SCIF);
	SCIF->SCIF_DFLL0CONF = SCIF_DFLL0CONF_EN;
	cpu_irq_restore(flags);
	dfll_write_reg(DFLL0CONF, cfg->conf | SCIF_DFLL0CONF_EN);
	dfll_write_reg(DFLL0MUL, cfg->mul);
	dfll_write_reg(DFLL0VAL, cfg->val);
	dfll_write_reg(DFLL0SSG, cfg->ssg);
}
void udd_test_mode_packet(void)
{
	uint8_t i;
	uint8_t *ptr_dest;
	const uint8_t *ptr_src;
	irqflags_t flags;

	const uint8_t test_packet[] = {
		// 00000000 * 9
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		// 01010101 * 8
		0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
		// 01110111 * 8
		0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
		// 0, {111111S * 15}, 111111
		0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
				0xFF, 0xFF,
		// S, 111111S, {0111111S * 7}
		0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD,
		// 00111111, {S0111111 * 9}, S0
		0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E
	};

	// Reconfigure control endpoint to bulk IN endpoint
	udd_disable_endpoint(0);
	udd_configure_endpoint(0, USB_EP_TYPE_BULK, 1,
			64, AVR32_USBB_UECFG0_EPBK_SINGLE);
	udd_allocate_memory(0);
	udd_enable_endpoint(0);

	udd_enable_hs_test_mode();
	udd_enable_hs_test_mode_packet();

	// Send packet on endpoint 0
	ptr_dest = (uint8_t *) & udd_get_endpoint_fifo_access(0, 8);
	ptr_src = test_packet;

	for (i = 0; i < sizeof(test_packet); i++) {
		*ptr_dest++ = *ptr_src++;
	}
	flags = cpu_irq_save();
	udd_enable_in_send_interrupt(0);
	cpu_irq_restore(flags);

	udd_ack_in_send(0);
}
Beispiel #26
0
/**
 * \brief Read configuration from ADC module
 *
 * Reads out the current configuration of the ADC module to the specified
 * buffer.
 *
 * \param adc Pointer to ADC module.
 * \param conf Pointer to ADC module configuration.
 */
void adc_read_configuration(ADC_t *adc, struct adc_config *conf)
{
	irqflags_t flags = cpu_irq_save();

	adc_enable_clock(adc);

	conf->cmp = adc->CMP;
	conf->refctrl = adc->REFCTRL;
	conf->prescaler = adc->PRESCALER;
	conf->evctrl = adc->EVCTRL;
	conf->ctrlb = adc->CTRLB;
	conf->sampctrl = adc->SAMPCTRL;

	adc_disable_clock(adc);

	cpu_irq_restore(flags);
}
Beispiel #27
0
void uhd_disable(bool b_id_stop)
{
	UNUSED(b_id_stop);

	irqflags_t flags;

	flags = cpu_irq_save();
	ohci_deinit();
	cpu_irq_restore(flags);

	/* Do not authorize asynchronous USB interrupts. */
//	pmc_clr_fast_startup_input(PMC_FSMR_USBAL);
	sysclk_disable_usb();
	pmc_disable_periph_clk(ID_UHP);
	uhd_sleep_mode(UHD_STATE_OFF);

}
Beispiel #28
0
/**
 * \brief Read analog comparator configuration from hardware
 *
 * This function will read the hardware configuration and put it into the \a
 * config argument.
 *
 * \param ac Pointer to the analog comparator (AC) base address
 * \param channel Number of analog comparator (AC) channel
 * \param config Pointer to a \ref ac_config variable
 */
void ac_read_config(AC_t *ac, uint8_t channel, struct ac_config *config)
{
	irqflags_t iflags = cpu_irq_save();

	if (channel == 0) {
		config->acmuxctrl   = ac->AC0MUXCTRL;
		config->acctrl      = ac->AC0CTRL;
	} else {
		config->acmuxctrl   = ac->AC1MUXCTRL;
		config->acctrl      = ac->AC1CTRL;
	}

	config->winctrl = ac->WINCTRL;
	config->ctrlb   = ac->CTRLB;

	cpu_irq_restore(iflags);
}
/**
 * \brief Configure new alarm on TC.
 * \internal
 *
 * Sets a new compare value for compare channel A and enables its interrupt.
 *
 * \param tc_id ID of the TC.
 * \param timer Pointer to timer struct.
 * \param delay Delay for timer alarm.
 */
void tc_timer_set_alarm(uint8_t tc_id, struct timer *timer, uint16_t delay)
{
	irqflags_t flags;
	bool enabled;
	uint16_t start;

	assert(timer);
	assert(timer->regs);

	// Disable any current alarms.
	tc_write_reg8(timer->regs, INTCTRLB, TC_BF(INTCTRLB_CCAINTLVL,
			PMIC_INTLVL_OFF));

	// TC must be stopped to be sure to avoid "overshoots" of delays.
	enabled = tc_pclk_is_enabled(tc_id);
	if (!enabled)
		tc_enable_pclk(tc_id);
	else
		tc_write_reg8(timer->regs, CTRLA, TC_CLKSEL_OFF);

	// Disable interrupts to prevent corruption of 16-bit read and writes.
	flags = cpu_irq_save();

	tc_write_reg8(timer->regs, INTFLAGS, TC_BIT(INTFLAGS_CCAIF));

	/* TC must be reset and started with \ref tc_timer_start() if disabled.
	 * Set compare value accordingly.
	 */
	if (!enabled)
		tc_write_reg16(timer->regs, CCA, delay);
	else {
		start = tc_read_reg16(timer->regs, CNT);
		tc_write_reg16(timer->regs, CCA, start + delay);
	}

	cpu_irq_restore(flags);

	tc_write_reg8(timer->regs, INTCTRLB, TC_BF(INTCTRLB_CCAINTLVL,
			timer->intlvl));

	// Leave the TC in the state it was upon entry of this function.
	if (!enabled)
		tc_disable_pclk(tc_id);
	else
		tc_write_reg8(timer->regs, CTRLA, timer->clksel);
}
Beispiel #30
0
/**
 * \brief Write configuration to ADC channel
 *
 * Writes the specified configuration to the ADC channel.
 *
 * \param adc Pointer to ADC module.
 * \param ch_mask Mask of ADC channel(s):
 * \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel
 * can be given in mask)
 * \param ch_conf Pointer to ADC channel configuration.
 *
 * \note The specified ADC's callback function must be set before this function
 * is called if callbacks are enabled and interrupts are enabled in the
 * channel configuration.
 */
void adcch_write_configuration(ADC_t *adc, uint8_t ch_mask,
		const struct adc_channel_config *ch_conf)
{
	ADC_CH_tmpfix_t *adc_ch;
	irqflags_t flags;

	adc_ch = adc_get_channel(adc, ch_mask);

	flags = cpu_irq_save();

#if defined(CONFIG_ADC_CALLBACK_ENABLE) && defined(_ASSERT_ENABLE_)
	if ((adc_ch->INTCTRL & ADC_CH_INTLVL_gm) != ADC_CH_INTLVL_OFF_gc) {
#  ifdef ADCA
		if ((uintptr_t)adc == (uintptr_t)&ADCA) {
			Assert(adca_callback);
		} else
#  endif

#  ifdef ADCB
		if ((uintptr_t)adc == (uintptr_t)&ADCB) {
			Assert(adcb_callback);
		} else
#  endif

		{
			Assert(0);
			return;
		}
	}
#endif

	adc_enable_clock(adc);
	adc_ch->CTRL = ch_conf->ctrl;
	adc_ch->INTCTRL = ch_conf->intctrl;
	adc_ch->MUXCTRL = ch_conf->muxctrl;
#if CONFIG_ADC_VERSION == 2
	if (ch_mask & ADC_CH0) {
		/* USB devices has channel scan available on ADC channel 0 */
		adc_ch->SCAN = ch_conf->scan;
	}
#endif
	adc_disable_clock(adc);

	cpu_irq_restore(flags);
}