/* * 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); }
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; }
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); }
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; }
/**************************************************************************** * 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; }
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); }
/** * 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; }
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 over@ 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(); }
// 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; }
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 }
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 }
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"); }
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 }
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 }
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 }
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; }
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); }
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 }
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); } }
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 }
void Device::interrupt_enable() { if (_irq_attached) up_enable_irq(_irq); }
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 }
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 }
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 }
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 }
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); }
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); } }