void sam_gclk_config(FAR const struct sam_gclkconfig_s *config) { irqstate_t flags; uintptr_t regaddr; uint32_t regval; uint32_t genctrl; /* Select the requested source clock for the generator */ genctrl = ((uint32_t)config->clksrc << GCLK_GENCTRL_SRC_SHIFT); #if 0 /* Not yet supported */ /* Configure the clock to be either high or low when disabled */ if (config->level) { genctrl |= GCLK_GENCTRL_OOV; } #endif /* Configure if the clock output to I/O pin should be enabled */ if (config->output) { genctrl |= GCLK_GENCTRL_OE; } /* Set the prescaler division factor */ if (config->prescaler > 1) { /* Check if division is a power of two */ if (((config->prescaler & (config->prescaler - 1)) == 0)) { /* Determine the index of the highest bit set to get the * division factor that must be loaded into the division * register. */ uint32_t count = 0; uint32_t mask; for (mask = 2; mask < (uint32_t)config->prescaler; mask <<= 1) { count++; } /* Set binary divider power of 2 division factor */ genctrl |= count << GCLK_GENCTRL_DIV_SHIFT; genctrl |= GCLK_GENCTRL_DIVSEL; } else { /* Set integer division factor */ genctrl |= GCLK_GENCTRL_DIV((uint32_t)config->prescaler); /* Enable non-binary division with increased duty cycle accuracy */ genctrl |= GCLK_GENCTRL_IDC; } } /* Enable or disable the clock in standby mode */ if (config->runstandby) { genctrl |= GCLK_GENCTRL_RUNSTDBY; } /* Wait for synchronization */ sam_gclck_waitsyncbusy(config->gclk); /* Preserve the GENEN bit */ regaddr = SAM_GCLK_GENCTRL(config->gclk); flags = enter_critical_section(); regval = getreg32(regaddr); regval &= GCLK_GENCTRL_GENEN; genctrl |= regval; /* Configure the generator */ putreg32(genctrl, regaddr); /* Wait for synchronization */ sam_gclck_waitsyncbusy(config->gclk); leave_critical_section(flags); sam_gclck_waitsyncbusy(config->gclk); /* Enable the clock generator */ flags = enter_critical_section(); genctrl |= GCLK_GENCTRL_GENEN; putreg32(genctrl, regaddr); /* Wait for synchronization */ sam_gclck_waitsyncbusy(config->gclk); leave_critical_section(flags); }
static void lpc31_domaininit(struct lpc31_domainconfig_s* dmn) { const struct lpc31_subdomainconfig_s * sub = dmn->sub; uint32_t fdivcfg; uint32_t regaddr; uint32_t regval; int fdndx; int clkndx; int bcrndx = lpc31_bcrndx(dmn->dmnid); int esrndx; if (bcrndx != BCRNDX_INVALID) { /* Disable BCR for domain */ regaddr = LPC31_CGU_BCR(bcrndx); putreg32(0, regaddr); } /* Configure the fractional dividers in this domain */ for (fdndx = 0; fdndx < dmn->nfdiv; fdndx++, sub++) { /* Set fractional divider confiruation but don't enable it yet */ fdivcfg = lpc31_fdivinit(fdndx + dmn->fdiv1, &sub->fdiv, false); /* Enable frac divider only if it has valid settings */ if (fdivcfg != 0) { /* Select the fractional dividir for each clock in this * sub domain. */ for (clkndx = 0; clkndx <= dmn->nclks; clkndx++) { /* Does this clock have an ESR register? */ esrndx = lpc31_esrndx((enum lpc31_clockid_e)(clkndx + dmn->clk1)); if (esrndx != ESRNDX_INVALID) { /* Yes.. Check if this clock belongs to this sub-domain */ if (sub->clkset & (1 << clkndx)) { /* Yes.. configure the clock to use this fractional divider */ regaddr = LPC31_CGU_ESR(esrndx); putreg32((fdndx << CGU_ESR_ESRSEL_SHIFT) | CGU_ESR_ESREN, regaddr); } } } /* Enable the fractional divider */ regaddr = LPC31_CGU_FDC(fdndx + dmn->fdiv1); regval = getreg32(regaddr); regval |= CGU_FDC_RUN; putreg32(regval, regaddr); } } if (bcrndx != BCRNDX_INVALID) { /* Enable the BCR for domain */ regaddr = LPC31_CGU_BCR(bcrndx); putreg32(CGU_BCR_FDRUN, regaddr); } /* Select input base clock for domain*/ lpc31_selectfreqin(dmn->dmnid, dmn->finsel); }
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. */ 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); /* 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_ARM_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_ARM_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 up_irq_enable(); #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 board_deepsleep_with_stopmode(uint32_t secs) { #if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME) struct tm t; struct timespec ts; struct timespec rtc_start_ts; struct timespec rtc_end_ts; #endif #ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS uint32_t gpio_off_mask; bool sdcard_enabled; #endif uint32_t regval; int ret; #ifdef DEEPSLEEP_WAKETIME_DEBUG static struct timespec wake_ts; #endif #ifdef DEEPSLEEP_SLEEPTIME_DEBUG bool slept = false; #endif /* Do not allow other tasks to takeover (for example, by wake-up with semaphore * from EXTI interrupt) before we have restored MCU functionalities. */ sched_lock(); #ifdef DEEPSLEEP_SLEEPTIME_DEBUG lldbg("sleep for %d\n", secs); #endif #ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS /* Special support for SDcard. */ if (stm32_gpioread(GPIO_CHIP_SELECT_SDCARD) == false) { lldbg("ERROR! SDcard communication active while trying deep-sleep!\n"); goto skip_deepsleep; } /* Following devices do not have proper GPIO reconfigure recovery yet (and * some cannot work with deep-sleep at all). Abort deep-sleep instead of * introducing hard-to-diagnose bugs and general instability. */ if (stm32_gpioread(GPIO_REGULATOR_WLAN)) { lldbg("ERROR! Trying to deep-sleep when WLAN active!\n"); goto skip_deepsleep; } if (stm32_gpioread(GPIO_PWR_SWITCH_MODEM)) { lldbg("ERROR! Trying to deep-sleep when Modem active!\n"); goto skip_deepsleep; } if (stm32_gpioread(GPIO_REGULATOR_GPS)) { lldbg("ERROR! Trying to deep-sleep when GPS active!\n"); goto skip_deepsleep; } if (stm32_gpioread(GPIO_REGULATOR_BLUETOOTH)) { lldbg("ERROR! Trying to deep-sleep when Bluetooth active!\n"); goto skip_deepsleep; } if (stm32_gpioread(GPIO_REGULATOR_DISPLAY)) { lldbg("ERROR! Trying to deep-sleep when Display active!\n"); goto skip_deepsleep; } #endif /* CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS */ #if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME) /* Get RTC clock before STOP. */ stm32_rtc_getdatetime_with_subseconds(&t, &rtc_start_ts.tv_nsec); rtc_start_ts.tv_sec = mktime(&t); /* Get current time. */ ret = clock_gettime(CLOCK_REALTIME, &ts); DEBUGASSERT(ret != ERROR); /* Add nanoseconds to entropy pool. */ add_time_randomness(ts.tv_nsec); #endif #ifdef DEEPSLEEP_WAKETIME_DEBUG if (wake_ts.tv_nsec || wake_ts.tv_sec) { struct timespec curr_ts; int64_t msecs; clock_gettime(CLOCK_REALTIME, &curr_ts); msecs = ((int64_t)curr_ts.tv_sec - wake_ts.tv_sec) * 1000; msecs += ((int64_t)curr_ts.tv_nsec - wake_ts.tv_nsec) / (1000 * 1000); lldbg("sleep to sleep time: %d msecs\n", (int)msecs); } else { lldbg("first sleep (for %u secs)\n", secs); } #endif #ifdef CONFIG_RTC_PERIODIC_AUTORELOAD_WAKEUP if (secs > 0) { /* Prepare RTC for wake-up. */ ret = up_rtc_setperiodicwakeup(secs, NULL); DEBUGASSERT(ret == OK); } #else DEBUGASSERT(secs == 0); #endif /* Prevent USART interrupt activity, make sure that last transmission has * completed. */ stm32_serial_set_suspend(true); #ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS /* Read control state of SDCard regulator (TODO: add proper pwrctl api) */ sdcard_enabled = stm32_gpioread(GPIO_REGULATOR_SDCARD); if (sdcard_enabled) { /* Mark SDcard as disconnected for block driver. */ mmcsd_slot_pm_suspend(CONFIG_BOARD_MMCSDSLOTNO); } /* Force SDcard off. */ stm32_gpiowrite(GPIO_REGULATOR_SDCARD, false); /* SDcard is off, and does not react on GPIOs. Force GPIOs low to avoid leak * current. */ gpio_off_mask = ~(GPIO_PUPD_MASK | GPIO_MODE_MASK | GPIO_OUTPUT_SET); stm32_configgpio((GPIO_SPI3_MOSI & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT); stm32_configgpio((GPIO_SPI3_MISO & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT); stm32_configgpio((GPIO_SPI3_SCK & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT); stm32_configgpio((GPIO_CHIP_SELECT_SDCARD & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT); /* Reconfigure GPIO's for stop mode (most pins are setup as analog input). */ up_reconfigure_gpios_for_pmstop(); #endif #if defined(CONFIG_USBDEV) && defined (CONFIG_STM32_USB) /* Reset USB peripheral */ regval = getreg32(STM32_RCC_APB1RSTR); putreg32(regval | RCC_APB1RSTR_USBRST, STM32_RCC_APB1RSTR); putreg32(regval, STM32_RCC_APB1RSTR); #endif #if defined(CONFIG_STM32_PWR) /* Disable PVD during sleep because I_DD (PVD/BOR) consumes 2.6 uA, and because there is nothing better to do than die while sleeping if lose power in stop-mode. */ stm32_pwr_disablepvd(); #endif #ifndef CONFIG_BOARD_DEEPSLEEP_SKIP_PMSTOP /* Enter stop-mode with MCU internal regulator in low-power mode. */ ret = stm32_pmstop(true); #endif #ifdef DEEPSLEEP_SLEEPTIME_DEBUG slept = true; #endif #if defined(CONFIG_STM32_PWR) /* Re-enable PVD and check if voltage has dropped too much while we slept. We might have enough power for MCU, but not for SD card or other peripherals. */ stm32_pwr_enablepvd(); board_pwr_checkpvd(); #endif #ifdef CONFIG_RTC_PERIODIC_AUTORELOAD_WAKEUP if (secs > 0) { /* Prevent more wake-ups. */ (void)up_rtc_cancelperiodicwakeup(); } #endif #if defined(CONFIG_RTC) && defined(CONFIG_RTC_DATETIME) /* Get RTC clock after STOP. */ stm32_rtc_getdatetime_with_subseconds(&t, &rtc_end_ts.tv_nsec); rtc_end_ts.tv_sec = mktime(&t); /* Advance time by RTC. */ ts.tv_sec += rtc_end_ts.tv_sec - rtc_start_ts.tv_sec; ts.tv_nsec += rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec; if (ts.tv_nsec < 0) { ts.tv_nsec += 1000 * 1000 * 1000; ts.tv_sec--; } if (ts.tv_nsec >= 1000 * 1000 * 1000) { ts.tv_nsec -= 1000 * 1000 * 1000; ts.tv_sec++; } /* Set current time / date */ ret = clock_settime(CLOCK_REALTIME, &ts); DEBUGASSERT(ret != ERROR); #ifdef DEEPSLEEP_WAKETIME_DEBUG wake_ts = ts; #endif #if defined(CONFIG_CLOCK_MONOTONIC) && defined(CONFIG_CLOCK_MONOTONIC_OFFSET_TIME) /* Get amount of time adjusted by RTC. */ ts.tv_sec = rtc_end_ts.tv_sec - rtc_start_ts.tv_sec; ts.tv_nsec = rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec; if (ts.tv_nsec < 0) { ts.tv_nsec += 1000 * 1000 * 1000; ts.tv_sec--; } if (ts.tv_nsec >= 1000 * 1000 * 1000) { ts.tv_nsec -= 1000 * 1000 * 1000; ts.tv_sec++; } /* Adjust CLOCK_MONOTONIC offset. */ clock_increase_monotonic_offset(&ts); #endif #endif /* Stop mode disables HSE/HSI/PLL and wake happens with default system * clock (MSI, 2Mhz). So reconfigure clocks early on. RTC is however * handled before this for accurate time keeping. */ stm32_clockconfig(); #ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS /* Restore pin configuration */ up_restore_gpios_after_pmstop(); #endif #if defined(CONFIG_USBDEV) && defined (CONFIG_STM32_USB) /* Initialize USB */ /* TODO initialize USB properly, up_usbinitialize() call alone is not sufficient */ up_usbinitialize(); #endif /* Resume serial ports after setting up system clock, as USART baud rate is * configured relative to system clock. */ stm32_serial_set_suspend(false); /* Check that we have enough battery left, just in case PVD detection missed it. */ board_pwr_checkvbat(false); #ifdef CONFIG_BOARD_DEEPSLEEP_RECONFIGURE_GPIOS /* Special support for SD card. */ /* Restore SDcard GPIOs */ stm32_configgpio(GPIO_SPI3_MOSI); stm32_configgpio(GPIO_SPI3_MISO); stm32_configgpio(GPIO_SPI3_SCK); stm32_configgpio(GPIO_CHIP_SELECT_SDCARD); if (sdcard_enabled) { /* Re-enable power now that GPIOs are in correct state. */ stm32_gpiowrite(GPIO_REGULATOR_SDCARD, true); /* Mark SDcard as reconnected for block driver, will reinitialize/reconfigure * SDcard. Apparently, block driver works fine without additional delay * for regulator. Might be because plug-in nature of SDcards require * block driver to keep retrying initialization until card stabilizes. */ mmcsd_slot_pm_resume(CONFIG_BOARD_MMCSDSLOTNO); } skip_deepsleep: #endif /* Allow scheduler to switch tasks. */ sched_unlock(); #ifdef DEEPSLEEP_SLEEPTIME_DEBUG if (slept) { /* Get amount of time adjusted by RTC. */ ts.tv_sec = rtc_end_ts.tv_sec - rtc_start_ts.tv_sec; ts.tv_nsec = rtc_end_ts.tv_nsec - rtc_start_ts.tv_nsec; if (ts.tv_nsec < 0) { ts.tv_nsec += 1000 * 1000 * 1000; ts.tv_sec--; } if (ts.tv_nsec >= 1000 * 1000 * 1000) { ts.tv_nsec -= 1000 * 1000 * 1000; ts.tv_sec++; } lldbg("slept for %u.%03u\n", ts.tv_sec, ts.tv_nsec / (1000 * 1000)); } #endif }
static inline void rcc_enableapb1(void) { uint32_t regval; /* Set the appropriate bits in the APB1ENR register to enabled the * selected APB1 peripherals. */ regval = getreg32(STM32_RCC_APB1ENR); #ifdef CONFIG_STM32_TIM2 /* Timer 2 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM2EN; #endif #endif #ifdef CONFIG_STM32_TIM3 /* Timer 3 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM3EN; #endif #endif #ifdef CONFIG_STM32_TIM6 /* Timer 6 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM6EN; #endif #endif #ifdef CONFIG_STM32_TIM7 /* Timer 7 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM7EN; #endif #endif #ifdef CONFIG_STM32_WWDG /* Window Watchdog clock enable */ regval |= RCC_APB1ENR_WWDGEN; #endif #ifdef CONFIG_STM32_USART2 /* USART 2 clock enable */ regval |= RCC_APB1ENR_USART2EN; #endif #ifdef CONFIG_STM32_USART3 /* USART 3 clock enable */ regval |= RCC_APB1ENR_USART3EN; #endif #ifdef CONFIG_STM32_I2C1 /* I2C 1 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_I2C1EN; #endif #endif #ifdef CONFIG_STM32_CAN1 /* CAN1 clock enable */ regval |= RCC_APB1ENR_CANEN; #endif #ifdef CONFIG_STM32_DAC2 /* DAC2 interface clock enable */ regval |= RCC_APB1ENR_DAC2EN; #endif #ifdef CONFIG_STM32_PWR /* Power interface clock enable */ regval |= RCC_APB1ENR_PWREN; #endif #ifdef CONFIG_STM32_DAC1 /* DAC1 interface clock enable */ regval |= RCC_APB1ENR_DAC1EN; #endif putreg32(regval, STM32_RCC_APB1ENR); }
static void stm32_stdclockconfig(void) { uint32_t regval; /* If the PLL is using the HSE, or the HSE is the system clock */ #if (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) || (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) { volatile int32_t timeout; /* Enable External High-Speed Clock (HSE) */ regval = getreg32(STM32_RCC_CR); regval &= ~RCC_CR_HSEBYP; /* Disable HSE clock bypass */ regval |= RCC_CR_HSEON; /* Enable HSE */ putreg32(regval, STM32_RCC_CR); /* Wait until the HSE is ready (or until a timeout elapsed) */ for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) { /* Check if the HSERDY flag is the set in the CR */ if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) { /* If so, then break-out with timeout > 0 */ break; } } if (timeout == 0) { /* In the case of a timeout starting the HSE, we really don't have a * strategy. This is almost always a hardware failure or * misconfiguration. */ return; } } #endif /* Set the HCLK source/divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_HPRE_MASK; regval |= STM32_RCC_CFGR_HPRE; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK2 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE2_MASK; regval |= STM32_RCC_CFGR_PPRE2; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK1 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE1_MASK; regval |= STM32_RCC_CFGR_PPRE1; putreg32(regval, STM32_RCC_CFGR); #if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL /* If we are using the PLL, configure and start it */ /* Set the PLL divider and multiplier */ regval = getreg32(STM32_RCC_CFGR); regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK); regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLXTPRE | STM32_CFGR_PLLMUL); putreg32(regval, STM32_RCC_CFGR); /* Enable the PLL */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLLON; putreg32(regval, STM32_RCC_CR); /* Wait until the PLL is ready */ while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); #endif /* Set flash wait states according to sysclk: * * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ regval = getreg32(STM32_FLASH_ACR); regval &= ~(FLASH_ACR_LATENCY_MASK); #if STM32_SYSCLK_FREQUENCY <= 24000000 regval |= FLASH_ACR_LATENCY_0; #elif STM32_SYSCLK_FREQUENCY <= 48000000 regval |= FLASH_ACR_LATENCY_1; #else regval |= FLASH_ACR_LATENCY_2; #endif regval |= FLASH_ACR_PRTFBE; putreg32(regval, STM32_FLASH_ACR); /* Select the system clock source (probably the PLL) */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_SW_MASK; regval |= STM32_SYSCLK_SW; putreg32(regval, STM32_RCC_CFGR); /* Wait until the selected source is used as the system clock source */ while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); #if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) /* Low speed internal clock source LSI * * TODO: There is another case where the LSI needs to * be enabled: if the MCO pin selects LSI as source. */ stm32_rcc_enablelsi(); #endif #if defined(CONFIG_RTC_LSECLOCK) /* Low speed external clock source LSE * * TODO: There is another case where the LSE needs to * be enabled: if the MCO pin selects LSE as source. * * TODO: There is another case where the LSE needs to * be enabled: if USARTx selects LSE as source. */ stm32_rcc_enablelse(); #endif #ifdef CONFIG_STM32_HRTIM_CLK_FROM_PLL regval = getreg32(STM32_RCC_CFGR3); regval |= RCC_CFGR3_HRTIM1SW; putreg32(regval, STM32_RCC_CFGR3); #endif }
static inline void rcc_enableahb1(void) { uint32_t regval; /* Set the appropriate bits in the AHB1ENR register to enabled the * selected AHB1 peripherals. */ regval = getreg32(STM32_RCC_AHB1ENR); /* Enable GPIOA, GPIOB, .... GPIOI*/ #if STM32_NGPIO > 0 regval |= (RCC_AHB1ENR_GPIOAEN #if STM32_NGPIO > 16 |RCC_AHB1ENR_GPIOBEN #endif #if STM32_NGPIO > 32 |RCC_AHB1ENR_GPIOCEN #endif #if STM32_NGPIO > 48 |RCC_AHB1ENR_GPIODEN #endif #if STM32_NGPIO > 64 |RCC_AHB1ENR_GPIOEEN #endif #if STM32_NGPIO > 80 |RCC_AHB1ENR_GPIOFEN #endif #if STM32_NGPIO > 96 |RCC_AHB1ENR_GPIOGEN #endif #if STM32_NGPIO > 112 |RCC_AHB1ENR_GPIOHEN #endif #if STM32_NGPIO > 128 |RCC_AHB1ENR_GPIOIEN #endif ); #endif #ifdef CONFIG_STM32_CRC /* CRC clock enable */ regval |= RCC_AHB1ENR_CRCEN; #endif #ifdef CONFIG_STM32_BKPSRAM /* Backup SRAM clock enable */ regval |= RCC_AHB1ENR_BKPSRAMEN; #endif #ifdef CONFIG_STM32_DMA1 /* DMA 1 clock enable */ regval |= RCC_AHB1ENR_DMA1EN; #endif #ifdef CONFIG_STM32_DMA2 /* DMA 2 clock enable */ regval |= RCC_AHB1ENR_DMA2EN; #endif #ifdef CONFIG_STM32_ETHMAC /* Ethernet MAC clocking */ regval |= (RCC_AHB1ENR_ETHMACEN|RCC_AHB1ENR_ETHMACTXEN|RCC_AHB1ENR_ETHMACRXEN); #ifdef CONFIG_STM32_ETH_PTP /* Precision Time Protocol (PTP) */ regval |= RCC_AHB1ENR_ETHMACPTPEN; #endif #endif #ifdef CONFIG_STM32_OTGHS /* USB OTG HS */ regval |= (RCC_AHB1ENR_OTGHSEN|RCC_AHB1ENR_OTGHSULPIEN); #endif putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ }
static inline void rcc_enableapb1(void) { uint32_t regval; /* Set the appropriate bits in the APB1ENR register to enabled the * selected APB1 peripherals. */ regval = getreg32(STM32_RCC_APB1ENR); #ifdef CONFIG_STM32_TIM2 /* TIM2 clock enable */ regval |= RCC_APB1ENR_TIM2EN; #endif #ifdef CONFIG_STM32_TIM3 /* TIM3 clock enable */ regval |= RCC_APB1ENR_TIM3EN; #endif #ifdef CONFIG_STM32_TIM4 /* TIM4 clock enable */ regval |= RCC_APB1ENR_TIM4EN; #endif #ifdef CONFIG_STM32_TIM5 /* TIM5 clock enable */ regval |= RCC_APB1ENR_TIM5EN; #endif #ifdef CONFIG_STM32_TIM6 /* TIM6 clock enable */ regval |= RCC_APB1ENR_TIM6EN; #endif #ifdef CONFIG_STM32_TIM7 /* TIM7 clock enable */ regval |= RCC_APB1ENR_TIM7EN; #endif #ifdef CONFIG_STM32_TIM12 /* TIM12 clock enable */ regval |= RCC_APB1ENR_TIM12EN; #endif #ifdef CONFIG_STM32_TIM13 /* TIM13 clock enable */ regval |= RCC_APB1ENR_TIM13EN; #endif #ifdef CONFIG_STM32_TIM14 /* TIM14 clock enable */ regval |= RCC_APB1ENR_TIM14EN; #endif #ifdef CONFIG_STM32_WWDG /* Window watchdog clock enable */ regval |= RCC_APB1ENR_WWDGEN; #endif #ifdef CONFIG_STM32_SPI2 /* SPI2 clock enable */ regval |= RCC_APB1ENR_SPI2EN; #endif #ifdef CONFIG_STM32_SPI3 /* SPI3 clock enable */ regval |= RCC_APB1ENR_SPI3EN; #endif #ifdef CONFIG_STM32_USART2 /* USART 2 clock enable */ regval |= RCC_APB1ENR_USART2EN; #endif #ifdef CONFIG_STM32_USART3 /* USART3 clock enable */ regval |= RCC_APB1ENR_USART3EN; #endif #ifdef CONFIG_STM32_UART4 /* UART4 clock enable */ regval |= RCC_APB1ENR_UART4EN; #endif #ifdef CONFIG_STM32_UART5 /* UART5 clock enable */ regval |= RCC_APB1ENR_UART5EN; #endif #ifdef CONFIG_STM32_I2C1 /* I2C1 clock enable */ regval |= RCC_APB1ENR_I2C1EN; #endif #ifdef CONFIG_STM32_I2C2 /* I2C2 clock enable */ regval |= RCC_APB1ENR_I2C2EN; #endif #ifdef CONFIG_STM32_I2C3 /* I2C3 clock enable */ regval |= RCC_APB1ENR_I2C3EN; #endif #ifdef CONFIG_STM32_CAN1 /* CAN 1 clock enable */ regval |= RCC_APB1ENR_CAN1EN; #endif #ifdef CONFIG_STM32_CAN2 /* CAN2 clock enable. NOTE: CAN2 needs CAN1 clock as well. */ regval |= (RCC_APB1ENR_CAN1EN | RCC_APB1ENR_CAN2EN); #endif /* Power interface clock enable. The PWR block is always enabled so that * we can set the internal voltage regulator for maximum performance. */ regval |= RCC_APB1ENR_PWREN; #if defined (CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) /* DAC interface clock enable */ regval |= RCC_APB1ENR_DACEN; #endif putreg32(regval, STM32_RCC_APB1ENR); /* Enable peripherals */ }
static inline int sam_configperiph(uintptr_t base, uint32_t pin, gpio_pinset_t cfgset) { uint32_t regval; /* Disable interrupts on the pin */ putreg32(pin, base + SAM_PIO_IDR_OFFSET); /* Enable/disable the pull-up as requested */ if ((cfgset & GPIO_CFG_PULLUP) != 0) { putreg32(pin, base + SAM_PIO_PUER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PUDR_OFFSET); } #ifdef GPIO_HAVE_PULLDOWN /* Enable/disable the pull-down as requested */ if ((cfgset & GPIO_CFG_PULLDOWN) != 0) { putreg32(pin, base + SAM_PIO_PPDER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); } #endif #ifdef GPIO_HAVE_DRIVER /* Reset output drive strength (PIO outputs only) */ regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); regval &= ~pin; putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); #endif #ifdef GPIO_HAVE_PERIPHCD /* Configure pin, depending upon the peripheral A, B, C or D * * PERIPHA: ABCDSR1[n] = 0 ABCDSR2[n] = 0 * PERIPHB: ABCDSR1[n] = 1 ABCDSR2[n] = 0 * PERIPHC: ABCDSR1[n] = 0 ABCDSR2[n] = 1 * PERIPHD: ABCDSR1[n] = 1 ABCDSR2[n] = 1 */ regval = getreg32(base + SAM_PIO_ABCDSR1_OFFSET); if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHC) { regval &= ~pin; } else { regval |= pin; } putreg32(regval, base + SAM_PIO_ABCDSR1_OFFSET); regval = getreg32(base + SAM_PIO_ABCDSR2_OFFSET); if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA || (cfgset & GPIO_MODE_MASK) == GPIO_PERIPHB) { regval &= ~pin; } else { regval |= pin; } putreg32(regval, base + SAM_PIO_ABCDSR2_OFFSET); #else /* Configure pin, depending upon the peripheral A or B: * * PERIPHA: ABSR[n] = 0 * PERIPHB: ABSR[n] = 1 */ regval = getreg32(base + SAM_PIO_ABSR_OFFSET); if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA) { regval &= ~pin; } else { regval |= pin; } putreg32(regval, base + SAM_PIO_ABSR_OFFSET); #endif /* Disable PIO functionality */ putreg32(pin, base + SAM_PIO_PDR_OFFSET); return OK; }
int kl_configgpio(uint32_t cfgset) { uintptr_t base; uint32_t regval; unsigned int port; unsigned int pin; unsigned int mode; /* Get the port number and pin number */ port = (cfgset & _PIN_PORT_MASK) >> _PIN_PORT_SHIFT; pin = (cfgset & _PIN_MASK) >> _PIN_SHIFT; DEBUGASSERT(port < KL_NPORTS); if (port < KL_NPORTS) { /* Get the base address of PORT block for this port */ base = KL_PORT_BASE(port); /* Get the port mode */ mode = (cfgset & _PIN_MODE_MASK) >> _PIN_MODE_SHIFT; /* Special case analog port mode. In this case, not of the digital * options are applicable. */ if (mode == PIN_MODE_ANALOG) { /* Set the analog mode with all digital options zeroed */ regval = PORT_PCR_MUX_ANALOG | PORT_PCR_IRQC_DISABLED; putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); } else { /* Configure the digital pin options */ regval = (mode << PORT_PCR_MUX_SHIFT); if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) { /* Handle input-only digital options */ /* Check for pull-up or pull-down */ if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLDOWN) { regval |= PORT_PCR_PE; } else if ((cfgset & _PIN_INPUT_PULLMASK) == _PIN_INPUT_PULLUP) { regval |= (PORT_PCR_PE | PORT_PCR_PS); } } else { /* Handle output-only digital options */ /* Check for slow slew rate setting */ if ((cfgset & _PIN_OUTPUT_SLEW_MASK) == _PIN_OUTPUT_SLOW) { regval |= PORT_PCR_SRE; } /* Check for open drain output */ if ((cfgset & _PIN_OUTPUT_OD_MASK) == _PIN_OUTPUT_OPENDRAIN) { regval |= PORT_PCR_ODE; } /* Check for high drive output */ if ((cfgset & _PIN_OUTPUT_DRIVE_MASK) == _PIN_OUTPUT_HIGHDRIVE) { regval |= PORT_PCR_DSE; } } /* Check for passive filter enable. Passive Filter configuration * is valid in all digital pin muxing modes. */ if ((cfgset & PIN_PASV_FILTER) != 0) { regval |= PORT_PCR_PFE; } /* Set the digital mode with all of the selected options */ putreg32(regval, base + KL_PORT_PCR_OFFSET(pin)); /* Check for digital filter enable. Digital Filter configuration * is valid in all digital pin muxing modes. */ regval = getreg32(base + KL_PORT_DFER_OFFSET); if ((cfgset & PIN_DIG_FILTER) != 0) { regval |= (1 << pin); } else { regval &= ~(1 << pin); } putreg32(regval, base + KL_PORT_DFER_OFFSET); /* Additional configuration for the case of Alternative 1 (GPIO) modes */ if (mode == PIN_MODE_GPIO) { /* Set the GPIO port direction */ base = KL_GPIO_BASE(port); regval = getreg32(base + KL_GPIO_PDDR_OFFSET); if ((cfgset & _PIN_IO_MASK) == _PIN_INPUT) { /* Select GPIO input */ regval &= ~(1 << pin); putreg32(regval, base + KL_GPIO_PDDR_OFFSET); } else /* if ((cfgset & _PIN_IO_MASK) == _PIN_OUTPUT) */ { /* Select GPIO input */ regval |= (1 << pin); putreg32(regval, base + KL_GPIO_PDDR_OFFSET); /* Set the initial value of the GPIO output */ kl_gpiowrite(cfgset, ((cfgset & GPIO_OUTPUT_ONE) != 0)); } } } return OK; }
static inline int sam_configoutput(uintptr_t base, uint32_t pin, gpio_pinset_t cfgset) { #ifdef GPIO_HAVE_DRIVER uint32_t regval; #endif /* Disable interrupts on the pin */ putreg32(pin, base + SAM_PIO_IDR_OFFSET); /* Enable/disable the pull-up as requested */ if ((cfgset & GPIO_CFG_PULLUP) != 0) { putreg32(pin, base + SAM_PIO_PUER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PUDR_OFFSET); } #ifdef GPIO_HAVE_PULLDOWN /* Enable/disable the pull-down as requested */ if ((cfgset & GPIO_CFG_PULLDOWN) != 0) { putreg32(pin, base + SAM_PIO_PPDER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); } #endif /* Enable the open drain driver if requrested */ if ((cfgset & GPIO_CFG_OPENDRAIN) != 0) { putreg32(pin, base + SAM_PIO_MDER_OFFSET); } else { putreg32(pin, base + SAM_PIO_MDDR_OFFSET); } /* Set default value */ if ((cfgset & GPIO_OUTPUT_SET) != 0) { putreg32(pin, base + SAM_PIO_SODR_OFFSET); } else { putreg32(pin, base + SAM_PIO_CODR_OFFSET); } #ifdef GPIO_HAVE_DRIVER /* Select the pin output drive strength */ regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); if ((cfgset & GPIO_OUTPUT_DRIVE) != GPIO_OUTPUT_LOW_DRIVE) { regval |= pin; } else { regval &= ~pin; } putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); #endif /* Configure the pin as an output and enable the GPIO function */ putreg32(pin, base + SAM_PIO_OER_OFFSET); putreg32(pin, base + SAM_PIO_PER_OFFSET); return OK; }
static inline int sam_configinput(uintptr_t base, uint32_t pin, gpio_pinset_t cfgset) { #ifdef GPIO_HAVE_SCHMITT uint32_t regval; #endif /* Disable interrupts on the pin */ putreg32(pin, base + SAM_PIO_IDR_OFFSET); /* Enable/disable the pull-up as requested */ if ((cfgset & GPIO_CFG_PULLUP) != 0) { putreg32(pin, base + SAM_PIO_PUER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PUDR_OFFSET); } #ifdef GPIO_HAVE_PULLDOWN /* Enable/disable the pull-down as requested */ if ((cfgset & GPIO_CFG_PULLDOWN) != 0) { putreg32(pin, base + SAM_PIO_PPDER_OFFSET); } else { putreg32(pin, base + SAM_PIO_PPDDR_OFFSET); } #endif /* Check if filtering should be enabled */ if ((cfgset & GPIO_CFG_DEGLITCH) != 0) { putreg32(pin, base + SAM_PIO_IFER_OFFSET); } else { putreg32(pin, base + SAM_PIO_IFDR_OFFSET); } #ifdef GPIO_HAVE_SCHMITT /* Enable/disable the Schmitt trigger */ regval = getreg32(base + SAM_PIO_SCHMITT_OFFSET); if ((cfgset & GPIO_CFG_PULLDOWN) != 0) { regval |= pin; } else { regval &= ~pin; } putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET); #endif #ifdef GPIO_HAVE_DRIVER /* Reset output drive strength (PIO outputs only) */ regval = getreg32(base + SAM_PIO_DRIVER_OFFSET); regval &= ~pin; putreg32(regval, base + SAM_PIO_DRIVER_OFFSET); #endif /* Configure the pin as an input and enable the GPIO function */ putreg32(pin, base + SAM_PIO_ODR_OFFSET); putreg32(pin, base + SAM_PIO_PER_OFFSET); /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and * IFDGSR registers. This would probably best be done with * another, new API... perhaps sam_configfilter() */ return 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); /* Colorize the interrupt stack for debug purposes */ #if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 3 { size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~3); up_stack_color((FAR void *)((uintptr_t)&g_intstackbase - intstack_size), intstack_size); } #endif /* 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. * * 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)_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 }
static void lpc17_gpiodemux(uint32_t intbase, uint32_t intmask, int irqbase, void *context) { uint32_t intstatr; uint32_t intstatf; uint32_t intstatus; uint32_t bit; int irq; /* Get the interrupt rising and falling edge status and mask out only the * interrupts that are enabled. */ intstatr = getreg32(intbase + LPC17_GPIOINT_INTSTATR_OFFSET); intstatr &= getreg32(intbase + LPC17_GPIOINT_INTENR_OFFSET); intstatf = getreg32(intbase + LPC17_GPIOINT_INTSTATF_OFFSET); intstatf &= getreg32(intbase + LPC17_GPIOINT_INTENF_OFFSET); /* And get the OR of the enabled interrupt sources. We do not make any * distinction between rising and falling edges (but the hardware does support * the ability to handle them differently if needed). */ intstatus = intstatr | intstatf; /* Now march through the (valid) bits and dispatch each interrupt */ irq = irqbase; bit = 1; while (intstatus != 0) { /* Does this pin support an interrupt? If no, skip over it WITHOUT * incrementing irq. */ if ((intmask & bit) != 0) { /* This pin can support an interrupt. Is there an interrupt pending * and enabled? */ if ((intstatus & bit) != 0) { /* Clear the interrupt status */ putreg32(bit, intbase + LPC17_GPIOINT_INTCLR_OFFSET); /* And dispatch the interrupt */ irq_dispatch(irq, context); } /* Increment the IRQ number on each interrupt pin */ irq++; } /* Next bit */ intstatus &= ~bit; bit <<= 1; } }
static inline void rcc_enableapb2(void) { uint32_t regval; /* Set the appropriate bits in the APB2ENR register to enabled the * selected APB2 peripherals. */ regval = getreg32(STM32_RCC_APB2ENR); #ifdef CONFIG_STM32_TIM1 /* TIM1 clock enable */ regval |= RCC_APB2ENR_TIM1EN; #endif #ifdef CONFIG_STM32_TIM8 /* TIM8 clock enable */ regval |= RCC_APB2ENR_TIM8EN; #endif #ifdef CONFIG_STM32_USART1 /* USART1 clock enable */ regval |= RCC_APB2ENR_USART1EN; #endif #ifdef CONFIG_STM32_USART6 /* USART6 clock enable */ regval |= RCC_APB2ENR_USART6EN; #endif #ifdef CONFIG_STM32_ADC1 /* ADC1 clock enable */ regval |= RCC_APB2ENR_ADC1EN; #endif #ifdef CONFIG_STM32_ADC2 /* ADC2 clock enable */ regval |= RCC_APB2ENR_ADC2EN; #endif #ifdef CONFIG_STM32_ADC3 /* ADC3 clock enable */ regval |= RCC_APB2ENR_ADC3EN; #endif #ifdef CONFIG_STM32_SDIO /* SDIO clock enable */ regval |= RCC_APB2ENR_SDIOEN; #endif #ifdef CONFIG_STM32_SPI1 /* SPI1 clock enable */ regval |= RCC_APB2ENR_SPI1EN; #endif #ifdef CONFIG_STM32_SYSCFG /* System configuration controller clock enable */ regval |= RCC_APB2ENR_SYSCFGEN; #endif #ifdef CONFIG_STM32_TIM9 /* TIM9 clock enable */ regval |= RCC_APB2ENR_TIM9EN; #endif #ifdef CONFIG_STM32_TIM10 /* TIM10 clock enable */ regval |= RCC_APB2ENR_TIM10EN; #endif #ifdef CONFIG_STM32_TIM11 /* TIM11 clock enable */ regval |= RCC_APB2ENR_TIM11EN; #endif putreg32(regval, STM32_RCC_APB2ENR); /* Enable peripherals */ }
ssize_t up_progmem_eraseblock(size_t block) { uintptr_t base; size_t page_address; if (block >= STM32_FLASH_NPAGES) { return -EFAULT; } #if defined(STM32_FLASH_DUAL_BANK) /* Handle paged FLASH */ if (block >= STM32_FLASH_BANK0_NPAGES) { base = STM32_FLASH_BANK1_BASE; } else #endif { base = STM32_FLASH_BANK0_BASE; } sem_lock(); if ((getreg32(base + STM32_RCC_CR_OFFSET) & RCC_CR_HSION) == 0) { sem_unlock(); return -EPERM; } /* Get flash ready and begin erasing single page */ flash_unlock(base); modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PER); /* Must be valid - page index checked above */ page_address = up_progmem_getaddress(block); putreg32(page_address, base + STM32_FLASH_AR_OFFSET); modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_STRT); while ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) != 0) { up_waste(); } modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PER, 0); sem_unlock(); /* Verify */ if (up_progmem_ispageerased(block) == 0) { return up_progmem_erasesize(block); /* success */ } else { return -EIO; /* failure */ } }
static void stm32_stdclockconfig(void) { uint32_t regval; volatile int32_t timeout; /* Enable External High-Speed Clock (HSE) */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_HSEON; /* Enable HSE */ putreg32(regval, STM32_RCC_CR); /* Wait until the HSE is ready (or until a timeout elapsed) */ for (timeout = HSERDY_TIMEOUT; timeout > 0; timeout--) { /* Check if the HSERDY flag is the set in the CR */ if ((getreg32(STM32_RCC_CR) & RCC_CR_HSERDY) != 0) { /* If so, then break-out with timeout > 0 */ break; } } /* Check for a timeout. If this timeout occurs, then we are hosed. We * have no real back-up plan, although the following logic makes it look * as though we do. */ if (timeout > 0) { /* Select regulator voltage output Scale 1 mode to support system * frequencies up to 168 MHz. */ regval = getreg32(STM32_RCC_APB1ENR); regval |= RCC_APB1ENR_PWREN; putreg32(regval, STM32_RCC_APB1ENR); regval = getreg32(STM32_PWR_CR); regval |= PWR_CR_VOS; putreg32(regval, STM32_PWR_CR); /* Set the HCLK source/divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_HPRE_MASK; regval |= STM32_RCC_CFGR_HPRE; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK2 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE2_MASK; regval |= STM32_RCC_CFGR_PPRE2; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK1 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE1_MASK; regval |= STM32_RCC_CFGR_PPRE1; putreg32(regval, STM32_RCC_CFGR); #ifdef CONFIG_RTC_HSECLOCK /* Set the RTC clock divisor */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_RTCPRE_MASK; regval |= RCC_CFGR_RTCPRE(HSE_DIVISOR); putreg32(regval, STM32_RCC_CFGR); #endif /* Set the PLL dividers and multipliers to configure the main PLL */ regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN |STM32_PLLCFG_PLLP | RCC_PLLCFG_PLLSRC_HSE | STM32_PLLCFG_PLLQ); putreg32(regval, STM32_RCC_PLLCFG); /* Enable the main PLL */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLLON; putreg32(regval, STM32_RCC_CR); /* Wait until the PLL is ready */ while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); /* Enable FLASH prefetch, instruction cache, data cache, and 5 wait states */ #ifdef CONFIG_STM32_FLASH_PREFETCH regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN); #else regval = (FLASH_ACR_LATENCY_5 | FLASH_ACR_ICEN | FLASH_ACR_DCEN); #endif putreg32(regval, STM32_FLASH_ACR); /* Select the main PLL as system clock source */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_SW_MASK; regval |= RCC_CFGR_SW_PLL; putreg32(regval, STM32_RCC_CFGR); /* Wait until the PLL source is used as the system clock source */ while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL); } }
static inline void rcc_enableapb2(void) { uint32_t regval; /* Set the appropriate bits in the APB2ENR register to enabled the * selected APB2 peripherals. */ regval = getreg32(STM32_RCC_APB2ENR); #ifdef CONFIG_STM32_SYSCFG /* SYSCFG clock */ regval |= RCC_APB2ENR_SYSCFGEN; #endif #ifdef CONFIG_STM32_TIM1 /* TIM1 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM1EN; #endif #endif #ifdef CONFIG_STM32_SPI1 /* SPI 1 clock enable */ regval |= RCC_APB2ENR_SPI1EN; #endif #ifdef CONFIG_STM32_USART1 /* USART1 clock enable */ regval |= RCC_APB2ENR_USART1EN; #endif #ifdef CONFIG_STM32_TIM15 /* TIM15 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM15EN; #endif #endif #ifdef CONFIG_STM32_TIM16 /* TIM16 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM16EN; #endif #endif #ifdef CONFIG_STM32_TIM17 /* TIM17 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM17EN; #endif #endif #ifdef CONFIG_STM32_HRTIM1 /* HRTIM1 Timer clock enable */ regval |= RCC_APB2ENR_HRTIM1EN; #endif putreg32(regval, STM32_RCC_APB2ENR); }
static inline void rcc_enableapb1(void) { uint32_t regval; /* Set the appropriate bits in the APB1ENR register to enabled the * selected APB1 peripherals. */ regval = getreg32(STM32_RCC_APB1ENR); #ifdef CONFIG_STM32_TIM2 /* Timer 2 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM2EN; #endif #endif #ifdef CONFIG_STM32_TIM3 /* Timer 3 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM3EN; #endif #endif #ifdef CONFIG_STM32_TIM4 /* Timer 4 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM4EN; #endif #endif #ifdef CONFIG_STM32_TIM5 /* Timer 5 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM5EN; #endif #endif #ifdef CONFIG_STM32_TIM6 /* Timer 6 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM6EN; #endif #endif #ifdef CONFIG_STM32_TIM7 /* Timer 7 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM7EN; #endif #endif #ifdef CONFIG_STM32_LCD /* LCD clock enable */ regval |= RCC_APB1ENR_LCDEN; #endif #ifdef CONFIG_STM32_WWDG /* Window Watchdog clock enable */ regval |= RCC_APB1ENR_WWDGEN; #endif #ifdef CONFIG_STM32_SPI2 /* SPI 2 clock enable */ regval |= RCC_APB1ENR_SPI2EN; #endif #ifdef CONFIG_STM32_SPI3 /* SPI 3 clock enable */ regval |= RCC_APB1ENR_SPI3EN; #endif #ifdef CONFIG_STM32_USART2 /* USART 2 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_USART2EN; #endif #endif #ifdef CONFIG_STM32_USART3 /* USART 3 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_USART3EN; #endif #endif #ifdef CONFIG_STM32_UART4 /* USART 4 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_UART4EN; #endif #endif #ifdef CONFIG_STM32_UART5 /* USART 5 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_UART5EN; #endif #endif #ifdef CONFIG_STM32_I2C1 /* I2C 1 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_I2C1EN; #endif #endif #ifdef CONFIG_STM32_I2C2 /* I2C 2 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_I2C2EN; #endif #endif #ifdef CONFIG_STM32_USB /* USB clock enable */ regval |= RCC_APB1ENR_USBEN; #endif #ifdef CONFIG_STM32_PWR /* Power interface clock enable */ regval |= RCC_APB1ENR_PWREN; #endif #ifdef CONFIG_STM32_DAC /* DAC interface clock enable */ regval |= RCC_APB1ENR_DACEN; #endif #ifdef CONFIG_STM32_COMP /* COMP interface clock enable */ regval |= RCC_APB1ENR_COMPEN; #endif putreg32(regval, STM32_RCC_APB1ENR); }
static inline void rcc_reset(void) { uint32_t regval; putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ putreg32(RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN, STM32_RCC_AHBENR); /* FLITF and SRAM Clock ON */ putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ regval = getreg32(STM32_RCC_CR); /* Set the HSION bit */ regval |= RCC_CR_HSION; putreg32(regval, STM32_RCC_CR); regval = getreg32(STM32_RCC_CFGR); /* Reset SW, HPRE, PPRE1, PPRE2, and MCO bits */ regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | RCC_CFGR_PPRE2_MASK | RCC_CFGR_MCO_MASK); putreg32(regval, STM32_RCC_CFGR); regval = getreg32(STM32_RCC_CFGR2); /* Reset PREDIV, and ADC12PRE bits */ regval &= ~(RCC_CFGR2_PREDIV_MASK | RCC_CFGR2_ADC12PRES_MASK); putreg32(regval, STM32_RCC_CFGR2); regval = getreg32(STM32_RCC_CFGR3); /* Reset all U[S]ARTs, I2C1, TIM1 and HRTIM1 bits */ regval &= ~(RCC_CFGR3_USART1SW_MASK | RCC_CFGR3_USART2SW_MASK | RCC_CFGR3_USART3SW_MASK | \ RCC_CFGR3_I2C1SW | RCC_CFGR3_TIM1SW | RCC_CFGR3_HRTIM1SW); putreg32(regval, STM32_RCC_CFGR3); regval = getreg32(STM32_RCC_CR); /* Reset HSEON, CSSON and PLLON bits */ regval &= ~(RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON); putreg32(regval, STM32_RCC_CR); regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ regval &= ~RCC_CR_HSEBYP; putreg32(regval, STM32_RCC_CR); regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */ regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMUL_MASK); putreg32(regval, STM32_RCC_CFGR); putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ }
static inline void rcc_enableapb2(void) { uint32_t regval; /* Set the appropriate bits in the APB2ENR register to enabled the * selected APB2 peripherals. */ regval = getreg32(STM32_RCC_APB2ENR); #ifdef CONFIG_STM32_SYSCFG /* SYSCFG clock */ regval |= RCC_APB2ENR_SYSCFGEN; #endif #ifdef CONFIG_STM32_TIM9 /* TIM9 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM9EN; #endif #endif #ifdef CONFIG_STM32_TIM10 /* TIM10 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM10EN; #endif #endif #ifdef CONFIG_STM32_TIM11 /* TIM11 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM11EN; #endif #endif #ifdef CONFIG_STM32_ADC1 /* ADC 1 clock enable */ regval |= RCC_APB2ENR_ADC1EN; #endif #ifdef CONFIG_STM32_SDIO /* SDIO clock enable */ regval |= RCC_APB2ENR_SDIOEN; #endif #ifdef CONFIG_STM32_SPI1 /* SPI 1 clock enable */ regval |= RCC_APB2ENR_SPI1EN; #endif #ifdef CONFIG_STM32_USART1 /* USART1 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_USART1EN; #endif #endif putreg32(regval, STM32_RCC_APB2ENR); }
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 }
static void stm32_stdclockconfig(void) { uint32_t regval; #if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK) uint16_t pwrcr; #endif #if defined(CONFIG_STM32_ENERGYLITE) /* Enable PWR clock from APB1 to give access to PWR_CR register */ regval = getreg32(STM32_RCC_APB1ENR); regval |= RCC_APB1ENR_PWREN; putreg32(regval, STM32_RCC_APB1ENR); #endif /* CONFIG_STM32_ENERGYLITE */ /* Go to the high performance voltage range 1 if necessary. In this mode, * the PLL VCO frequency can be up to 96MHz. USB and SDIO can be supported. * * Range 1: PLLVCO up to 96MHz in range 1 (1.8V) * Range 2: PLLVCO up to 48MHz in range 2 (1.5V) (default) * Range 3: PLLVCO up to 24MHz in range 3 (1.2V) */ #if STM32_PLL_FREQUENCY > 48000000 stm32_pwr_setvos(PWR_CR_VOS_SCALE_1); #endif #if defined(CONFIG_RTC_HSECLOCK) || defined(CONFIG_LCD_HSECLOCK) /* If RTC / LCD selects HSE as clock source, the RTC prescaler * needs to be set before HSEON bit is set. */ /* The RTC domain has write access denied after reset, * you have to enable write access using DBP bit in the PWR CR * register before to selecting the clock source ( and the PWR * peripheral must be enabled) */ regval = getreg32(STM32_RCC_APB1ENR); regval |= RCC_APB1ENR_PWREN; putreg32(regval, STM32_RCC_APB1ENR); pwrcr = getreg16(STM32_PWR_CR); putreg16(pwrcr | PWR_CR_DBP, STM32_PWR_CR); /* Set the RTC clock divisor */ regval = getreg32(STM32_RCC_CSR); regval &= ~RCC_CSR_RTCSEL_MASK; regval |= RCC_CSR_RTCSEL_HSE; putreg32(regval, STM32_RCC_CSR); regval = getreg32(STM32_RCC_CR); regval &= ~RCC_CR_RTCPRE_MASK; regval |= HSE_DIVISOR); putreg32(regval, STM32_RCC_CR); /* Restore the previous state of the DBP bit */ putreg32(regval, STM32_PWR_CR); #endif /* Enable the source clock for the PLL (via HSE or HSI), HSE, and HSI. * NOTE that only PLL, HSE, or HSI are supported for the system clock * in this implementation */ #if (STM32_SYSCLK_SW == RCC_CFGR_SW_HSE) || \ ((STM32_SYSCLK_SW == RCC_CFGR_SW_PLL) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC)) /* The PLL is using the HSE, or the HSE is the system clock. In either * case, we need to enable HSE clocking. */ if (!stm32_rcc_enablehse()) { /* In the case of a timeout starting the HSE, we really don't have a * strategy. This is almost always a hardware failure or * misconfiguration (for example, if no crystal is fitted on the board. */ return; } #elif (STM32_SYSCLK_SW == RCC_CFGR_SW_HSI) || \ ((STM32_SYSCLK_SW == RCC_CFGR_SW_PLL) && STM32_CFGR_PLLSRC == 0) /* The PLL is using the HSI, or the HSI is the system clock. In either * case, we need to enable HSI clocking. */ regval = getreg32(STM32_RCC_CR); /* Enable the HSI */ regval |= RCC_CR_HSION; putreg32(regval, STM32_RCC_CR); /* Wait until the HSI clock is ready. Since this is an internal clock, no * timeout is expected */ while ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) == 0); #endif #if (STM32_SYSCLK_SW != RCC_CFGR_SW_MSI) /* Increasing the CPU frequency (in the same voltage range): * * After reset, the used clock is the MSI (2 MHz) with 0 WS configured in the * FLASH_ACR register. 32-bit access is enabled and prefetch is disabled. * ST strongly recommends to use the following software sequences to tune the * number of wait states needed to access the Flash memory with the CPU * frequency. * * - Program the 64-bit access by setting the ACC64 bit in Flash access * control register (FLASH_ACR) * - Check that 64-bit access is taken into account by reading FLASH_ACR * - Program 1 WS to the LATENCY bit in FLASH_ACR * - Check that the new number of WS is taken into account by reading FLASH_ACR * - Modify the CPU clock source by writing to the SW bits in the Clock * configuration register (RCC_CFGR) * - If needed, modify the CPU clock prescaler by writing to the HPRE bits in * RCC_CFGR * - Check that the new CPU clock source or/and the new CPU clock prescaler * value is/are taken into account by reading the clock source status (SWS * bits) or/and the AHB prescaler value (HPRE bits), respectively, in the * RCC_CFGR register */ regval = getreg32(STM32_FLASH_ACR); regval |= FLASH_ACR_ACC64; /* 64-bit access mode */ putreg32(regval, STM32_FLASH_ACR); regval |= FLASH_ACR_LATENCY; /* One wait state */ putreg32(regval, STM32_FLASH_ACR); /* Enable FLASH prefetch */ regval |= FLASH_ACR_PRFTEN; putreg32(regval, STM32_FLASH_ACR); #endif /* Set the HCLK source/divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_HPRE_MASK; regval |= STM32_RCC_CFGR_HPRE; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK2 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE2_MASK; regval |= STM32_RCC_CFGR_PPRE2; putreg32(regval, STM32_RCC_CFGR); /* Set the PCLK1 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_PPRE1_MASK; regval |= STM32_RCC_CFGR_PPRE1; putreg32(regval, STM32_RCC_CFGR); /* If we are using the PLL, configure and start it */ #if STM32_SYSCLK_SW == RCC_CFGR_SW_PLL /* Set the PLL divider and multiplier. NOTE: The PLL needs to be disabled * to do these operation. We know this is the case here because pll_reset() * was previously called by stm32_clockconfig(). */ regval = getreg32(STM32_RCC_CFGR); regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK); regval |= (STM32_CFGR_PLLSRC | STM32_CFGR_PLLMUL | STM32_CFGR_PLLDIV); putreg32(regval, STM32_RCC_CFGR); /* Enable the PLL */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLLON; putreg32(regval, STM32_RCC_CR); /* Wait until the PLL is ready */ while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); #endif /* Select the system clock source (probably the PLL) */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_SW_MASK; regval |= STM32_SYSCLK_SW; putreg32(regval, STM32_RCC_CFGR); /* Wait until the selected source is used as the system clock source */ while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != STM32_SYSCLK_SWS); #if defined(CONFIG_STM32_IWDG) || \ defined(CONFIG_RTC_LSICLOCK) || defined(CONFIG_LCD_LSICLOCK) /* Low speed internal clock source LSI */ /* * TODO: There is another case where the LSI needs to * be enabled: if the MCO pin selects LSI as source. */ stm32_rcc_enablelsi(); #endif #if defined(CONFIG_RTC_LSECLOCK) || defined(CONFIG_LCD_LSECLOCK) /* Low speed external clock source LSE * * TODO: There is another case where the LSE needs to * be enabled: if the MCO pin selects LSE as source. * * TODO: There is another case where the LSE needs to * be enabled: if TIM9-10 Channel 1 selects LSE as input. * * TODO: There is another case where the LSE needs to * be enabled: if TIM10-11 selects LSE as ETR Input. * */ stm32_rcc_enablelse(); #endif }
void nokia_blinitialize(void) { uint32_t regval; /* Enable clocking of PWM1 */ regval = getreg32(LPC17_SYSCON_PCONP); regval |= SYSCON_PCONP_PCPWM1; putreg32(regval, LPC17_SYSCON_PCONP); /* Disable and reset PWM1 */ regval = getreg32(LPC17_PWM1_TCR); regval &= ~(PWM_TCR_PWMEN|PWM_TCR_CNTREN); regval |= PWM_TCR_CNTRRST; putreg32(regval, LPC17_PWM1_TCR); /* Put PWM1 in timer mode */ regval = getreg32(LPC17_PWM1_CTCR); regval &= ~PWM_CTCR_MODE_MASK; regval |= PWM_CTCR_MODE_TIMER; putreg32(regval, LPC17_PWM1_CTCR); /* Reset on MR0 */ putreg32(PWM_MCR_MR0R, LPC17_PWM1_MCR); /* Single edge controlled mod for PWM3 and enable output */ regval = getreg32(LPC17_PWM1_PCR); regval &= ~PWM_PCR_SEL3; regval |= PWM_PCR_ENA3; putreg32(regval, LPC17_PWM1_PCR); /* Clear prescaler */ putreg32(0, LPC17_PWM1_PR); /* Set 8-bit resolution */ putreg32(0xff, LPC17_PWM1_MCR); /* Enable PWM match 1 latch */ regval = getreg32(LPC17_PWM1_LER); regval |= PWM_LER_M0EN; putreg32(regval, LPC17_PWM1_LER); /* Clear match register 3 */ putreg32(0, LPC17_PWM1_MR3); /* Enable PWM1 */ regval |= PWM_LER_M3EN; putreg32(regval, LPC17_PWM1_LER); regval = getreg32(LPC17_PWM1_TCR); regval &= ~(PWM_TCR_CNTRRST); regval |= (PWM_TCR_PWMEN|PWM_TCR_CNTREN); putreg32(regval, LPC17_PWM1_TCR); nokia_backlight(0); }
static inline void rcc_reset(void) { #if 0 /* None of this is necessary if only called from power up */ uint32_t regval; /* Make sure that all devices are out of reset */ putreg32(0, STM32_RCC_AHBRSTR); /* Disable AHB Peripheral Reset */ putreg32(0, STM32_RCC_APB2RSTR); /* Disable APB2 Peripheral Reset */ putreg32(0, STM32_RCC_APB1RSTR); /* Disable APB1 Peripheral Reset */ /* Disable all clocking (other than to FLASH) */ putreg32(RCC_AHBENR_FLITFEN, STM32_RCC_AHBENR); /* FLITF Clock ON */ putreg32(0, STM32_RCC_APB2ENR); /* Disable APB2 Peripheral Clock */ putreg32(0, STM32_RCC_APB1ENR); /* Disable APB1 Peripheral Clock */ /* Set the Internal clock sources calibration register to its reset value. * MSI to the default frequency (nominally 2.097MHz), MSITRIM=0, HSITRIM=0x10. * Preserve the factory HSICAL and MSICAL settings. */ regval = getreg32(STM32_RCC_ICSCR); regval &= (RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK); regval |= (RCC_ICSR_RSTVAL & ~(RCC_ICSCR_HSICAL_MASK | RCC_ICSCR_MSICAL_MASK)); putreg32(regval, STM32_RCC_ICSCR); /* Enable the internal MSI */ regval = getreg32(STM32_RCC_CR); /* Enable the MSI */ regval |= RCC_CR_MSION; putreg32(regval, STM32_RCC_CR); /* Set the CFGR register to its reset value: Reset SW, HPRE, PPRE1, PPRE2, * and MCO bits. Resetting SW selects the MSI clock as the system clock * source. We do not clear PLL values yet because the PLL may be providing * the SYSCLK and we want the PLL to be stable through the transition. */ regval = getreg32(STM32_RCC_CFGR); regval &= ~(RCC_CFGR_SW_MASK | RCC_CFGR_HPRE_MASK | RCC_CFGR_PPRE1_MASK | RCC_CFGR_PPRE2_MASK | RCC_CFGR_MCOSEL_MASK | RCC_CFGR_MCOPRE_MASK); putreg32(regval, STM32_RCC_CFGR); /* Make sure that the selected MSI source is used as the system clock source */ while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_MSI); /* Now we can disable the alternative clock sources: HSE, HSI, PLL, CSS and RTCPRE. Also, * reset the HSE bypass. This restores the RCC CR to its reset state. */ regval = getreg32(STM32_RCC_CR); /* Disable the HSE and the PLL */ regval &= ~(RCC_CR_HSION | RCC_CR_HSEON | RCC_CR_PLLON | RCC_CR_CSSON | RCC_CR_RTCPRE_MASK); putreg32(regval, STM32_RCC_CR); regval = getreg32(STM32_RCC_CR); /* Reset HSEBYP bit */ regval &= ~RCC_CR_HSEBYP; putreg32(regval, STM32_RCC_CR); /* Now we can reset the CFGR PLL fields to their reset value */ regval = getreg32(STM32_RCC_CFGR); /* Reset PLLSRC, PLLMUL, and PLLDIV bits */ regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK | RCC_CFGR_PLLDIV_MASK); putreg32(regval, STM32_RCC_CFGR); /* Make sure that all interrupts are disabled */ putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ /* Go to the (default) voltage range 2 */ stm32_pwr_setvos(PWR_CR_VOS_SCALE_2); /* Reset the FLASH controller to 32-bit mode, no wait states. * * First, program the new number of WS to the LATENCY bit in Flash access * control register (FLASH_ACR) */ regval = getreg32(STM32_FLASH_ACR); regval &= ~FLASH_ACR_LATENCY; /* No wait states */ putreg32(regval, STM32_FLASH_ACR); /* Check that the new number of WS is taken into account by reading FLASH_ACR */ /* Program the 32-bit access by clearing ACC64 in FLASH_ACR */ regval &= ~FLASH_ACR_ACC64; /* 32-bit access mode */ putreg32(regval, STM32_FLASH_ACR); /* Check that 32-bit access is taken into account by reading FLASH_ACR */ #endif }
FAR struct spi_dev_s *up_spiinitialize(int port) { uint32_t regval32; uint8_t regval8; int i; /* Only the SPI1 interface is supported */ #ifdef CONFIG_DEBUG if (port != 1) { return NULL; } #endif /* Configure multiplexed pins as connected on the ZP213X/4XPA board: * * PINSEL1 P0.17/CAP1.2/SCK1/MAT1.2 Bits 2-3=10 for SCK1 * PINSEL1 P0.18/CAP1.3/MISO1/MAT1.3 Bits 4-5=10 for MISO1 * (This is the RESET line for the UG_2864AMBAG01, * although it is okay to configure it as an input too) * PINSEL1 P0.19/MAT1.2/MOSI1/CAP1.2 Bits 6-7=10 for MOSI1 * PINSEL1 P0.20/MAT1.3/SSEL1/EINT3 Bits 8-9=00 for P0.20 (we'll control it via GPIO or FIO) * PINSEL1 P0.23/VBUS Bits 12-13=00 for P0.21 (we'll control it via GPIO or FIO) */ regval32 = getreg32(LPC214X_PINSEL1); #ifdef CONFIG_LCD_UG2864AMBAG01 regval32 &= ~(LPC214X_PINSEL1_P017_MASK|LPC214X_PINSEL1_P019_MASK| LPC214X_PINSEL1_P020_MASK|LPC214X_PINSEL1_P023_MASK); regval32 |= (LPC214X_PINSEL1_P017_SCK1|LPC214X_PINSEL1_P019_MOSI1| LPC214X_PINSEL1_P020_GPIO|LPC214X_PINSEL1_P023_GPIO); #else regval32 &= ~(LPC214X_PINSEL1_P017_MASK|LPC214X_PINSEL1_P018_MASK LPC214X_PINSEL1_P019_MASK|LPC214X_PINSEL1_P020_MASK| LPC214X_PINSEL1_P023_MASK); regval32 |= (LPC214X_PINSEL1_P017_SCK1|LPC214X_PINSEL1_P018_MISO1| LPC214X_PINSEL1_P019_MOSI1|LPC214X_PINSEL1_P020_GPIO| LPC214X_PINSEL1_P023_GPIO); #endif putreg32(regval32, LPC214X_PINSEL1); /* De-select chip select using P0.20 (SSEL1) (low enables) and select A0 * for commands (also low) */ regval32 = (1 << 20) | (1 << 23); putreg32(regval32, CS_SET_REGISTER); regval32 |= getreg32(CS_DIR_REGISTER); putreg32(regval32, CS_DIR_REGISTER); spidbg("CS Pin Config: PINSEL1: %08x PIN: %08x DIR: %08x\n", getreg32(LPC214X_PINSEL1), getreg32(CS_PIN_REGISTER), getreg32(CS_DIR_REGISTER)); /* Enable peripheral clocking to SPI1 */ regval32 = getreg32(LPC214X_PCON_PCONP); regval32 |= LPC214X_PCONP_PCSPI1; putreg32(regval32, LPC214X_PCON_PCONP); /* Configure 8-bit SPI mode */ putreg16(LPC214X_SPI1CR0_DSS8BIT|LPC214X_SPI1CR0_FRFSPI, LPC214X_SPI1_CR0); /* Disable the SSP and all interrupts (we'll poll for all data) */ putreg8(0, LPC214X_SPI1_CR1); putreg8(0, LPC214X_SPI1_IMSC); /* Set the initial clock frequency for indentification mode < 400kHz */ spi_setfrequency(NULL, 400000); /* Enable the SPI */ regval8 = getreg8(LPC214X_SPI1_CR1); putreg8(regval8 | LPC214X_SPI1CR1_SSE, LPC214X_SPI1_CR1); for (i = 0; i < 8; i++) { (void)getreg16(LPC214X_SPI1_DR); } return &g_spidev; }
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); /* 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 /* 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 FIQs */ #ifdef CONFIG_ARCH_FIQ up_fiqinitialize(); #endif /* 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 setbasepri(NVIC_SYSH_PRIORITY_MAX); irqrestore(0); #endif }
static inline void stm32_gpioremap(void) { #if defined(CONFIG_STM32_STM32F10XX) /* Remap according to the configuration within .config file */ uint32_t val = 0; #ifdef CONFIG_STM32_SPI1_REMAP val |= AFIO_MAPR_SPI1_REMAP; #endif #ifdef CONFIG_STM32_SPI3_REMAP val |= AFIO_MAPR_SPI3_REMAP; #endif #ifdef CONFIG_STM32_I2C1_REMAP val |= AFIO_MAPR_I2C1_REMAP; #endif #ifdef CONFIG_STM32_USART1_REMAP val |= AFIO_MAPR_USART1_REMAP; #endif #ifdef CONFIG_STM32_USART2_REMAP val |= AFIO_MAPR_USART2_REMAP; #endif #ifdef CONFIG_STM32_USART3_FULL_REMAP val |= AFIO_MAPR_USART3_FULLREMAP; #endif #ifdef CONFIG_STM32_USART3_PARTIAL_REMAP val |= AFIO_MAPR_USART3_PARTREMAP; #endif #ifdef CONFIG_STM32_TIM1_FULL_REMAP val |= AFIO_MAPR_TIM1_FULLREMAP; #endif #ifdef CONFIG_STM32_TIM1_PARTIAL_REMAP val |= AFIO_MAPR_TIM1_PARTREMAP; #endif #ifdef CONFIG_STM32_TIM2_FULL_REMAP val |= AFIO_MAPR_TIM2_FULLREMAP; #endif #ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_1 val |= AFIO_MAPR_TIM2_PARTREMAP1; #endif #ifdef CONFIG_STM32_TIM2_PARTIAL_REMAP_2 val |= AFIO_MAPR_TIM2_PARTREMAP2; #endif #ifdef CONFIG_STM32_TIM3_FULL_REMAP val |= AFIO_MAPR_TIM3_FULLREMAP; #endif #ifdef CONFIG_STM32_TIM3_PARTIAL_REMAP val |= AFIO_MAPR_TIM3_PARTREMAP; #endif #ifdef CONFIG_STM32_TIM4_REMAP val |= AFIO_MAPR_TIM4_REMAP; #endif #ifdef CONFIG_STM32_CAN1_REMAP1 val |= AFIO_MAPR_PB89; #endif #ifdef CONFIG_STM32_CAN1_REMAP2 val |= AFIO_MAPR_PD01; #endif #ifdef CONFIG_STM32_CAN2_REMAP /* Connectivity line only */ val |= AFIO_MAPR_CAN2_REMAP; #endif #ifdef CONFIG_STM32_ETH_REMAP /* Connectivity line only */ val |= AFIO_MAPR_ETH_REMAP; #endif #ifdef CONFIG_STM32_JTAG_FULL_ENABLE /* The reset default */ #elif CONFIG_STM32_JTAG_NOJNTRST_ENABLE val |= AFIO_MAPR_SWJ; /* enabled but without JNTRST */ #elif CONFIG_STM32_JTAG_SW_ENABLE val |= AFIO_MAPR_SWDP; /* set JTAG-DP disabled and SW-DP enabled */ #else val |= AFIO_MAPR_DISAB; /* set JTAG-DP and SW-DP Disabled */ #endif putreg32(val, STM32_AFIO_MAPR); #endif }
int nuc_configgpio(gpio_cfgset_t cfgset) { uintptr_t base; uint32_t regaddr; uint32_t regval; uint32_t isrc; uint32_t imd; uint32_t ien; uint32_t value; int port; int pin; /* Decode the port and pin. Use the port number to get the GPIO base * address. */ port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); base = NUC_GPIO_CTRL_BASE(port); /* Set the GPIO PMD register */ regaddr = base + NUC_GPIO_PMD_OFFSET; regval = getreg32(regaddr); regval &= ~GPIO_PMD_MASK(pin); switch (cfgset & GPIO_MODE_MASK) { default: case GPIO_INPUT: /* Input */ value = GPIO_PMD_INPUT; break; case GPIO_OUTPUT: /* Push-pull output */ value = GPIO_PMD_OUTPUT; break; case GPIO_OPENDRAIN: /* Open drain output */ value = GPIO_PMD_OPENDRAIN; break; case GPIO_BIDI: /* Quasi bi-directional */ value = GPIO_PMD_BIDI; break; } regval |= GPIO_PMD(pin, value); putreg32(regval, regaddr); /* Check if we need to disable the digital input path */ regaddr = base + NUC_GPIO_OFFD_OFFSET; regval = getreg32(regaddr); regval &= ~GPIO_OFFD(pin); if ((cfgset & GPIO_ANALOG) != 0) { regval |= GPIO_OFFD(pin); } putreg32(regval, regaddr); /* Check if we need to enable debouncing */ regaddr = base + NUC_GPIO_DBEN_OFFSET; regval = getreg32(regaddr); regval &= ~GPIO_DBEN(pin); if ((cfgset & GPIO_DEBOUNCE) != 0) { regval |= GPIO_DBEN(pin); } putreg32(regval, regaddr); /* Configure interrupting pins */ isrc = getreg32(base + NUC_GPIO_ISRC_OFFSET); isrc &= ~GPIO_ISRC(pin); imd = getreg32(base + NUC_GPIO_IMD_OFFSET); imd &= ~GPIO_IMD(pin); ien = getreg32(base + NUC_GPIO_IEN_OFFSET); ien &= ~(GPIO_IF_EN(pin) | GPIO_IR_EN(pin)); switch (cfgset & GPIO_INTERRUPT_MASK) { case GPIO_INTERRUPT_RISING_EDGE: isrc |= GPIO_ISRC(pin); ien |= GPIO_IR_EN(pin); break; case GPIO_INTERRUPT_FALLING_EDGE: isrc |= GPIO_ISRC(pin); ien |= GPIO_IF_EN(pin); break; case GPIO_INTERRUPT_BOTH_EDGES: isrc |= GPIO_ISRC(pin); ien |= (GPIO_IF_EN(pin) | GPIO_IR_EN(pin)); break; case GPIO_INTERRUPT_HIGH_LEVEL: isrc |= GPIO_ISRC(pin); imd |= GPIO_IMD(pin); ien |= GPIO_IR_EN(pin); break; case GPIO_INTERRUPT_LOW_LEVEL: isrc |= GPIO_ISRC(pin); imd |= GPIO_IMD(pin); ien |= GPIO_IF_EN(pin); break; default: break; } putreg32(ien, base + NUC_GPIO_IEN_OFFSET); putreg32(imd, base + NUC_GPIO_IMD_OFFSET); putreg32(isrc, base + NUC_GPIO_ISRC_OFFSET); /* If the pin is an output, set the initial output value */ if ((cfgset & GPIO_MODE_MASK) == GPIO_OUTPUT) { nuc_gpiowrite(cfgset, (cfgset & GPIO_OUTPUT_SET) != 0); } return 0; }