static int stm32_cap_setisr(FAR struct stm32_cap_dev_s *dev, xcpt_t handler, void *arg) { const struct stm32_cap_priv_s *priv = (const struct stm32_cap_priv_s *)dev; int irq; #ifdef USE_ADVENCED_TIM int irq_of; #endif DEBUGASSERT(dev != NULL); irq = priv->irq; #ifdef USE_ADVENCED_TIM irq_of = priv->irq_of; #endif /* Disable interrupt when callback is removed */ if (!handler) { up_disable_irq(irq); irq_detach(irq); #ifdef USE_ADVENCED_TIM if (priv->irq_of) { up_disable_irq(irq_of); irq_detach(irq_of); } #endif return OK; } /* Otherwise set callback and enable interrupt */ irq_attach(irq, handler, arg); up_enable_irq(irq); #ifdef USE_ADVENCED_TIM if (priv->irq_of) { irq_attach(priv->irq_of, handler, arg); up_enable_irq(priv->irq_of); } #endif #ifdef CONFIG_ARCH_IRQPRIO /* Set the interrupt priority */ up_prioritize_irq(irq, NVIC_SYSH_PRIORITY_DEFAULT); # ifdef USE_ADVENCED_TIM if (priv->irq_of) { up_prioritize_irq(irq_of, NVIC_SYSH_PRIORITY_DEFAULT); } # endif #endif return OK; }
static void z8_detach(FAR struct uart_dev_s *dev) { struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; up_disable_irq(priv->rxirq); up_disable_irq(priv->txirq); irq_detach(priv->rxirq); irq_detach(priv->txirq); }
static void usart0_detach(struct uart_dev_s *dev) { /* Disable all USART0 interrupts */ usart0_disableusartint(NULL); /* Detach the USART0 IRQs */ (void)irq_detach(ATMEGA_IRQ_U0RX); (void)irq_detach(ATMEGA_IRQ_U0DRE); // (void)irq_detach(ATMEGA_IRQ_U0TX); }
static void usart1_detach(struct uart_dev_s *dev) { /* Disable USART1 interrupts */ usart1_disableusartint(NULL); /* Detach USART1 interrupts */ (void)irq_detach(AT90USB_IRQ_U1RX); (void)irq_detach(AT90USB_IRQ_U1DRE); // (void)irq_detach(AT90USB_IRQ_U1TX); }
static void up_detach(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; #if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) up_disable_irq(priv->rxirq); up_disable_irq(priv->txirq); irq_detach(priv->rxirq); irq_detach(priv->txirq); #else up_disable_irq(priv->irq); irq_detach(priv->irq); #endif }
/** * Uninitialise an I2C device */ int up_i2cuninitialize(struct i2c_dev_s *dev) { irqstate_t flags; i2cvdbg("Deinit I2C port\n"); flags = irqsave(); if (!refcount) goto out; if (--refcount) goto out; tsb_release_pinshare(TSB_PIN_GPIO21 | TSB_PIN_GPIO22); /* Detach Interrupt Handler */ irq_detach(TSB_IRQ_I2C); wd_delete(g_timeout); out: irqrestore(flags); return 0; }
/** * @brief Close SPI device * * This function is called when the caller is no longer using this driver. It * should release or close all resources that were allocated by the open() * function. This function should be called after the open() function. If the * device is not opened yet, this function should return without any operations. * * @param dev pointer to structure of device data */ static void tsb_spi_dev_close(struct device *dev) { int i; struct tsb_spi_dev_info *info = NULL; /* check input parameter */ if (!dev || !device_get_private(dev)) { return; } info = device_get_private(dev); sem_wait(&info->lock); up_disable_irq(TSB_IRQ_SPI); irq_detach(TSB_IRQ_SPI); tsb_spi_hw_deinit(info); for (i = 0; i < info->num_boards; i++) { device_close(info->dev_spi_board[i]); info->dev_spi_board[i] = NULL; } info->state = TSB_SPI_STATE_CLOSED; sem_post(&info->lock); }
static void ssp_cdirqsetup(int irq, xcpt_t irqhandler) { irqstate_t flags; /* Disable interrupts until we are done */ flags = irqsave(); /* Configure the interrupt. Either attach and enable the new * interrupt or disable and detach the old interrupt handler. */ if (irqhandler) { /* Attach then enable the new interrupt handler */ (void)irq_attach(irq, irqhandler); up_enable_irq(irq); } else { /* Disable then detach the old interrupt handler */ up_disable_irq(irq); (void)irq_detach(irq); } }
static int uart_detach_irq(struct uart *uart) { if (uart->params.irq) { return irq_detach(uart->irq_num, uart); } return 0; }
static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source) { int vectorno; ASSERT(dev); ASSERT(source==0); switch( ((struct stm32_tim_priv_s *)dev)->base ) { #if CONFIG_STM32_TIM2 case STM32_TIM2_BASE: vectorno = STM32_IRQ_TIM2; break; #endif #if CONFIG_STM32_TIM3 case STM32_TIM3_BASE: vectorno = STM32_IRQ_TIM3; break; #endif #if CONFIG_STM32_TIM4 case STM32_TIM4_BASE: vectorno = STM32_IRQ_TIM4; break; #endif #if CONFIG_STM32_TIM5 case STM32_TIM5_BASE: vectorno = STM32_IRQ_TIM5; break; #endif #if STM32_NBTIM > 0 #if CONFIG_STM32_TIM6 case STM32_TIM6_BASE: vectorno = STM32_IRQ_TIM6; break; #endif #endif #if STM32_NBTIM > 1 #if CONFIG_STM32_TIM7 case STM32_TIM7_BASE: vectorno = STM32_IRQ_TIM7; break; #endif #endif #if STM32_NATIM > 0 /** \todo add support for multiple sources and callbacks */ #if CONFIG_STM32_TIM1 case STM32_TIM1_BASE: vectorno = STM32_IRQ_TIM1UP; break; #endif #if CONFIG_STM32_TIM8 case STM32_TIM8_BASE: vectorno = STM32_IRQ_TIM8UP; break; #endif #endif default: return ERROR; } /* Disable interrupt when callback is removed */ if (!handler) { up_disable_irq(vectorno); irq_detach(vectorno); return OK; } /* Otherwise set callback and enable interrupt */ irq_attach(vectorno, handler); up_enable_irq(vectorno); // up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); return OK; }
xcpt_t board_button_irq(int id, xcpt_t irqhandler) { xcpt_t oldhandler = NULL; if (id >=0 && id < NUM_BUTTONS) { irqstate_t flags; /* Disable interrupts until we are done. This guarantees that the * following operations are atomic. */ flags = enter_critical_section(); /* Get/set the old button handler * * REVISIT: Keeping copies of the hander in RAM seems wasteful * since the OS already has this information internally. */ #if 0 /* REVISIT */ oldhandler = g_button_handlers[id]; g_button_handlers[id] = irqhandler; #else oldhandler = NULL; #endif /* Are we attaching or detaching? */ if (irqhandler != NULL) { /* Configure the interrupt */ efm32_gpioirq(g_button_configs[id]); /* Attach and enable the interrupt */ (void)irq_attach(g_button_irqs[id], irqhandler); efm32_gpioirqenable(g_button_irqs[id]); } else { /* Disable and detach the interrupt */ efm32_gpioirqdisable(g_button_irqs[id]); (void)irq_detach(g_button_irqs[id]); } leave_critical_section(flags); } /* Return the old button handler (so that it can be restored) */ return oldhandler; }
/**************************************************************************** * Name: adc_shutdown * * Description: * Disable the ADC. This method is called when the ADC device is closed. * This method reverses the operation the setup method. * * Input Parameters: * * Returned Value: * ****************************************************************************/ static void adc_shutdown(FAR struct adc_dev_s *dev) { /* Disable interrupt */ putreg32(ADC_INT_DISABLE, S5J_ADC_INT); /* Disable ADC interrupts and detach the ADC interrupt handler */ up_disable_irq(IRQ_ADC); irq_detach(IRQ_ADC); /* Reset ADC */ putreg32(ADC_CON1_SOFTRESET_RESET, S5J_ADC_CON1); }
xcpt_t board_button_irq(int id, xcpt_t irqhandler) { xcpt_t oldhandler = NULL; irqstate_t flags; int irq; /* Verify that the button ID is within range */ if ((unsigned)id < BOARD_NUM_BUTTONS) { /* Get the IRQ number for the button; A value of zero indicates that * the button does not support the interrupt function. */ irq = g_buttonirq[id]; if (irq > 0) { /* Disable interrupts until we are done */ flags = irqsave(); /* Return the current button handler and set the new interrupt handler */ oldhandler = g_buttonisr[id]; g_buttonisr[id] = irqhandler; /* Configure the interrupt. Either attach and enable the new * interrupt or disable and detach the old interrupt handler. */ if (irqhandler) { /* Attach then enable the new interrupt handler */ (void)irq_attach(irq, irqhandler); up_enable_irq(irq); } else { /* Disable then detach the old interrupt handler */ up_disable_irq(irq); (void)irq_detach(irq); } irqrestore(flags); } } return oldhandler; }
xcpt_t board_button_irq(int id, xcpt_t irqhandler) { xcpt_t rethandler = NULL; irqstate_t flags; int ret; /* Interrupts are supported on KEY5 only */ if (id == BOARD_BUTTON_5) { /* Return the previous value of the interrupt handler */ flags = irqsave(); rethandler = g_oldhandler; g_oldhandler = irqhandler; /* Attach or detach the interrupt handler for KEY5. */ if (irqhandler) { /* Configure KEY5 as an interrupting input */ lpc17_configgpio(ZKITARM_INT_KEY5); /* Attach the new interrupt handler and enable the interrupt */ ret = irq_attach(ZKITARM_KEY5_IRQ, irqhandler); if (ret == OK) { up_enable_irq(ZKITARM_KEY5_IRQ); } } else { /* Disable the interrupt and detach the handler */ up_disable_irq(ZKITARM_KEY5_IRQ); (void)irq_detach(ZKITARM_KEY5_IRQ); /* Configure KEY5 as a non-interrupting input */ lpc17_configgpio(ZKITARM_KEY5); } irqrestore(flags); } return rethandler; }
void tiva_adc_irq_detach(uint8_t adc, uint8_t sse) { uint32_t ret = 0; int irq = sse2irq[SSE_IDX(adc, sse)]; /* Disable ADC interrupts at the level of the AIC */ up_disable_irq(irq); /* Then detach the ADC interrupt handler. */ ret = irq_detach(irq); if (ret < 0) { aerr("ERROR: Failed to detach IRQ %d: %d\n", irq, ret); return; } }
xcpt_t board_button_irq(int id, xcpt_t irqhandler) { xcpt_t oldhandler = NULL; if (id == BUTTON_USER) { irqstate_t flags; /* Disable interrupts until we are done. This guarantees that the * following operations are atomic. */ flags = irqsave(); /* Get the old button interrupt handler and save the new one */ oldhandler = g_irquser1; g_irquser1 = irqhandler; /* Are we attaching or detaching? */ if (irqhandler != NULL) { /* Configure the interrupt */ sam_pioirq(PIO_BTN_USER); (void)irq_attach(IRQ_BTN_USER, irqhandler); sam_pioirqenable(IRQ_BTN_USER); } else { /* Disable and detach the interrupt */ sam_pioirqdisable(IRQ_BTN_USER); (void)irq_detach(IRQ_BTN_USER); } irqrestore(flags); } /* Return the old button handler (so that it can be restored) */ return oldhandler; }
PX4IO_serial::~PX4IO_serial() { if (_tx_dma != nullptr) { stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); } /* reset the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* detach our interrupt handler */ up_disable_irq(PX4IO_SERIAL_VECTOR); irq_detach(PX4IO_SERIAL_VECTOR); /* restore the GPIOs */ stm32_unconfiggpio(PX4IO_SERIAL_TX_GPIO); stm32_unconfiggpio(PX4IO_SERIAL_RX_GPIO); /* and kill our semaphores */ sem_destroy(&_completion_semaphore); sem_destroy(&_bus_semaphore); perf_free(_pc_txns); perf_free(_pc_dmasetup); perf_free(_pc_retries); perf_free(_pc_timeouts); perf_free(_pc_crcerrs); perf_free(_pc_dmaerrs); perf_free(_pc_protoerrs); perf_free(_pc_uerrs); perf_free(_pc_idle); perf_free(_pc_badidle); if (g_interface == this) { g_interface = nullptr; } }
xcpt_t board_button_irq(int id, xcpt_t irqhandler) { xcpt_t oldhandler = NULL; irqstate_t flags; int irq; /* Verify that the button ID is within range */ if ((unsigned)id < BOARD_NUM_BUTTONS) { /* Return the current button handler and set the new interrupt handler */ oldhandler = g_buttonisr[id]; g_buttonisr[id] = irqhandler; /* Disable interrupts until we are done */ flags = enter_critical_section(); /* Configure the interrupt. Either attach and enable the new * interrupt or disable and detach the old interrupt handler. */ irq = g_buttonirq[id]; if (irqhandler) { /* Attach then enable the new interrupt handler */ (void)irq_attach(irq, irqhandler); up_enable_irq(irq); } else { /* Disable then detach the old interrupt handler */ up_disable_irq(irq); (void)irq_detach(irq); } leave_critical_section(flags); } return oldhandler; }
static int z8_attach(FAR struct uart_dev_s *dev) { struct z8_uart_s *priv = (struct z8_uart_s*)dev->priv; int ret; /* Attach the RX IRQ */ ret = irq_attach(priv->rxirq, z8_rxinterrupt); if (ret == OK) { /* Attach the TX IRQ */ ret = irq_attach(priv->txirq, z8_txinterrupt); if (ret != OK) { irq_detach(priv->rxirq); } } return ret; }
static xcpt_t board_button_irqx(gpio_pinset_t pinset, int irq, xcpt_t irqhandler, xcpt_t *store) { xcpt_t oldhandler; irqstate_t flags; /* Disable interrupts until we are done. This guarantees that the following * operations are atomic. */ flags = irqsave(); /* Get the old button interrupt handler and save the new one */ oldhandler = *store; *store = irqhandler; /* Are we attaching or detaching? */ if (irqhandler != NULL) { /* Configure the interrupt */ sam_gpioirq(pinset); (void)irq_attach(irq, irqhandler); sam_gpioirqenable(irq); } else { /* Detach and disable the interrupt */ (void)irq_detach(irq); sam_gpioirqdisable(irq); } irqrestore(flags); /* Return the old button handler (so that it can be restored) */ return oldhandler; }
int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) { if (id >=0 && id < NUM_BUTTONS) { irqstate_t flags; /* Disable interrupts until we are done. This guarantees that the * following operations are atomic. */ flags = enter_critical_section(); /* Are we attaching or detaching? */ if (irqhandler != NULL) { /* Configure the interrupt */ efm32_gpioirq(g_button_configs[id]); /* Attach and enable the interrupt */ (void)irq_attach(g_button_irqs[id], irqhandler, arg); efm32_gpioirqenable(g_button_irqs[id]); } else { /* Disable and detach the interrupt */ efm32_gpioirqdisable(g_button_irqs[id]); (void)irq_detach(g_button_irqs[id]); } leave_critical_section(flags); } /* Return the old button handler (so that it can be restored) */ return OK; }
static int up_attach(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; int ret; /* Attach and enable the IRQ */ #if defined(CONFIG_ARCH_CHIP_IMX1) || defined(CONFIG_ARCH_CHIP_IMXL) ret = irq_attach(priv->rxirq, up_interrupt); if (ret < 0) { return ret; } ret = irq_attach(priv->txirq, up_interrupt); if (ret < 0) { irq_detach(priv->rxirq); return ret; } /* Enable the interrupts (interrupts are still disabled in the UART) */ up_enable_irq(priv->rxirq); up_enable_irq(priv->txirq); #else ret = irq_attach(priv->irq, up_interrupt); if (ret == OK) { /* Enable the interrupt (RX and TX interrupts are still disabled * in the UART */ up_enable_irq(priv->irq); } #endif return ret; }
int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) { irqstate_t flags; int irq; /* Verify that the button ID is within range */ if ((unsigned)id < NUM_BUTTONS) { /* Disable interrupts until we are done */ flags = enter_critical_section(); /* Configure the interrupt. Either attach and enable the new * interrupt or disable and detach the old interrupt handler. */ irq = g_buttonirq[id]; if (irqhandler) { /* Attach then enable the new interrupt handler */ (void)irq_attach(irq, irqhandler, arg); up_enable_irq(irq); } else { /* Disable then detach the old interrupt handler */ up_disable_irq(irq); (void)irq_detach(irq); } leave_critical_section(flags); } return OK; }
static void ez80_detach(struct uart_dev_s *dev) { struct ez80_dev_s *priv = (struct ez80_dev_s*)dev->priv; ez80_disableuartint(priv); irq_detach(priv->irq); }
static int stm32_tim_setisr(FAR struct stm32_tim_dev_s *dev, int (*handler)(int irq, void *context), int source) { int vectorno; DEBUGASSERT(dev != NULL); DEBUGASSERT(source == 0); switch (((struct stm32_tim_priv_s *)dev)->base) { #ifdef CONFIG_STM32F7_TIM1 case STM32_TIM1_BASE: vectorno = STM32_IRQ_TIM1UP; break; #endif #ifdef CONFIG_STM32F7_TIM2 case STM32_TIM2_BASE: vectorno = STM32_IRQ_TIM2; break; #endif #ifdef CONFIG_STM32F7_TIM3 case STM32_TIM3_BASE: vectorno = STM32_IRQ_TIM3; break; #endif #ifdef CONFIG_STM32F7_TIM4 case STM32_TIM4_BASE: vectorno = STM32_IRQ_TIM4; break; #endif #ifdef CONFIG_STM32F7_TIM5 case STM32_TIM5_BASE: vectorno = STM32_IRQ_TIM5; break; #endif #ifdef CONFIG_STM32F7_TIM6 case STM32_TIM6_BASE: vectorno = STM32_IRQ_TIM6; break; #endif #ifdef CONFIG_STM32F7_TIM7 case STM32_TIM7_BASE: vectorno = STM32_IRQ_TIM7; break; #endif #ifdef CONFIG_STM32F7_TIM8 case STM32_TIM8_BASE: vectorno = STM32_IRQ_TIM8UP; break; #endif #ifdef CONFIG_STM32F7_TIM9 case STM32_TIM9_BASE: vectorno = STM32_IRQ_TIM9; break; #endif #ifdef CONFIG_STM32F7_TIM10 case STM32_TIM10_BASE: vectorno = STM32_IRQ_TIM10; break; #endif #ifdef CONFIG_STM32F7_TIM11 case STM32_TIM11_BASE: vectorno = STM32_IRQ_TIM11; break; #endif #ifdef CONFIG_STM32F7_TIM12 case STM32_TIM12_BASE: vectorno = STM32_IRQ_TIM12; break; #endif #ifdef CONFIG_STM32F7_TIM13 case STM32_TIM13_BASE: vectorno = STM32_IRQ_TIM13; break; #endif #ifdef CONFIG_STM32F7_TIM14 case STM32_TIM14_BASE: vectorno = STM32_IRQ_TIM14; break; #endif default: return -EINVAL; } /* Disable interrupt when callback is removed */ if (!handler) { up_disable_irq(vectorno); irq_detach(vectorno); return OK; } /* Otherwise set callback and enable interrupt */ irq_attach(vectorno, handler); up_enable_irq(vectorno); #ifdef CONFIG_ARCH_IRQPRIO /* Set the interrupt priority */ up_prioritize_irq(vectorno, NVIC_SYSH_PRIORITY_DEFAULT); #endif return OK; }
PX4IO_serial_f7::PX4IO_serial_f7() : _tx_dma(nullptr), _rx_dma(nullptr), _current_packet(nullptr), _rx_dma_status(_dma_status_inactive), _completion_semaphore(SEM_INITIALIZER(0)), #if 0 _pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")), _pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs ")) #else _pc_dmasetup(nullptr), _pc_dmaerrs(nullptr) #endif { } PX4IO_serial_f7::~PX4IO_serial_f7() { if (_tx_dma != nullptr) { stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); } /* reset the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* detach our interrupt handler */ up_disable_irq(PX4IO_SERIAL_VECTOR); irq_detach(PX4IO_SERIAL_VECTOR); /* restore the GPIOs */ px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO); px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO); /* Disable APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0); /* and kill our semaphores */ px4_sem_destroy(&_completion_semaphore); perf_free(_pc_dmasetup); perf_free(_pc_dmaerrs); } int PX4IO_serial_f7::init() { /* initialize base implementation */ int r; if ((r = PX4IO_serial::init((IOPacket *)ROUND_UP_TO_POW2_CT((uintptr_t)_io_buffer_storage, CACHE_LINE_SIZE))) != 0) { return r; } /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } /* Enable the APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN); /* configure pins for serial use */ px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO); px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO); /* reset & configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* clear data that may be in the RDR and clear overrun error: */ if (rISR & USART_ISR_RXNE) { (void)rRDR; } rICR = rISR & rISR_ERR_FLAGS_MASK; /* clear the flags */ /* configure line speed */ uint32_t usartdiv32 = (PX4IO_SERIAL_CLOCK + (PX4IO_SERIAL_BITRATE) / 2) / (PX4IO_SERIAL_BITRATE); rBRR = usartdiv32; /* attach serial interrupt handler */ irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this); up_enable_irq(PX4IO_SERIAL_VECTOR); /* enable UART in DMA mode, enable error and line idle interrupts */ rCR3 = USART_CR3_EIE; /* TODO: maybe use DDRE */ rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; /* TODO: maybe we need to adhere to the procedure as described in the reference manual page 1251 (34.5.2) */ /* create semaphores */ px4_sem_init(&_completion_semaphore, 0, 0); /* _completion_semaphore use case is a signal */ px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE); /* XXX this could try talking to IO */ return 0; }
PX4IO_serial_f4::PX4IO_serial_f4() : _tx_dma(nullptr), _rx_dma(nullptr), _current_packet(nullptr), _rx_dma_status(_dma_status_inactive), _completion_semaphore(SEM_INITIALIZER(0)), #if 0 _pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")), _pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs ")) #else _pc_dmasetup(nullptr), _pc_dmaerrs(nullptr) #endif { } PX4IO_serial_f4::~PX4IO_serial_f4() { if (_tx_dma != nullptr) { stm32_dmastop(_tx_dma); stm32_dmafree(_tx_dma); } if (_rx_dma != nullptr) { stm32_dmastop(_rx_dma); stm32_dmafree(_rx_dma); } /* reset the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* detach our interrupt handler */ up_disable_irq(PX4IO_SERIAL_VECTOR); irq_detach(PX4IO_SERIAL_VECTOR); /* restore the GPIOs */ px4_arch_unconfiggpio(PX4IO_SERIAL_TX_GPIO); px4_arch_unconfiggpio(PX4IO_SERIAL_RX_GPIO); /* Disable APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, PX4IO_SERIAL_RCC_EN, 0); /* and kill our semaphores */ px4_sem_destroy(&_completion_semaphore); perf_free(_pc_dmasetup); perf_free(_pc_dmaerrs); } int PX4IO_serial_f4::init() { /* initialize base implementation */ int r; if ((r = PX4IO_serial::init(&_io_buffer_storage)) != 0) { return r; } /* allocate DMA */ _tx_dma = stm32_dmachannel(PX4IO_SERIAL_TX_DMAMAP); _rx_dma = stm32_dmachannel(PX4IO_SERIAL_RX_DMAMAP); if ((_tx_dma == nullptr) || (_rx_dma == nullptr)) { return -1; } /* Enable the APB clock for the USART peripheral */ modifyreg32(PX4IO_SERIAL_RCC_REG, 0, PX4IO_SERIAL_RCC_EN); /* configure pins for serial use */ px4_arch_configgpio(PX4IO_SERIAL_TX_GPIO); px4_arch_configgpio(PX4IO_SERIAL_RX_GPIO); /* reset & configure the UART */ rCR1 = 0; rCR2 = 0; rCR3 = 0; /* eat any existing interrupt status */ (void)rSR; (void)rDR; /* configure line speed */ uint32_t usartdiv32 = PX4IO_SERIAL_CLOCK / (PX4IO_SERIAL_BITRATE / 2); uint32_t mantissa = usartdiv32 >> 5; uint32_t fraction = (usartdiv32 - (mantissa << 5) + 1) >> 1; rBRR = (mantissa << USART_BRR_MANT_SHIFT) | (fraction << USART_BRR_FRAC_SHIFT); /* attach serial interrupt handler */ irq_attach(PX4IO_SERIAL_VECTOR, _interrupt, this); up_enable_irq(PX4IO_SERIAL_VECTOR); /* enable UART in DMA mode, enable error and line idle interrupts */ rCR3 = USART_CR3_EIE; rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE; /* create semaphores */ px4_sem_init(&_completion_semaphore, 0, 0); /* _completion_semaphore use case is a signal */ px4_sem_setprotocol(&_completion_semaphore, SEM_PRIO_NONE); /* XXX this could try talking to IO */ return 0; }
xcpt_t arch_phy_irq(FAR const char *intf, xcpt_t handler, phy_enable_t *enable) { irqstate_t flags; xcpt_t *phandler; xcpt_t oldhandler; pio_pinset_t pinset; phy_enable_t enabler; int irq; DEBUGASSERT(intf); nvdbg("%s: handler=%p\n", intf, handler); #ifdef CONFIG_SAMA5_EMACA phydbg("EMAC: devname=%s\n", SAMA5_EMAC_DEVNAME); #endif #ifdef CONFIG_SAMA5_GMAC phydbg("GMAC: devname=%s\n", SAMA5_GMAC_DEVNAME); #endif #ifdef CONFIG_SAMA5_EMACA if (strcmp(intf, SAMA5_EMAC_DEVNAME) == 0) { phydbg("Select EMAC\n"); phandler = &g_emac_handler; pinset = PIO_INT_ETH1; irq = IRQ_INT_ETH1; enabler = sam_emac_phy_enable; } else #endif #ifdef CONFIG_SAMA5_GMAC if (strcmp(intf, SAMA5_GMAC_DEVNAME) == 0) { phydbg("Select GMAC\n"); phandler = &g_gmac_handler; pinset = PIO_INT_ETH0; irq = IRQ_INT_ETH0; enabler = sam_gmac_phy_enable; } else #endif { ndbg("Unsupported interface: %s\n", intf); return NULL; } /* Disable interrupts until we are done. This guarantees that the * following operations are atomic. */ flags = irqsave(); /* Get the old interrupt handler and save the new one */ oldhandler = *phandler; *phandler = handler; /* Configure the interrupt */ if (handler) { phydbg("Configure pin: %08x\n", pinset); sam_pioirq(pinset); phydbg("Attach IRQ%d\n", irq); (void)irq_attach(irq, handler); } else { phydbg("Detach IRQ%d\n", irq); (void)irq_detach(irq); enabler = NULL; } /* Return with the interrupt disabled in either case */ sam_pioirqdisable(irq); /* Return the enabling function pointer */ if (enable) { *enable = enabler; } /* Return the old handler (so that it can be restored) */ irqrestore(flags); return oldhandler; }
xcpt_t arch_phy_irq(FAR const char *intf, xcpt_t handler, phy_enable_t *enable) { irqstate_t flags; xcpt_t *phandler; xcpt_t oldhandler; gpio_pinset_t pinset; phy_enable_t enabler; int irq; DEBUGASSERT(intf); ninfo("%s: handler=%p\n", intf, handler); phyinfo("EMAC0: devname=%s\n", SAMV7_EMAC0_DEVNAME); if (strcmp(intf, SAMV7_EMAC0_DEVNAME) == 0) { phyinfo("Select EMAC0\n"); phandler = &g_emac0_handler; pinset = GPIO_EMAC0_INT; irq = IRQ_EMAC0_INT; enabler = sam_emac0_phy_enable; } else { nerr("ERROR: Unsupported interface: %s\n", intf); return NULL; } /* Disable interrupts until we are done. This guarantees that the * following operations are atomic. */ flags = enter_critical_section(); /* Get the old interrupt handler and save the new one */ oldhandler = *phandler; *phandler = handler; /* Configure the interrupt */ if (handler) { phyinfo("Configure pin: %08x\n", pinset); sam_gpioirq(pinset); phyinfo("Attach IRQ%d\n", irq); (void)irq_attach(irq, handler); } else { phyinfo("Detach IRQ%d\n", irq); (void)irq_detach(irq); enabler = NULL; } /* Return with the interrupt disabled in either case */ sam_gpioirqdisable(irq); /* Return the enabling function pointer */ if (enable) { *enable = enabler; } /* Return the old handler (so that it can be restored) */ leave_critical_section(flags); return oldhandler; }