static void udd_ctrl_send_zlp_out(void) { irqflags_t flags; udd_ep_control_state = UDD_EPCTRL_HANDSHAKE_WAIT_OUT_ZLP; // No action is necessary to accept OUT ZLP // because the buffer of control endpoint is already free // To detect a protocol error, enable NAK interrupt on data IN phase flags = cpu_irq_save(); udd_ack_nak_in(0); udd_enable_nak_in_interrupt(0); cpu_irq_restore(flags); }
void udd_disable(void) { irqflags_t flags; flags = cpu_irq_save(); // Disable USB pad otg_disable(); otg_disable_pad(); 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); }
iram_size_t uhi_cdc_write_buf(uint8_t port, const void* buf, iram_size_t size) { irqflags_t flags; uhi_cdc_port_t *ptr_port; uhi_cdc_line_t *line; uhi_cdc_buf_t *cdc_buf; iram_size_t copy_nb; // Select port ptr_port = uhi_cdc_get_port(port); if (ptr_port == NULL) { return false; } line = &ptr_port->line_tx; if (9 == ptr_port->conf.bDataBits) { size *=2; } uhi_cdc_write_buf_loop_wait: // Check available space cdc_buf = &line->buffer[line->buf_sel]; while (line->buffer_size == cdc_buf->nb) { if (NULL == uhi_cdc_get_port(port)) { return 0; } goto uhi_cdc_write_buf_loop_wait; } // Write value flags = cpu_irq_save(); cdc_buf = &line->buffer[line->buf_sel]; copy_nb = line->buffer_size - cdc_buf->nb; if (copy_nb>size) { copy_nb = size; } memcpy(&cdc_buf->ptr[cdc_buf->nb], buf, copy_nb); cdc_buf->nb += copy_nb; cpu_irq_restore(flags); // Update buffer pointer buf = (uint8_t*)buf + copy_nb; size -= copy_nb; if (size) { goto uhi_cdc_write_buf_loop_wait; } return 0; }
void udd_enable(void) { irqflags_t flags; flags = cpu_irq_save(); #if SAMG55 matrix_set_usb_device(); #endif // Enable USB hardware udd_enable_periph_ck(); sysclk_enable_usb(); // Cortex, uses NVIC, no need to register IRQ handler NVIC_SetPriority((IRQn_Type) ID_UDP, UDD_USB_INT_LEVEL); NVIC_EnableIRQ((IRQn_Type) ID_UDP); // Reset internal variables #if (0!=USB_DEVICE_MAX_EP) udd_ep_job_table_reset(); #endif // Always authorize asynchronous USB interrupts to exit of sleep mode pmc_set_fast_startup_input(PMC_FSMR_USBAL); #ifndef UDD_NO_SLEEP_MGR // Initialize the sleep mode authorized for the USB suspend mode udd_b_idle = false; sleepmgr_lock_mode(UDP_SLEEP_MODE_USB_SUSPEND); #endif #if UDD_VBUS_IO /* Initialize VBus monitor */ udd_vbus_init(udd_vbus_handler); udd_vbus_monitor_sleep_mode(true); /* Force Vbus interrupt when Vbus is always high * This is possible due to a short timing between a Host mode stop/start. */ if (Is_udd_vbus_high()) { udd_vbus_handler(USB_VBUS_PIO_ID, USB_VBUS_PIO_MASK); } #else # ifndef USB_DEVICE_ATTACH_AUTO_DISABLE udd_attach(); # endif #endif cpu_irq_restore(flags); }
// 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; }
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; }
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); }
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); }
/** * Record a trace event * @param event * @param data */ void hf_trace(uint8_t event, uint8_t data) { irqflags_t irq; irq = cpu_irq_save(); t_head->event = event; t_head->data = data; /* in 250nsec increments */ t_head->time = tc_read_count(&TCC0); if (++t_head >= &trace_records[TRACE_RECORDS]) t_head = trace_records; /* marker */ t_head->event = 255; cpu_irq_restore(irq); }
static void udd_reset_ep_ctrl(void) { irqflags_t flags; // Reset USB address to 0 udd_enable_address(); udd_configure_address(0); // Alloc and configure control endpoint in OUT direction udd_configure_endpoint(0, USB_EP_TYPE_CONTROL, 0); udd_enable_endpoint(0); flags = cpu_irq_save(); udd_enable_endpoint_interrupt(0); cpu_irq_restore(flags); }
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); }
void osc_priv_enable_osc32(void) { irqflags_t flags; flags = cpu_irq_save(); AVR32_SCIF.unlock = 0xaa000000 | AVR32_SCIF_OSCCTRL32; AVR32_SCIF.oscctrl32 = (OSC32_STARTUP_VALUE << AVR32_SCIF_OSCCTRL32_STARTUP) | (OSC32_MODE_VALUE << AVR32_SCIF_OSCCTRL32_MODE) | (1U << AVR32_SCIF_OSCCTRL32_EN32K) | (1U << AVR32_SCIF_OSCCTRL32_EN1K) | (BOARD_OSC32_PINSEL << AVR32_SCIF_OSCCTRL32_PINSEL) | (1U << AVR32_SCIF_OSCCTRL32_OSC32EN); cpu_irq_restore(flags); }
/** * \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); }
/** * \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; }
static bool udi_cdc_rx_start(uint8_t port) { irqflags_t flags; uint8_t buf_sel_trans; udd_ep_id_t ep; #if UDI_CDC_PORT_NB == 1 // To optimize code port = 0; #endif flags = cpu_irq_save(); buf_sel_trans = udi_cdc_rx_buf_sel[port]; if (udi_cdc_rx_trans_ongoing[port] || (udi_cdc_rx_pos[port] < udi_cdc_rx_buf_nb[port][buf_sel_trans])) { // Transfer already on-going or current buffer no empty cpu_irq_restore(flags); return false; } // Change current buffer udi_cdc_rx_pos[port] = 0; udi_cdc_rx_buf_sel[port] = (buf_sel_trans==0)?1:0; // Start transfer on RX udi_cdc_rx_trans_ongoing[port] = true; cpu_irq_restore(flags); if (udi_cdc_multi_is_rx_ready(port)) { UDI_CDC_RX_NOTIFY(port); } // Send the buffer with enable of short packet switch (port) { #define UDI_CDC_PORT_TO_DATA_EP_OUT(index, unused) \ case index: \ ep = UDI_CDC_DATA_EP_OUT_##index; \ break; MREPEAT(UDI_CDC_PORT_NB, UDI_CDC_PORT_TO_DATA_EP_OUT, ~) #undef UDI_CDC_PORT_TO_DATA_EP_OUT default: ep = UDI_CDC_DATA_EP_OUT_0; break; } return udd_ep_run(ep, true, udi_cdc_rx_buf[port][buf_sel_trans], UDI_CDC_RX_BUFFERS, udi_cdc_data_received); }
/** * \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); }
bool uhd_ep_run(usb_add_t add, usb_ep_t endp, bool b_shortpacket, uint8_t *buf, iram_size_t buf_size, uint16_t timeout, uhd_callback_trans_t callback) { UNUSED(b_shortpacket); UNUSED(timeout); uint32_t i; bool return_value = true; /* Check if there is free callback resource. */ for (i = 0; i < 8; i++) { if (!callback_trans_end_para[i].flag) { memset((void *)&callback_trans_end_para[i], 0, sizeof(callback_trans_end_para[i])); break; } } if (i == 8) { return false; } irqflags_t flags; flags = cpu_irq_save(); return_value = ohci_add_td_non_control(endp, buf, buf_size, &callback_trans_end_para[i].td_general_header); if (return_value == false) { cpu_irq_restore(flags); return false; } callback_trans_end_para[i].add = add; callback_trans_end_para[i].ep = endp; callback_trans_end_para[i].status = UHD_TRANS_NOERROR; callback_trans_end_para[i].nb_transfered = (iram_size_t)buf; callback_trans_end_para[i].callback_trans_end_func = callback; callback_trans_end_para[i].flag = 1; cpu_irq_restore(flags); return true; }
/** * \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; }
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); }
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(); }
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); }
/** * \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); }
/** * \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); }
/** * \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); }
/** * \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); }
/** * \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); }
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); }
/** * 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; }
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); }
/** * \brief Check of there is ADCB data ready to be read * * When data is ready to be read this function will return true, and assume * that the data is going to be read so it sets the ready flag to false. * * \retval true if the ADCB value is ready to be read * \retval false if data is not ready yet */ bool adcb_data_is_ready(void) { irqflags_t irqflags; /* We will need to save and turn of global interrupts to make sure that we read the latest adcb value and not the next one if a conversation finish before one have time read the data. */ irqflags = cpu_irq_save(); if (adc_sensor_data_ready_ch0) { adc_sensor_data_ready_ch0 = false; cpu_irq_restore(irqflags); return true; } else { cpu_irq_restore(irqflags); return false; } }