Esempio n. 1
0
/*
 * Initialise the timer we are going to use.
 *
 * We expect that we'll own one of the reduced-function STM32 general
 * timers, and that we can use channel 1 in compare mode.
 */
static void
hrt_tim_init(void)
{
	/* claim our interrupt vector */
	irq_attach(HRT_TIMER_VECTOR, hrt_tim_isr);

	/* clock/power on our timer */
	modifyreg32(HRT_TIMER_POWER_REG, 0, HRT_TIMER_POWER_BIT);

	/* disable and configure the timer */
	rCR1 = 0;
	rCR2 = 0;
	rSMCR = 0;
	rDIER = DIER_HRT | DIER_PPM;
	rCCER = 0;		/* unlock CCMR* registers */
	rCCMR1 = CCMR1_PPM;
	rCCMR2 = CCMR2_PPM;
	rCCER = CCER_PPM;
	rDCR = 0;

	/* configure the timer to free-run at 1MHz */
	rPSC = (HRT_TIMER_CLOCK / 1000000) - 1;	/* this really only works for whole-MHz clocks */

	/* run the full span of the counter */
	rARR = 0xffff;

	/* set an initial capture a little ways off */
	rCCR_HRT = 1000;

	/* generate an update event; reloads the counter, all registers */
	rEGR = GTIM_EGR_UG;

	/* enable the timer */
	rCR1 = GTIM_CR1_CEN;

	/* enable interrupts */
	up_enable_irq(HRT_TIMER_VECTOR);
}
Esempio n. 2
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;
}
Esempio n. 3
0
void tiva_adc_sse_int_enable(uint8_t adc, uint8_t sse, bool state)
{
  irqstate_t flags;
  uintptr_t imreg = TIVA_ADC_IM(adc);
  int irq = tiva_adc_getirq(adc, sse);

  flags = enter_critical_section();
  up_disable_irq(irq);

  tiva_adc_sse_clear_int(adc, sse);

  if (state == true)
    {
      modifyreg32(imreg, 0, (1 << sse));
    }
  else
    {
      modifyreg32(imreg, (1 << sse), 0);
    }

  up_enable_irq(irq);
  leave_critical_section(flags);
}
Esempio n. 4
0
static int skel_ifup(FAR struct net_driver_s *dev)
{
  FAR struct skel_driver_s *priv = (FAR struct skel_driver_s *)dev->d_private;

#ifdef CONFIG_NET_IPv4
  ndbg("Bringing up: %d.%d.%d.%d\n",
       dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff,
       (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24);
#endif
#ifdef CONFIG_NET_IPv6
  ndbg("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
       dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2],
       dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5],
       dev->d_ipv6addr[6], dev->d_ipv6addr[7]);
#endif

  /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */

  /* Instantiate the MAC address from priv->sk_dev.d_mac.ether_addr_octet */

#ifdef CONFIG_NET_ICMPv6
  /* Set up IPv6 multicast address filtering */

  skel_ipv6multicast(priv);
#endif

  /* Set and activate a timer process */

  (void)wd_start(priv->sk_txpoll, skeleton_WDDELAY, skel_poll_expiry, 1,
                 (wdparm_t)priv);

  /* Enable the Ethernet interrupt */

  priv->sk_bifup = true;
  up_enable_irq(CONFIG_skeleton_IRQ);
  return OK;
}
Esempio n. 5
0
/****************************************************************************
 * Name: adc_setup
 *
 * Description:
 *   Configure the ADC. This method is called the first time that the ADC
 *   device is opened.  This will occur when the port is first opened.
 *   This setup includes configuring and attaching ADC interrupts.
 *   Interrupts are all disabled upon return.
 *
 * Input Parameters:
 *
 * Returned Value:
 ****************************************************************************/
static int adc_setup(FAR struct adc_dev_s *dev)
{
	int ret;
	FAR struct s5j_dev_s *priv = (FAR struct s5j_dev_s *)dev->ad_priv;

	/* Attach the ADC interrupt */
	ret = irq_attach(IRQ_ADC, adc_interrupt, priv);
	if (ret < 0) {
		lldbg("irq_attach failed: %d\n", ret);
		return ret;
	}

	/* Make sure that the ADC device is in the powered up, reset state */
	adc_reset(dev);

	/*
	 * Enable the ADC interrupt, but it will not be generated until we
	 * request to start the conversion.
	 */
	llwdbg("Enable the ADC interrupt: irq=%d\n", IRQ_ADC);
	up_enable_irq(IRQ_ADC);

	return OK;
}
Esempio n. 6
0
void up_timer_initialize(void)
{
  /* uint32_t to avoid compile time overflow errors */

  uint32_t divisor = PIT_DIVISOR;
  DEBUGASSERT(divisor <= 0xffff);

  /* Attach to the timer interrupt handler */

  (void)irq_attach(IRQ0, (xcpt_t)up_timerisr);

  /* Send the command byte to configure counter 0 */

  outb(PIT_OCW_MODE_SQUARE|PIT_OCW_RL_DATA|PIT_OCW_COUNTER_0, PIT_REG_COMMAND);

  /* Set the PIT input frequency divisor */

  outb((uint8_t)(divisor & 0xff),  PIT_REG_COUNTER0);
  outb((uint8_t)((divisor >> 8) & 0xff), PIT_REG_COUNTER0);

  /* And enable IRQ0 */

  up_enable_irq(IRQ0);
}
Esempio n. 7
0
/**
 * Initialise an I2C device
 */
struct i2c_dev_s *up_i2cinitialize(int port)
{
    irqstate_t flags;
    int retval;

    i2cvdbg("Init I2C port %d\n", port);

    /* Only one I2C port on TSB */
    if (port > 0)
        return NULL;

    flags = irqsave();

    if (refcount++)
        goto out;

    retval = tsb_request_pinshare(TSB_PIN_GPIO21 | TSB_PIN_GPIO22);
    if (retval) {
        lowsyslog("I2C: cannot get ownership of I2C pins\n");
        goto err_req_pinshare;
    }

    sem_init(&g_mutex, 0, 1);
    sem_init(&g_wait, 0, 0);

    /* enable I2C pins */
    tsb_clr_pinshare(TSB_PIN_GPIO21);
    tsb_clr_pinshare(TSB_PIN_GPIO22);

    /* enable I2C clocks */
    tsb_clk_enable(TSB_CLK_I2CP);
    tsb_clk_enable(TSB_CLK_I2CS);

    /* reset I2C module */
    tsb_reset(TSB_RST_I2CP);
    tsb_reset(TSB_RST_I2CS);

    /* Initialize the I2C controller */
    tsb_i2c_init();

    /* Allocate a watchdog timer */
    g_timeout = wd_create();
    DEBUGASSERT(g_timeout != 0);

    /* Attach Interrupt Handler */
    irq_attach(TSB_IRQ_I2C, i2c_interrupt);

    /* Enable Interrupt Handler */
    up_enable_irq(TSB_IRQ_I2C);

    /* Install our operations */
    g_dev.ops = &dev_i2c_ops;

out:
    irqrestore(flags);
    return &g_dev;

err_req_pinshare:
    refcount--;
    irqrestore(flags);
    return NULL;
}
Esempio n. 8
0
void up_timer_initialize(void)
{
  uint32_t ticks_per_int;
  uint32_t mask_bits = 0;
  uint32_t mask_test = 0x80000000;

  lpc43_RIT_timer_stop();
  lpc43_load_RIT_timer(0);
  internal_timer = 0;

  /* Set up the IRQ here */

  irq_attach(LPC43M4_IRQ_RITIMER, lpc43_RIT_isr);

  /* Compute how many seconds per tick we have on the main clock.  If it is
   * 204MHz for example, then there should be about 4.90ns per tick
   */

  sec_per_tick = (double)1.0/(double)LPC43_CCLK;

  /* Given an RIT_TIMER_RESOLUTION, compute how many ticks it will take to
   * reach that resolution.  For example, if we wanted a 1/4uS timer
   * resolution, that would be 250ns resolution.  The timer is an integer
   * value, although maybe this should change, but that means
   * 250/1000000000*0.00000000490 = 51.02 ticks or 51 ticks, roughly.
   * We round up by 1 tick.
   */

  ticks_per_int = RIT_TIMER_RESOLUTION/(1000000000*sec_per_tick)+1;

  /* Now we need to compute the mask that will let us set up to generate an
   * interrupt every 1/4uS.  This isn't "tickless" per-se, and probably
   * should be implemented differently, however it allows me to create a
   * 64 bit nanosecond timer than can "free-run" by being updated every
   * RIT_TIMER_RESOLUTION cycles.  I would have implemented the better
   * approach, but I didn't have a good way to determine how to manage a
   * 32 bit ns timer.  Every 21 seconds the thing rolls [email protected] 204MHz, so
   * you'd have to set up the compare interrupt to handle the roll over.  It
   * WOULD be fewer interrupts, but it seemed to make things more
   * complicated.  When I have a better idea, I'll change this.
   */

  while (!((mask_test >> mask_bits) & ticks_per_int))
    {
      mask_bits++;
    }

  tmrinfo("mask_bits = %d, mask = %X, ticks_per_int = %d\r\n",
          mask_bits, (0xffffffff << (32 - mask_bits)), ticks_per_int);

  /* Set the mask and compare value so we get interrupts every
   * RIT_TIMER_RESOLUTION cycles.
   */

  lpc43_set_RIT_timer_mask((0xFFFFFFFF << (32 - mask_bits)));
  lpc43_load_RIT_compare(ticks_per_int);

  /* Turn on the IRQ */

  up_enable_irq(LPC43M4_IRQ_RITIMER);

  /* Start the timer */

  lpc43_RIT_timer_start();
}
Esempio n. 9
0
// Allocate an UniPro TX channel.
int tsb_dma_allocal_unipro_tx_channel(struct tsb_dma_channel *channel)
{
    int ret;
    tsb_dma_gdmac_unipro_tx_channel *unipro_tx_channel = zalloc (
            sizeof(tsb_dma_gdmac_unipro_tx_channel));
    uint8_t *prog_ptr;
    volatile tsb_dma_gdmac_control_regs *control_regs =
            (tsb_dma_gdmac_control_regs*) GDMAC_CONTROL_REGS_ADDRESS;

    if (unipro_tx_channel == NULL) {
        return -ENOMEM;
    }

    prog_ptr = &unipro_tx_channel->dma_program[0];

    // make a copy of the UniPro TX binary code.
    memcpy (prog_ptr, &tsb_dma_gdma_unipro_tx_prg[0],
            sizeof(tsb_dma_gdma_unipro_tx_prg));

    // Set a pointer to the EOM register address.
    *(uint32_t*) (&prog_ptr[2]) = (uint32_t) &eom_value;
    prog_ptr += DMA_MOV_SIZE;
    unipro_tx_channel->eom_dest_addr = (uint32_t*) (prog_ptr + 2);

    // Set a pointer to the PL330 event used for this UniPro TX channel.
    prog_ptr += DMA_MOV_SIZE + DMA_LD_SIZE + DMA_ST_SIZE + DMA_WMB_SIZE;
    prog_ptr[2] = GDMAC_EVENT(channel->channel_id);
    prog_ptr += DMA_SEV_SIZE + DMA_END_SIZE;

    // Set a pointer to the starting address of this UniPro PL330 program
    unipro_tx_channel->dma_program_start = prog_ptr;

    // Set pointers to the source and destination address,as well as the size of this GDMAC UniPro TX data transfer.
    prog_ptr += DMA_MOV_SIZE;
    unipro_tx_channel->tx_src_addr = (uint32_t*) (prog_ptr + 2);
    prog_ptr += DMA_MOV_SIZE;
    unipro_tx_channel->tx_dest_addr = (uint32_t*) (prog_ptr + 2);
    prog_ptr += DMA_MOV_SIZE;
    unipro_tx_channel->tx_lc_addr = prog_ptr + 1;

    // Set a pointer to the EOM condition counter. There is no if statement in PL330,
    // we are using loop count to simulate the if statement.
    prog_ptr += DMA_LP_SIZE + DMA_LD_SIZE + DMA_ST_SIZE + DMA_LPEND_SIZE;
    unipro_tx_channel->eom_lc_addr = prog_ptr + 1;

    // Set a pointer to the PL330 event used for this UniPro TX channel.
    prog_ptr += DMA_LP_SIZE + DMA_LPEND_SIZE + DMA_WMB_SIZE;
    prog_ptr[2] = GDMAC_EVENT(channel->channel_id);

    // Set interrupt handler for this GDMAC UniPro TX channel
    ret = irq_attach (DMA_CHANNEL_TO_TSB_IRQ(channel->channel_id),
            tsb_dma_irq_handler);
    if (ret != OK) {
        lldbg ("Failed to attach interrupt %d.\n",
                DMA_CHANNEL_TO_TSB_IRQ(channel->channel_id));
        return -EIO;
    } else {
        sem_init (&unipro_tx_channel->tx_sem, 0, 0);
        control_regs->inten = GDMAC_EVENT_MASK(channel->channel_id);
        up_enable_irq (DMA_CHANNEL_TO_TSB_IRQ(channel->channel_id));
    }

    // Set the transfer and transfer done handlers
    channel->do_dma_transfer = gdmac_unipro_tx_transfer;
    channel->release_channel = gdmac_unipro_tx_release_channel;
    channel->channel_info = (struct tsb_dma_channel_info*)unipro_tx_channel;

    return 0;
}
Esempio n. 10
0
void up_irqinitialize(void)
{
  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);

  /* The standard location for the vector table is at the beginning of FLASH
   * at address 0x0800:0000.  If we are using the STMicro DFU bootloader, then
   * the vector table will be offset to a different location in FLASH and we
   * will need to set the NVIC vector location to this alternative location.
   */

#ifdef CONFIG_STM32_DFU
  putreg32((uint32_t)stm32_vectors, NVIC_VECTAB);
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ48_51_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ52_55_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ56_59_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ60_63_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ64_67_PRIORITY);

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(STM32_IRQ_SVCALL, up_svcall);
  irq_attach(STM32_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(STM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(STM32_IRQ_NMI, stm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault);
  irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault);
  irq_attach(STM32_IRQ_PENDSV, stm32_pendsv);
  irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor);
  irq_attach(STM32_IRQ_RESERVED, stm32_reserved);
#endif

  stm32_dumpnvic("initial", NR_IRQS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS

  /* Initialize FIQs */

#ifdef CONFIG_ARCH_FIQ
  up_fiqinitialize();
#endif

  /* And finally, enable interrupts */

  setbasepri(NVIC_SYSH_PRIORITY_MAX);
  irqrestore(0);
#endif
}
Esempio n. 11
0
void up_irqinitialize(void)
{
  uintptr_t regaddr;
  int nintlines;
  int i;

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports, defined in groups of 32. That is,
   * the total number of interrupt lines is up to (32*(INTLINESNUM+1)).
   *
   *  0 -> 32 interrupt lines, 1 enable register,   8 priority registers
   *  1 -> 64 "       " "   ", 2 enable registers, 16 priority registers
   *  2 -> 96 "       " "   ", 3 enable regsiters, 24 priority registers
   *  ...
   */

  nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1;

  /* Disable all interrupts.  There are nintlines interrupt enable
   * registers.
   */

  for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(0, regaddr);
    }

  /* Make sure that we are using the correct vector table.  The default
   * vector address is 0x0000:0000 but if we are executing code that is
   * positioned in SRAM or in external FLASH, then we may need to reset
   * the interrupt vector so that it refers to the table in SRAM or in
   * external FLASH.
   */

  putreg32((uint32_t)_vectors, NVIC_VECTAB);

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* Now set all of the interrupt lines to the default priority.  There are
   * nintlines * 8 priority registers.
   */

  for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(DEFPRIORITY32, regaddr);
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(KINETIS_IRQ_SVCALL, up_svcall);
  irq_attach(KINETIS_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
  /* up_prioritize_irq(KINETIS_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
  kinetis_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARM_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(KINETIS_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(KINETIS_IRQ_NMI, kinetis_nmi);
#ifndef CONFIG_ARM_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault);
  irq_attach(KINETIS_IRQ_USAGEFAULT, kinetis_usagefault);
  irq_attach(KINETIS_IRQ_PENDSV, kinetis_pendsv);
  irq_attach(KINETIS_IRQ_DBGMONITOR, kinetis_dbgmonitor);
  irq_attach(KINETIS_IRQ_RESERVED, kinetis_reserved);
#endif

  kinetis_dumpnvic("initial", NR_IRQS);

  /* Initialize logic to support a second level of interrupt decoding for
   * configured pin interrupts.
   */

#ifdef CONFIG_GPIO_IRQ
  kinetis_pinirqinitialize();
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  irqenable();
#endif
}
Esempio n. 12
0
void
interface_init(void)
{
	pc_txns = perf_alloc(PC_ELAPSED, "txns");
	pc_errors = perf_alloc(PC_COUNT, "errors");
	pc_ore = perf_alloc(PC_COUNT, "overrun");
	pc_fe = perf_alloc(PC_COUNT, "framing");
	pc_ne = perf_alloc(PC_COUNT, "noise");
	pc_idle = perf_alloc(PC_COUNT, "idle");
	pc_badidle = perf_alloc(PC_COUNT, "badidle");
	pc_regerr = perf_alloc(PC_COUNT, "regerr");
	pc_crcerr = perf_alloc(PC_COUNT, "crcerr");

	/* allocate DMA */
	tx_dma = stm32_dmachannel(PX4FMU_SERIAL_TX_DMA);
	rx_dma = stm32_dmachannel(PX4FMU_SERIAL_RX_DMA);

	/* configure pins for serial use */
	px4_arch_configgpio(PX4FMU_SERIAL_TX_GPIO);
	px4_arch_configgpio(PX4FMU_SERIAL_RX_GPIO);

	/* reset and configure the UART */
	rCR1 = 0;
	rCR2 = 0;
	rCR3 = 0;

	/* clear status/errors */
	(void)rSR;
	(void)rDR;

	/* configure line speed */
	uint32_t usartdiv32 = PX4FMU_SERIAL_CLOCK / (PX4FMU_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);

	/* connect our interrupt */
	irq_attach(PX4FMU_SERIAL_VECTOR, serial_interrupt, NULL);
	up_enable_irq(PX4FMU_SERIAL_VECTOR);

	/* enable UART and error/idle interrupts */
	rCR3 = USART_CR3_EIE;
	rCR1 = USART_CR1_RE | USART_CR1_TE | USART_CR1_UE | USART_CR1_IDLEIE;

#if 0	/* keep this for signal integrity testing */

	for (;;) {
		while (!(rSR & USART_SR_TXE))
			;

		rDR = 0xfa;

		while (!(rSR & USART_SR_TXE))
			;

		rDR = 0xa0;
	}

#endif

	/* configure RX DMA and return to listening state */
	dma_reset();

	debug("serial init");
}
Esempio n. 13
0
uint32_t *pic32mx_decodeirq(uint32_t *regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS

  up_ledon(LED_INIRQ);
  PANIC(OSERR_ERREXCEPTION);
  up_ledoff(LED_INIRQ); /* Won't get here */
  return regs;

#else
  uint32_t *savestate;
  uint32_t regval;
  int irq;

  /* If the board supports LEDs, turn on an LED now to indicate that we are
   * processing an interrupt.
   */

  up_ledon(LED_INIRQ);

  /* Save the current value of current_regs (to support nested interrupt
   * handling).  Then set current_regs to regs, indicating that this is
   * the interrupted context that is being processed now.
   */

  savestate    = (uint32_t*)current_regs;
  current_regs = regs;

  /* Loop while there are pending interrupts with priority greater than zero */

  for (;;)
    {
      /* Read the INTSTAT register.  This register contains both the priority
       * and the interrupt vector number.
       */

      regval = getreg32(PIC32MX_INT_INTSTAT);
      if ((regval & INT_INTSTAT_RIPL_MASK) == 0)
        {
          /* Break out of the loop when the priority is zero meaning that
           * there are no further pending interrupts.
           */

          break;
        }

      /* Get the vector number.  The IRQ numbers have been arranged so that
       * vector numbers and NuttX IRQ numbers are the same value.
       */

      irq = ((regval) & INT_INTSTAT_VEC_MASK) >> INT_INTSTAT_VEC_SHIFT;
      
      /* Disable further interrupts from this source until the driver has
       * cleared the pending interrupt sources.
       */

      up_disable_irq(irq);

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);

      /* Unmask the last interrupt (global interrupt below the current interrupt
       * level are are still disabled)
       */

      up_enable_irq(irq);
    }

  /* If a context switch occurred while processing the interrupt then
   * current_regs may have change value.  If we return any value different
   * from the input regs, then the lower level will know that a context
   * switch occurred during interrupt processing.
   */

  regs = (uint32_t*)current_regs;

  /* Restore the previous value of current_regs.  NULL would indicate that
   * we are no longer in an interrupt handler.  It will be non-NULL if we
   * are returning from a nested interrupt.
   */

  current_regs = savestate;
  if (current_regs == NULL)
    {
      up_ledoff(LED_INIRQ);
    }

  return regs;
#endif
}
Esempio n. 14
0
void up_irqinitialize(void)
{
  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);
  putreg32(0, NVIC_IRQ64_95_ENABLE);
  putreg32(0, NVIC_IRQ96_127_ENABLE);

  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

#ifdef CONFIG_ARCH_RAMVECTORS
  up_ramvec_initialize();
#endif

  /* Set all interrrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ32_35_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ36_39_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ40_43_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ44_47_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ48_51_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ52_55_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ56_59_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ60_63_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ64_67_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ68_71_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ72_75_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ76_79_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ80_83_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ84_87_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ88_91_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ92_95_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ96_99_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ100_103_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ104_107_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ108_111_PRIORITY); /* K40 has 111 defined vectors */
#if NR_VECTORS > 111
  putreg32(DEFPRIORITY32, NVIC_IRQ112_115_PRIORITY); /* K60 has 120 defined vectors */
  putreg32(DEFPRIORITY32, NVIC_IRQ116_119_PRIORITY);
#endif

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(KINETIS_IRQ_SVCALL, up_svcall);
  irq_attach(KINETIS_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(KINETIS_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   kinetis_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(KINETIS_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(KINETIS_IRQ_NMI, kinetis_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(KINETIS_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(KINETIS_IRQ_BUSFAULT, kinetis_busfault);
  irq_attach(KINETIS_IRQ_USAGEFAULT, kinetis_usagefault);
  irq_attach(KINETIS_IRQ_PENDSV, kinetis_pendsv);
  irq_attach(KINETIS_IRQ_DBGMONITOR, kinetis_dbgmonitor);
  irq_attach(KINETIS_IRQ_RESERVED, kinetis_reserved);
#endif

  kinetis_dumpnvic("initial", NR_IRQS);

  /* Initialize logic to support a second level of interrupt decoding for
   * configured pin interrupts.
   */
 
#ifdef CONFIG_GPIO_IRQ
  kinetis_pinirqinitialize();
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  irqenable();
#endif
}
Esempio n. 15
0
void imxrt_gpioirq_initialize(void)
{
  /* Disable all GPIO interrupts at the source */

  putreg32(0, IMXRT_GPIO1_IMR);
  putreg32(0, IMXRT_GPIO2_IMR);
  putreg32(0, IMXRT_GPIO3_IMR);
  putreg32(0, IMXRT_GPIO4_IMR);
  putreg32(0, IMXRT_GPIO5_IMR);

  /* Disable all unconfigured GPIO interrupts at the NVIC */

#ifndef CONFIG_IMXRT_GPIO1_0_15_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO1_0_15);
#endif
#ifndef CONFIG_IMXRT_GPIO1_16_31_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO1_16_31);
#endif
#ifndef CONFIG_IMXRT_GPIO2_0_15_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO2_0_15);
#endif
#ifndef CONFIG_IMXRT_GPIO2_16_31_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO2_16_31);
#endif
#ifndef CONFIG_IMXRT_GPIO3_0_15_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO3_0_15);
#endif
#ifndef CONFIG_IMXRT_GPIO3_16_31_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO3_16_31);
#endif
#ifndef CONFIG_IMXRT_GPIO4_0_15_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO4_0_15);
#endif
#ifndef CONFIG_IMXRT_GPIO4_16_31_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO4_16_31);
#endif
#ifndef CONFIG_IMXRT_GPIO5_0_15_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO5_0_15);
#endif
#ifndef CONFIG_IMXRT_GPIO5_16_31_IRQ
  up_disable_irq(IMXRT_IRQ_GPIO5_16_31);
#endif

  /* Attach all configured GPIO interrupts and enable the interrupt at the
   * NVIC
   */

#ifdef CONFIG_IMXRT_GPIO1_0_15_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO1_0_15,
                         imxrt_gpio1_0_15_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO1_0_15);
#endif

#ifdef CONFIG_IMXRT_GPIO1_16_31_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO1_16_31,
                         imxrt_gpio1_16_31_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO1_16_31);
#endif

#ifdef CONFIG_IMXRT_GPIO2_0_15_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO2_0_15,
                         imxrt_gpio2_0_15_interrupt,NULL));
  up_enable_irq(IMXRT_IRQ_GPIO2_0_15);
#endif

#ifdef CONFIG_IMXRT_GPIO2_16_31_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO2_16_31,
                         imxrt_gpio2_16_31_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO2_16_31);
#endif

#ifdef CONFIG_IMXRT_GPIO3_0_15_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO3_0_15,
                         imxrt_gpio3_0_15_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO3_0_15);
#endif

#ifdef CONFIG_IMXRT_GPIO3_16_31_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO3_16_31,
                         imxrt_gpio3_16_31_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO3_16_31);
#endif

#ifdef CONFIG_IMXRT_GPIO4_0_15_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO4_0_15,
                         imxrt_gpio4_0_15_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO4_0_15);
#endif

#ifdef CONFIG_IMXRT_GPIO4_16_31_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO4_16_31,
                         imxrt_gpio4_16_31_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO4_16_31);
#endif

#ifdef CONFIG_IMXRT_GPIO5_0_15_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO5_0_15,
                         imxrt_gpio5_0_15_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO5_0_15);
#endif

#ifdef CONFIG_IMXRT_GPIO5_16_31_IRQ
  DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO5_16_31,
                         imxrt_gpio5_16_31_interrupt, NULL));
  up_enable_irq(IMXRT_IRQ_GPIO5_16_31);
#endif
}
Esempio n. 16
0
uint32_t *up_doirq(int irq, uint32_t* regs)
{
  up_ledon(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  PANIC();
#else
  if ((unsigned)irq < NR_IRQS)
    {
       uint32_t *savestate;

       /* Nested interrupts are not supported in this implementation.  If
        * you want to implement nested interrupts, you would have to (1)
        * change the way that current_regs is handled and (2) the design
        * associated with CONFIG_ARCH_INTERRUPTSTACK.  The savestate
        * variable will not work for that purpose as implemented here
        * because only the outermost nested interrupt can result in a
        * context switch (it can probably be deleted).
        */

       /* Current regs non-zero indicates that we are processing
        * an interrupt; current_regs is also used to manage
        * interrupt level context switches.
        */

       savestate    = (uint32_t*)current_regs;
       current_regs = regs;

       /* Mask and acknowledge the interrupt (if supported by the chip) */

#ifndef CONFIG_ARCH_NOINTC
       up_maskack_irq(irq);
#endif

       /* Deliver the IRQ */

       irq_dispatch(irq, regs);

       /* Get the current value of regs... it may have changed because
        * of a context switch performed during interrupt processing.
        */

       regs = current_regs;

       /* Restore the previous value of current_regs.  NULL would indicate that
        * we are no longer in an interrupt handler.  It will be non-NULL if we
        * are returning from a nested interrupt.
        */

       current_regs = savestate;

       /* Unmask the last interrupt (global interrupts are still
        * disabled.
        */

#ifndef CONFIG_ARCH_NOINTC
       up_enable_irq(irq);
#endif
    }
  up_ledoff(LED_INIRQ);
#endif
  return regs;
}
Esempio n. 17
0
void arm_timer_initialize(void)
{
#ifdef CHECK_INTERVAL
  lc823450_gpio_config(TIMER_PIN |
                       GPIO_MODE_OUTPUT |
                       GPIO_VALUE_ONE);
#endif

#ifdef CONFIG_HRT_TIMER
  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM2_CLKEN);
  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM2C_CLKEN);

  /* MTM2: unreset */

  modifyreg32(MRSTCNTEXT1, 0x0, MRSTCNTEXT1_MTM2_RSTB);

  /* Enable AEVT Interrupt */

  putreg32(1 << 0, rMT20TIER);

  /* Set prescaler to (1/10) */

  putreg32(10 - 1, rMT20PSCL);

  modifyreg32(MCLKCNTEXT1, MCLKCNTEXT1_MTM2C_CLKEN, 0);
  modifyreg32(MCLKCNTEXT1, MCLKCNTEXT1_MTM2_CLKEN, 0);

  (void)irq_attach(LC823450_IRQ_MTIMER20, (xcpt_t)hrt_interrupt, NULL);
  up_enable_irq(LC823450_IRQ_MTIMER20);

#endif /* CONFIG_HRT_TIMER */
#ifdef CONFIG_PROFILE

  /* MTM3: enable clocking */

  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM3_CLKEN);
  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM3C_CLKEN);

  /* MTM3: unreset */

  modifyreg32(MRSTCNTEXT1, 0x0, MRSTCNTEXT1_MTM3_RSTB);

  /* Input clock for the MTM3 is XT1 (i.e. 24M or 20M) */
  /* then the clock will be set to 1/10 by the internal divider */
  /* To implement 10ms timer, ADT=0, BDT=MTM_RELOAD */

  putreg32(0, rMT30A); /* AEVT counter */
  putreg32((XT1OSC_CLK / 1010) - 1, rMT30B); /* BEVT counter */

  /* Clear the counter by BEVT */

  putreg32(0x80, rMT30CTL);

  /* Set prescaler to 9 : (1/10) */

  putreg32(9, rMT30PSCL);

  /* Enable BEVT Interrupt */

  putreg32(1 << 1, rMT30TIER);

  /* Enable MTM3-Ch0 */

  putreg32(1, rMT30OPR);

  /* Attach the timer interrupt vector */

  (void)irq_attach(LC823450_IRQ_MTIMER30, (xcpt_t)up_proftimerisr, NULL);

  /* And enable the system timer interrupt */

  up_enable_irq(LC823450_IRQ_MTIMER30);

#endif /* CONFIG_PROFILE */

#ifdef CONFIG_LC823450_MTM0_TICK

  /* MTM0: enable clocking */

  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM0_CLKEN);
  modifyreg32(MCLKCNTEXT1, 0x0, MCLKCNTEXT1_MTM0C_CLKEN);

  /* MTM0: unreset */

  modifyreg32(MRSTCNTEXT1, 0x0, MRSTCNTEXT1_MTM0_RSTB);

  /* Input clock for the MTM0 is XT1 (i.e. 24M or 20M) */
  /* then the clock will be set to 1/10 by the internal divider */
  /* To implement the tick timer, ADT=0, BDT=MTM_RELOAD-1 */

  putreg32(0, rMT00A); /* AEVT counter */
  putreg32(MTM_RELOAD - 1, rMT00B); /* BEVT counter */

  /* Clear the counter by BEVT */

  putreg32(0x80, rMT00CTL);

  /* Set prescaler to 9 : (1/10) */

  putreg32(9, rMT00PSCL);

  /* Enable BEVT Interrupt */

  putreg32(1 << 1, rMT00TIER);

  /* Enable MTM0-Ch0 */

  putreg32(1, rMT00OPR);

  /* Attach the timer interrupt vector */

  (void)irq_attach(LC823450_IRQ_MTIMER00, (xcpt_t)up_timerisr, NULL);

  /* And enable the system timer interrupt */

  up_enable_irq(LC823450_IRQ_MTIMER00);
#else
  uint32_t regval;

  /* Set the SysTick interrupt to the default priority */

  regval = getreg32(NVIC_SYSH12_15_PRIORITY);
  regval &= ~NVIC_SYSH_PRIORITY_PR15_MASK;
  regval |= (NVIC_SYSH_PRIORITY_DEFAULT << NVIC_SYSH_PRIORITY_PR15_SHIFT);
  putreg32(regval, NVIC_SYSH12_15_PRIORITY);

  /* Make sure that the SYSTICK clock source is set correctly */

#if 0 /* Does not work.  Comes up with HCLK source and I can't change it */
  regval = getreg32(NVIC_SYSTICK_CTRL);
#if CONFIG_LC823450_SYSTICK_HCLKd8
  regval &= ~NVIC_SYSTICK_CTRL_CLKSOURCE;
#else
  regval |= NVIC_SYSTICK_CTRL_CLKSOURCE;
#endif
  putreg32(regval, NVIC_SYSTICK_CTRL);
#endif

  /* Configure SysTick to interrupt at the requested rate */

  putreg32(SYSTICK_RELOAD, NVIC_SYSTICK_RELOAD);

  /* Attach the timer interrupt vector */

  (void)irq_attach(LC823450_IRQ_SYSTICK, (xcpt_t)up_timerisr, NULL);

  /* Enable SysTick interrupts */

  putreg32((NVIC_SYSTICK_CTRL_CLKSOURCE |
            NVIC_SYSTICK_CTRL_TICKINT |
            NVIC_SYSTICK_CTRL_ENABLE),
            NVIC_SYSTICK_CTRL);

  /* And enable the timer interrupt */

  up_enable_irq(LC823450_IRQ_SYSTICK);
#endif

#ifdef CONFIG_DVFS
  /* attach timer interrupt handler */

  (void)irq_attach(LC823450_IRQ_MTIMER01, (xcpt_t)lc823450_dvfs_oneshot, NULL);

  /* enable MTM0-ch1 */

  up_enable_irq(LC823450_IRQ_MTIMER01);
#endif
}
void up_timer_initialize(void)
{
  uint32_t regval;

  /* Configure the SysTick clock source. This is only necessary if we are not
   * using the Cortex-M0 core clock as the frequency source.
   */

#ifndef CONFIG_NUC_SYSTICK_CORECLK

  /* This field is write protected and must be unlocked */

  nuc_unlock();

  /* Read the CLKSEL0 register and set the STCLK_S field appropriately */

  regval  = getreg32(NUC_CLK_CLKSEL0);
  regval &= ~CLK_CLKSEL0_STCLK_S_MASK;
#if defined(CONFIG_NUC_SYSTICK_XTALHI)
  regval |= CLK_CLKSEL0_STCLK_S_XTALHI;   /* High speed XTAL clock */
#elif defined(CONFIG_NUC_SYSTICK_XTALLO)
  regval |= CLK_CLKSEL0_STCLK_S_XTALLO;   /* Low speed XTAL clock */
#elif defined(CONFIG_NUC_SYSTICK_XTALHId2)
  regval |= CLK_CLKSEL0_STCLK_S_XTALDIV2; /* High speed XTAL clock/2 */
#elif defined(CONFIG_NUC_SYSTICK_HCLKd2)
  regval |= CLK_CLKSEL0_STCLK_S_HCLKDIV2; /* HCLK/2 */
#elif defined(CONFIG_NUC_SYSTICK_INTHId2)
  regval |= CLK_CLKSEL0_STCLK_S_INTDIV2;  /* Internal high speed clock/2 */
#endif
  putreg32(regval, NUC_CLK_CLKSEL0);

  /* Re-lock the register */

  nuc_lock();
#endif

  /* Set the SysTick interrupt to the default priority */

  regval = getreg32(ARMV6M_SYSCON_SHPR3);
  regval &= ~SYSCON_SHPR3_PRI_15_MASK;
  regval |= (NVIC_SYSH_PRIORITY_DEFAULT << SYSCON_SHPR3_PRI_15_SHIFT);
  putreg32(regval, ARMV6M_SYSCON_SHPR3);

  /* Configure SysTick to interrupt at the requested rate */

  putreg32(SYSTICK_RELOAD, ARMV6M_SYSTICK_RVR);

  /* Attach the timer interrupt vector */

  (void)irq_attach(NUC_IRQ_SYSTICK, (xcpt_t)up_timerisr);

  /* Enable SysTick interrupts.  We need to select the core clock here if
   * we are not using one of the alternative clock sources above.
   */

#ifdef CONFIG_NUC_SYSTICK_CORECLK
  putreg32((SYSTICK_CSR_CLKSOURCE | SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE),
           ARMV6M_SYSTICK_CSR);
#else
  putreg32((SYSTICK_CSR_TICKINT | SYSTICK_CSR_ENABLE), ARMV6M_SYSTICK_CSR);
#endif

  /* And enable the timer interrupt */

  up_enable_irq(NUC_IRQ_SYSTICK);
}
Esempio n. 19
0
void up_irqinitialize(void)
{
  uintptr_t regaddr;
  int nintlines;
  int i;

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports, defined in groups of 32. That is,
   * the total number of interrupt lines is up to (32*(INTLINESNUM+1)).
   *
   *  0 -> 32 interrupt lines, 1 enable register,   8 priority registers
   *  1 -> 64 "       " "   ", 2 enable registers, 16 priority registers
   *  2 -> 96 "       " "   ", 3 enable regsiters, 24 priority registers
   *  ...
   */

  nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1;

  /* Disable all interrupts.  There are nintlines interrupt enable
   * registers.
   */

  for (i = nintlines, regaddr = NVIC_IRQ0_31_ENABLE;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(0, regaddr);
    }

  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

#ifdef CONFIG_ARCH_RAMVECTORS
  up_ramvec_initialize();
#endif

#ifdef CONFIG_ARCH_CHIP_CC3200
  putreg32((uint32_t)CONFIG_RAM_START, NVIC_VECTAB);
#endif


  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* Now set all of the interrupt lines to the default priority.  There are
   * nintlines * 8 priority registers.
   */

  for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(DEFPRIORITY32, regaddr);
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Initialize support for GPIO interrupts if included in this build */

#ifndef CONFIG_TIVA_DISABLE_GPIO_IRQS
#ifdef CONFIG_HAVE_WEAKFUNCTIONS
  if (gpio_irqinitialize != NULL)
#endif
    {
      gpio_irqinitialize();
    }
#endif

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(TIVA_IRQ_SVCALL, up_svcall);
  irq_attach(TIVA_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(TIVA_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   tiva_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(TIVA_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(TIVA_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(TIVA_IRQ_NMI, tiva_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(TIVA_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(TIVA_IRQ_BUSFAULT, tiva_busfault);
  irq_attach(TIVA_IRQ_USAGEFAULT, tiva_usagefault);
  irq_attach(TIVA_IRQ_PENDSV, tiva_pendsv);
  irq_attach(TIVA_IRQ_DBGMONITOR, tiva_dbgmonitor);
  irq_attach(TIVA_IRQ_RESERVED, tiva_reserved);
#endif

  tiva_dumpnvic("initial", NR_IRQS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS

  /* And finally, enable interrupts */

  irqenable();
#endif
}
Esempio n. 20
0
void up_decodeirq(uint32_t* regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  lowsyslog("Unexpected IRQ\n");
  current_regs = regs;
  PANIC();
#else
  /* Decode the interrupt.  First, fetch the interrupt id register. */

  uint16_t irqentry = getreg16(DM320_INTC_IRQENTRY0);

  /* The irqentry value is an offset into a table.  Zero means no interrupt. */

  if (irqentry != 0)
    {
      /* If non-zero, then we can map the table offset into an IRQ number */

      int irq = (irqentry >> 2) - 1;

      /* Verify that the resulting IRQ number is valid */

      if ((unsigned)irq < NR_IRQS)
        {
          /* Mask and acknowledge the interrupt */

          up_maskack_irq(irq);

          /* Current regs non-zero indicates that we are processing an interrupt;
           * current_regs is also used to manage interrupt level context switches.
           *
           * Nested interrupts are not supported.
           */

          DEBUGASSERT(current_regs == NULL);
          current_regs = regs;

          /* Deliver the IRQ */

          irq_dispatch(irq, regs);

#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
          /* Check for a context switch.  If a context switch occurred, then
           * current_regs will have a different value than it did on entry.
           * If an interrupt level context switch has occurred, then restore
           * the floating point state and the establish the correct address
           * environment before returning from the interrupt.
           */

          if (regs != current_regs)
            {
#ifdef CONFIG_ARCH_FPU
              /* Restore floating point registers */

              up_restorefpu((uint32_t*)current_regs);
#endif

#ifdef CONFIG_ARCH_ADDRENV
              /* Make sure that the address environment for the previously
               * running task is closed down gracefully (data caches dump,
               * MMU flushed) and set up the address environment for the new
               * thread at the head of the ready-to-run list.
               */

              (void)group_addrenv(NULL);
#endif
            }
#endif

          /* Set current_regs to NULL to indicate that we are no longer in
           * an interrupt handler.
           */

          current_regs = NULL;

          /* Unmask the last interrupt (global interrupts are still
           * disabled).
           */

          up_enable_irq(irq);
        }
    }
Esempio n. 21
0
void up_irqinitialize(void)
{
  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);

  /* Set up the vector table address.
   *
   * If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

#if defined(CONFIG_ARCH_RAMVECTORS)
  up_ramvec_initialize();
#elif defined(CONFIG_STM32_DFU)
  putreg32((uint32_t)sam3u_vectors, NVIC_VECTAB);
#endif

  /* Set all interrrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  putreg32(DEFPRIORITY32, NVIC_IRQ0_3_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ12_15_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ16_19_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ20_23_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ24_27_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_IRQ28_31_PRIORITY);

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(SAM3U_IRQ_SVCALL, up_svcall);
  irq_attach(SAM3U_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(SAM3U_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   sam3u_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(SAM3U_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(SAM3U_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(SAM3U_IRQ_NMI, sam3u_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(SAM3U_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(SAM3U_IRQ_BUSFAULT, sam3u_busfault);
  irq_attach(SAM3U_IRQ_USAGEFAULT, sam3u_usagefault);
  irq_attach(SAM3U_IRQ_PENDSV, sam3u_pendsv);
  irq_attach(SAM3U_IRQ_DBGMONITOR, sam3u_dbgmonitor);
  irq_attach(SAM3U_IRQ_RESERVED, sam3u_reserved);
#endif

  sam3u_dumpnvic("initial", SAM3U_IRQ_NIRQS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS

  /* Initialize logic to support a second level of interrupt decoding for
   * GPIO pins.
   */
 
#ifdef CONFIG_GPIO_IRQ
  sam3u_gpioirqinitialize();
#endif

  /* And finally, enable interrupts */

  irqenable();
#endif
}
Esempio n. 22
0
void
Device::interrupt_enable()
{
	if (_irq_attached)
		up_enable_irq(_irq);
}
Esempio n. 23
0
void up_decodeirq(uint32_t* regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  lowsyslog("Unexpected IRQ\n");
  current_regs = regs;
  PANIC(OSERR_ERREXCEPTION);
#else
  uint32_t* savestate;
  uint32_t regval;
  int irq;

  /* Current regs non-zero indicates that we are processing an interrupt;
   * current_regs is also used to manage interrupt level context switches.
   */

  savestate    = (uint32_t*)current_regs;
  current_regs = regs;

  /* Loop while there are pending interrupts to be processed */

  do
    {
      /* Decode the interrupt.  First, fetch the NIVECSR register. */

      regval = getreg32(IMX_AITC_NIVECSR);

      /* The MS 16 bits of the NIVECSR register contains vector index for the
       * highest pending normal interrupt.
       */

      irq = regval >> AITC_NIVECSR_NIVECTOR_SHIFT;

      /* If irq < 64, then this is the IRQ.  If there is no pending interrupt,
       * then irq will be >= 64 (it will be 0xffff for illegal source).
       */

      if (irq < NR_IRQS)
        {
          /* Mask and acknowledge the interrupt */

          up_maskack_irq(irq);

          /* Deliver the IRQ */

          irq_dispatch(irq, regs);

          /* Unmask the last interrupt (global interrupts are still
           * disabled).
           */

          up_enable_irq(irq);
        }
    }
  while (irq < NR_IRQS);

  /* Restore the previous value of current_regs.  NULL would indicate that
   * we are no longer in an interrupt handler.  It will be non-NULL if we
   * are returning from a nested interrupt.
   */

  current_regs = savestate;
#endif
}
Esempio n. 24
0
void up_irqinitialize(void)
{
  uint32_t regaddr;
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 32)
  putreg32(0, NVIC_IRQ32_63_ENABLE);
#if NR_VECTORS >= (EFM32_IRQ_INTERRUPTS + 64)
  putreg32(0, NVIC_IRQ64_95_ENABLE);
#endif
#endif

#if defined(CONFIG_DEBUG_STACK) && CONFIG_ARCH_INTERRUPTSTACK > 3
  /* Colorize the interrupt stack for debug purposes */

  {
    size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3);
    up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size),
                   intstack_size);
  }
#endif

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(EFM32_IRQ_SVCALL, up_svcall);
  irq_attach(EFM32_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARMV7M_USEBASEPRI
   efm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(EFM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(EFM32_IRQ_NMI, efm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(EFM32_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(EFM32_IRQ_BUSFAULT, efm32_busfault);
  irq_attach(EFM32_IRQ_USAGEFAULT, efm32_usagefault);
  irq_attach(EFM32_IRQ_PENDSV, efm32_pendsv);
  irq_attach(EFM32_IRQ_DBGMONITOR, efm32_dbgmonitor);
  irq_attach(EFM32_IRQ_RESERVED, efm32_reserved);
#endif

  efm32_dumpnvic("initial", NR_VECTORS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS
#ifdef CONFIG_EFM32_GPIO_IRQ
  /* Initialize logic to support a second level of interrupt decoding for
   * GPIO pins.
   */

  efm32_gpioirqinitialize();
#endif

  /* And finally, enable interrupts */

  irqenable();
#endif
}
Esempio n. 25
0
void up_decodeirq(uint32_t* regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  lowsyslog(LOG_ERR, "Unexpected IRQ\n");
  current_regs = regs;
  PANIC();
#else
  uint32_t regval;
  int irq;

  /* Current regs non-zero indicates that we are processing an interrupt;
   * current_regs is also used to manage interrupt level context switches.
   *
   * Nested interrupts are not supported.
   */

  DEBUGASSERT(current_regs == NULL);
  current_regs = regs;

  /* Loop while there are pending interrupts to be processed */

  do
    {
      /* Decode the interrupt.  First, fetch the NIVECSR register. */

      regval = getreg32(IMX_AITC_NIVECSR);

      /* The MS 16 bits of the NIVECSR register contains vector index for the
       * highest pending normal interrupt.
       */

      irq = regval >> AITC_NIVECSR_NIVECTOR_SHIFT;

      /* If irq < 64, then this is the IRQ.  If there is no pending interrupt,
       * then irq will be >= 64 (it will be 0xffff for illegal source).
       */

      if (irq < NR_IRQS)
        {
          /* Mask and acknowledge the interrupt */

          up_maskack_irq(irq);

          /* Deliver the IRQ */

          irq_dispatch(irq, regs);

#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
          /* Check for a context switch.  If a context switch occurred, then
           * current_regs will have a different value than it did on entry.
           * If an interrupt level context switch has occurred, then restore
           * the floating point state and the establish the correct address
           * environment before returning from the interrupt.
           */

          if (regs != current_regs)
            {
#ifdef CONFIG_ARCH_FPU
              /* Restore floating point registers */

              up_restorefpu((uint32_t*)current_regs);
#endif

#ifdef CONFIG_ARCH_ADDRENV
              /* Make sure that the address environment for the previously
               * running task is closed down gracefully (data caches dump,
               * MMU flushed) and set up the address environment for the new
               * thread at the head of the ready-to-run list.
               */

              (void)group_addrenv(NULL);
#endif
            }
#endif
          /* Unmask the last interrupt (global interrupts are still
           * disabled).
           */

          up_enable_irq(irq);
        }
    }
  while (irq < NR_IRQS);

  /* Set current_regs to NULL to indicate that we are no longer in
   * an interrupt handler.
   */

  current_regs = NULL;
#endif
}
void up_irqinitialize(void)
{
  uint32_t regaddr;
#ifdef CONFIG_DEBUG
  uint32_t regval;
#endif
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);

  /* Make sure that we are using the correct vector table.  The default
   * vector address is 0x0000:0000 but if we are executing code that is
   * positioned in SRAM or in external FLASH, then we may need to reset
   * the interrupt vector so that it refers to the table in SRAM or in
   * external FLASH.
   *
   * If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

#ifdef CONFIG_ARCH_RAMVECTORS
  up_ramvec_initialize();
#else
  putreg32((uint32_t)_vectors, NVIC_VECTAB);
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(LPC43_IRQ_SVCALL, up_svcall);
  irq_attach(LPC43_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(LPC43_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   lpc43_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(LPC43_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(LPC43_IRQ_NMI, lpc43_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(LPC43_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(LPC43_IRQ_BUSFAULT, lpc43_busfault);
  irq_attach(LPC43_IRQ_USAGEFAULT, lpc43_usagefault);
  irq_attach(LPC43_IRQ_PENDSV, lpc43_pendsv);
  irq_attach(LPC43_IRQ_DBGMONITOR, lpc43_dbgmonitor);
  irq_attach(LPC43_IRQ_RESERVED, lpc43_reserved);
#endif

  lpc43_dumpnvic("initial", LPC43M4_IRQ_NIRQS);

  /* If a debugger is connected, try to prevent it from catching hardfaults.
   * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal
   * operation.
   */

#if defined(CONFIG_DEBUG) && !defined(CONFIG_ARMV7M_USEBASEPRI)
  regval  = getreg32(NVIC_DEMCR);
  regval &= ~NVIC_DEMCR_VCHARDERR;
  putreg32(regval, NVIC_DEMCR);
#endif

  /* And finally, enable interrupts */

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  irqenable();
#endif
}
Esempio n. 27
0
void up_irqinitialize(void)
{
  uintptr_t regaddr;
#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI)
  uint32_t regval;
#endif
  int nintlines;
  int i;

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports, defined in groups of 32. That is,
   * the total number of interrupt lines is up to (32*(INTLINESNUM+1)).
   *
   *  0 -> 32 interrupt lines, 1 enable register,   8 priority registers
   *  1 -> 64 "       " "   ", 2 enable registers, 16 priority registers
   *  2 -> 96 "       " "   ", 3 enable regsiters, 24 priority registers
   *  ...
   */

  nintlines = (getreg32(NVIC_ICTR) & NVIC_ICTR_INTLINESNUM_MASK) + 1;

  /* Disable all interrupts.  There are nintlines interrupt enable
   * registers.
   */

  for (i = nintlines, regaddr = NVIC_IRQ0_31_CLEAR;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(0xffffffff, regaddr);
    }

  /* Make sure that we are using the correct vector table.  The default
   * vector address is 0x0000:0000 but if we are executing code that is
   * positioned in SRAM or in external FLASH, then we may need to reset
   * the interrupt vector so that it refers to the table in SRAM or in
   * external FLASH.
   */

  putreg32((uint32_t)_vectors, NVIC_VECTAB);

#ifdef CONFIG_ARCH_RAMVECTORS
  /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
   * vector table that requires special initialization.
   */

  up_ramvec_initialize();
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* Now set all of the interrupt lines to the default priority.  There are
   * nintlines * 8 priority registers.
   */

  for (i = (nintlines << 3), regaddr = NVIC_IRQ0_3_PRIORITY;
       i > 0;
       i--, regaddr += 4)
    {
      putreg32(DEFPRIORITY32, regaddr);
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  CURRENT_REGS = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(STM32_IRQ_SVCALL, up_svcall, NULL);
  irq_attach(STM32_IRQ_HARDFAULT, up_hardfault, NULL);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
  /* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
  stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARM_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault, NULL);
  up_enable_irq(STM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG_FEATURES
  irq_attach(STM32_IRQ_NMI, stm32_nmi, NULL);
#ifndef CONFIG_ARM_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault, NULL);
#endif
  irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault, NULL);
  irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault, NULL);
  irq_attach(STM32_IRQ_PENDSV, stm32_pendsv, NULL);
  irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor, NULL);
  irq_attach(STM32_IRQ_RESERVED, stm32_reserved, NULL);
#endif

  stm32_dumpnvic("initial", STM32_IRQ_NIRQS);

  /* If a debugger is connected, try to prevent it from catching hardfaults.
   * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal
   * operation.
   */

#if defined(CONFIG_DEBUG_SYMBOLS) && !defined(CONFIG_ARMV7M_USEBASEPRI)
  regval  = getreg32(NVIC_DEMCR);
  regval &= ~NVIC_DEMCR_VCHARDERR;
  putreg32(regval, NVIC_DEMCR);
#endif

#ifndef CONFIG_SUPPRESS_INTERRUPTS
  /* Initialize logic to support a second level of interrupt decoding for
   * GPIO pins.
   */

#ifdef CONFIG_STM32H7_GPIO_IRQ
  stm32_gpioirqinitialize();
#endif

  /* And finally, enable interrupts */

  up_irq_enable();
#endif
}
Esempio n. 28
0
static int pic32mx_cninterrupt(int irq, FAR void *context)
{
  int status;
  int ret = OK;
  int i;

  /* Call all attached handlers */

  for (i = 0; i < IOPORT_NUMCN; i++)
    {
      /* Is this one attached */

      if (g_cnisrs[i])
        {
          /* Call the attached handler */

          status = g_cnisrs[i](irq, context);

          /* Keep track of the status of the last handler that failed */

          if (status < 0)
            {
              ret = status;
            }
    }

  /* Clear the pending interrupt */

  up_clrpend_irq(PIC32MX_IRQ_CN);
  return ret;
}

/****************************************************************************
 * Public Functions
 ****************************************************************************/

/****************************************************************************
 * Name: pic32mx_gpioirqinitialize
 *
 * Description:
 *   Initialize logic to support a GPIO change notification interrupts.
 *   This function is called internally by the system on power up and should
 *   not be called again.
 *
 ****************************************************************************/

void pic32mx_gpioirqinitialize(void)
{
  int ret;

  /* Attach the change notice interrupt handler */

  ret = irqattach(PIC32MX_IRQ_CN, pic32mx_cninterrupt);
  DEBUGASSERT(ret == OK);

  /* Set the interrupt priority */

#ifdef CONFIG_ARCH_IRQPRIO
  ret = up_prioritize_irq(PIC32MX_IRQ_CN, CONFIG_PIC32MX_CNPRIO);
  DEBUGASSERT(ret == OK);
#endif

  /* Reset all registers and enable the CN module */

  putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNENCLR);
  putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNPUECLR);
  putreg32(IOPORT_CNCON_ON, PIC32MX_IOPORT_CNCON);

  /* And enable the GPIO interrupt */

  ret = up_enable_irq(PIC32MX_IRQSRC_CN);
  DEBUGASSERT(ret == OK);
}
Esempio n. 29
0
void up_irqinitialize(void)
{
  uint32_t regaddr;
  int num_priority_registers;

  /* Disable all interrupts */

  putreg32(0, NVIC_IRQ0_31_ENABLE);
  putreg32(0, NVIC_IRQ32_63_ENABLE);

  /* The standard location for the vector table is at the beginning of FLASH
   * at address 0x0800:0000.  If we are using the STMicro DFU bootloader, then
   * the vector table will be offset to a different location in FLASH and we
   * will need to set the NVIC vector location to this alternative location.
   */

#ifdef CONFIG_STM32_DFU
  putreg32((uint32_t)stm32_vectors, NVIC_VECTAB);
#endif

  /* Set all interrupts (and exceptions) to the default priority */

  putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
  putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);

  /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
   * lines that the NVIC supports:
   *
   *  0 -> 32 interrupt lines,  8 priority registers
   *  1 -> 64 "       " "   ", 16 priority registers
   *  2 -> 96 "       " "   ", 32 priority registers
   *  ...
   */

  num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;

  /* Now set all of the interrupt lines to the default priority */

  regaddr = NVIC_IRQ0_3_PRIORITY;
  while (num_priority_registers--)
    {
      putreg32(DEFPRIORITY32, regaddr);
      regaddr += 4;
    }

  /* currents_regs is non-NULL only while processing an interrupt */

  current_regs = NULL;

  /* Attach the SVCall and Hard Fault exception handlers.  The SVCall
   * exception is used for performing context switches; The Hard Fault
   * must also be caught because a SVCall may show up as a Hard Fault
   * under certain conditions.
   */

  irq_attach(STM32_IRQ_SVCALL, up_svcall);
  irq_attach(STM32_IRQ_HARDFAULT, up_hardfault);

  /* Set the priority of the SVCall interrupt */

#ifdef CONFIG_ARCH_IRQPRIO
/* up_prioritize_irq(STM32_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
#endif
#ifdef CONFIG_ARMV7M_USEBASEPRI
   stm32_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
#endif

  /* If the MPU is enabled, then attach and enable the Memory Management
   * Fault handler.
   */

#ifdef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
  up_enable_irq(STM32_IRQ_MEMFAULT);
#endif

  /* Attach all other processor exceptions (except reset and sys tick) */

#ifdef CONFIG_DEBUG
  irq_attach(STM32_IRQ_NMI, stm32_nmi);
#ifndef CONFIG_ARMV7M_MPU
  irq_attach(STM32_IRQ_MEMFAULT, up_memfault);
#endif
  irq_attach(STM32_IRQ_BUSFAULT, stm32_busfault);
  irq_attach(STM32_IRQ_USAGEFAULT, stm32_usagefault);
  irq_attach(STM32_IRQ_PENDSV, stm32_pendsv);
  irq_attach(STM32_IRQ_DBGMONITOR, stm32_dbgmonitor);
  irq_attach(STM32_IRQ_RESERVED, stm32_reserved);
#endif

  stm32_dumpnvic("initial", NR_IRQS);

#ifndef CONFIG_SUPPRESS_INTERRUPTS

  /* And finally, enable interrupts */

  irqenable();
#endif
}
void up_decodeirq(uint32_t *regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
    lowsyslog("Unexpected IRQ\n");
    current_regs = regs;
    PANIC();
#else
    int index;
    int irq;

    /* Read the IRQ vector status register.  Bits 3-10 provide the IRQ number
     * of the interrupt (the TABLE_ADDR was initialized to zero, so the
     * following masking should be unnecessary)
     */

    index = getreg32(LPC31_INTC_VECTOR0) & INTC_VECTOR_INDEX_MASK;
    if (index != 0)
    {
        /* Shift the index so that the range of IRQ numbers are in bits 0-7 (values
         * 1-127) and back off the IRQ number by 1 so that the numbering is zero-based
         */

        irq = (index >> INTC_VECTOR_INDEX_SHIFT) -1;

        /* Verify that the resulting IRQ number is valid */

        if ((unsigned)irq < NR_IRQS)
        {
            /* Mask and acknowledge the interrupt */

            up_maskack_irq(irq);

            /* Current regs non-zero indicates that we are processing an interrupt;
             * current_regs is also used to manage interrupt level context switches.
             *
             * Nested interrupts are not supported.
             */

            DEBUGASSERT(current_regs == NULL);
            current_regs = regs;

            /* Deliver the IRQ */

            irq_dispatch(irq, regs);

#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
            /* Check for a context switch.  If a context switch occurred, then
             * current_regs will have a different value than it did on entry.
             * If an interrupt level context switch has occurred, then restore
             * the floating point state and the establish the correct address
             * environment before returning from the interrupt.
             */

            if (regs != current_regs)
            {
#ifdef CONFIG_ARCH_FPU
                /* Restore floating point registers */

                up_restorefpu((uint32_t*)current_regs);
#endif

#ifdef CONFIG_ARCH_ADDRENV
                /* Make sure that the address environment for the previously
                 * running task is closed down gracefully (data caches dump,
                 * MMU flushed) and set up the address environment for the new
                 * thread at the head of the ready-to-run list.
                 */

                (void)group_addrenv(NULL);
#endif
            }
#endif
            /* Set current_regs to NULL to indicate that we are no longer in an
             * interrupt handler.
             */

            current_regs = NULL;

            /* Unmask the last interrupt (global interrupts are still
             * disabled).
             */

            up_enable_irq(irq);
        }
    }