예제 #1
0
파일: stm32_capture.c 프로젝트: dagar/NuttX
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;
}
예제 #2
0
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);
}
예제 #3
0
파일: atmega_serial.c 프로젝트: a1ien/nuttx
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);
}
예제 #4
0
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);
}
예제 #5
0
파일: imx_serial.c 프로젝트: a1ien/nuttx
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
}
예제 #6
0
파일: tsb_i2c.c 프로젝트: AresHou/nuttx
/**
 * 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;
}
예제 #7
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);
}
예제 #8
0
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);
    }
}
예제 #9
0
static int uart_detach_irq(struct uart *uart) {

    if (uart->params.irq) {
        return irq_detach(uart->irq_num, uart);
    }

    return 0;
}
예제 #10
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;
}
예제 #11
0
파일: efm32_buttons.c 프로젝트: a1ien/nuttx
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;
}
예제 #12
0
파일: s5j_adc.c 프로젝트: tool3210/TizenRT
/****************************************************************************
 * 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);
}
예제 #13
0
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;
}
예제 #14
0
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;
}
예제 #15
0
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;
    }
}
예제 #16
0
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;
}
예제 #17
0
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;
	}
}
예제 #18
0
파일: lpc43_buttons.c 프로젝트: a1ien/nuttx
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;
}
예제 #19
0
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;
}
예제 #20
0
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;
}
예제 #21
0
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;
}
예제 #22
0
파일: imx_serial.c 프로젝트: a1ien/nuttx
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;
}
예제 #23
0
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;
}
예제 #24
0
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);
}
예제 #25
0
파일: stm32_tim.c 프로젝트: a1ien/nuttx
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;
}
예제 #26
0
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;
}
예제 #27
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;
}
예제 #28
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;
}
예제 #29
0
파일: sam_ethernet.c 프로젝트: a1ien/nuttx
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;
}