static inline void sam_pmcsetup(void) { uint32_t regval; /* Enable main oscillator (if it has not already been selected) */ if ((getreg32(SAM_PMC_CKGR_MOR) & PMC_CKGR_MOR_MOSCSEL) == 0) { /* "When the MOSCXTEN bit and the MOSCXTCNT are written in CKGR_MOR to * enable the main oscillator, the MOSCXTS bit in the Power Management * Controller Status Register (PMC_SR) is cleared and the counter starts * counting down on the slow clock divided by 8 from the MOSCXTCNT * value. ... When the counter reaches 0, the MOSCXTS bit is set, * indicating that the main clock is valid." */ putreg32(BOARD_CKGR_MOR, SAM_PMC_CKGR_MOR); sam_pmcwait(PMC_INT_MOSCXTS); } /* "Switch to the main oscillator. The selection is made by writing the * MOSCSEL bit in the Main Oscillator Register (CKGR_MOR). The switch of * the Main Clock source is glitch free, so there is no need to run out * of SLCK, PLLACK or UPLLCK in order to change the selection. The MOSCSELS * bit of the power Management Controller Status Register (PMC_SR) allows * knowing when the switch sequence is done." * * MOSCSELS: Main Oscillator Selection Status * 0 = Selection is done * 1 = Selection is in progress */ putreg32((BOARD_CKGR_MOR | PMC_CKGR_MOR_MOSCSEL), SAM_PMC_CKGR_MOR); sam_pmcwait(PMC_INT_MOSCSELS); /* "Select the master clock. "The Master Clock selection is made by writing * the CSS field (Clock Source Selection) in PMC_MCKR (Master Clock Register). * The prescaler supports the division by a power of 2 of the selected clock * between 1 and 64, and the division by 3. The PRES field in PMC_MCKR programs * the prescaler. Each time PMC_MCKR is written to define a new Master Clock, * the MCKRDY bit is cleared in PMC_SR. It reads 0 until the Master Clock is * established. */ regval = getreg32(SAM_PMC_MCKR); regval &= ~PMC_MCKR_CSS_MASK; regval |= PMC_MCKR_CSS_MAIN; putreg32(regval, SAM_PMC_MCKR); sam_pmcwait(PMC_INT_MCKRDY); #if defined(CONFIG_ARCH_CHIP_SAM4E) /* Setup the maximum value for the PLLAR multiplier. The PMMR register * "defines the maximum value of multiplication factor that can be sent to * PLLA. Any value of the MULA bitfield ... above PLLA_MMAX is saturated * to PLLA_MMAX. */ //putreg32(PMC_PMMR_MASK, SAM_PMC_PMMR); #endif /* Setup PLLA and wait for LOCKA */ putreg32(BOARD_CKGR_PLLAR, SAM_PMC_CKGR_PLLAR); sam_pmcwait(PMC_INT_LOCKA); #ifdef CONFIG_ARCH_CHIP_SAM4CM /* Setup PLLB and wait for LOCKB */ putreg32(BOARD_CKGR_PLLBR, SAM_PMC_CKGR_PLLBR); sam_pmcwait(PMC_INT_LOCKB); #endif #ifdef CONFIG_USBDEV /* Setup UTMI for USB and wait for LOCKU */ #ifdef SAM_PMC_CKGR_UCKR /* This MCU has a USB PLL. Configure the UPLL and wait for it to lock. */ regval = getreg32(SAM_PMC_CKGR_UCKR); regval |= BOARD_CKGR_UCKR; putreg32(regval, SAM_PMC_CKGR_UCKR); sam_pmcwait(PMC_INT_LOCKU); #else /* This board does not have a UPLL. Use the output of PLLA or PLLA * (depending on USBS) and setup the PLL divisor to generate the 48MHz * USB clock. */ regval = (BOARD_PMC_USBS | BOARD_PMC_USBDIV); putreg32(regval, SAM_PMC_USB); #if 0 /* Done in the UDP driver */ /* Set the UDP bit in the SCER register to enable the USB clock output */ regval = getreg32(SAM_PMC_SCER); regval |= PMC_UDP; putreg32(regval, SAM_PMC_SCER); #endif /* 0 */ #endif /* SAM_PMC_CKGR_UCKR */ #endif /* CONFIG_USBDEV */ /* Switch to the fast clock and wait for MCKRDY */ putreg32(BOARD_PMC_MCKR_FAST, SAM_PMC_MCKR); sam_pmcwait(PMC_INT_MCKRDY); putreg32(BOARD_PMC_MCKR, SAM_PMC_MCKR); sam_pmcwait(PMC_INT_MCKRDY); }
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_CCMDATARAM /* CCM data RAM clock enable */ regval |= RCC_AHB1ENR_CCMDATARAMEN; #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; #endif /* CONFIG_STM32_OTGHS */ #ifdef CONFIG_STM32_DMA2D /* DMA2D clock */ regval |= RCC_AHB1ENR_DMA2DEN; #endif putreg32(regval, STM32_RCC_AHB1ENR); /* Enable peripherals */ }
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_SPI4 /* SPI4 clock enable */ regval |= RCC_APB2ENR_SPI4EN; #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 #ifdef CONFIG_STM32_SPI5 /* SPI5 clock enable */ regval |= RCC_APB2ENR_SPI5EN; #endif #ifdef CONFIG_STM32_SPI6 /* SPI6 clock enable */ regval |= RCC_APB2ENR_SPI6EN; #endif #ifdef CONFIG_STM32_LTDC /* LTDC clock enable */ regval |= RCC_APB2ENR_LTDCEN; #endif putreg32(regval, STM32_RCC_APB2ENR); /* Enable peripherals */ }
int up_hardfault(int irq, FAR void *context) { #if defined(CONFIG_DEBUG_HARDFAULT) || !defined(CONFIG_ARMV7M_USEBASEPRI) uint32_t *regs = (uint32_t*)context; #endif /* Get the value of the program counter where the fault occurred */ #ifndef CONFIG_ARMV7M_USEBASEPRI uint16_t *pc = (uint16_t*)regs[REG_PC] - 1; /* Check if the pc lies in known FLASH memory. * REVISIT: What if the PC lies in "unknown" external memory? Best * use the BASEPRI register if you have external memory. */ #ifdef CONFIG_NUTTX_KERNEL /* In the kernel build, SVCalls are expected in either the base, kernel * FLASH region or in the user FLASH region. */ if (((uintptr_t)pc >= (uintptr_t)&_stext && (uintptr_t)pc < (uintptr_t)&_etext) || ((uintptr_t)pc >= (uintptr_t)USERSPACE->us_textstart && (uintptr_t)pc < (uintptr_t)USERSPACE->us_textend)) #else /* SVCalls are expected only from the base, kernel FLASH region */ if ((uintptr_t)pc >= (uintptr_t)&_stext && (uintptr_t)pc < (uintptr_t)&_etext) #endif { /* Fetch the instruction that caused the Hard fault */ uint16_t insn = *pc; hfdbg(" PC: %p INSN: %04x\n", pc, insn); /* If this was the instruction 'svc 0', then forward processing * to the SVCall handler */ if (insn == INSN_SVC0) { hfdbg("Forward SVCall\n"); return up_svcall(irq, context); } } #endif /* Dump some hard fault info */ hfdbg("Hard Fault:\n"); hfdbg(" IRQ: %d regs: %p\n", irq, regs); hfdbg(" BASEPRI: %08x PRIMASK: %08x IPSR: %08x CONTROL: %08x\n", getbasepri(), getprimask(), getipsr(), getcontrol()); hfdbg(" CFAULTS: %08x HFAULTS: %08x DFAULTS: %08x BFAULTADDR: %08x AFAULTS: %08x\n", getreg32(NVIC_CFAULTS), getreg32(NVIC_HFAULTS), getreg32(NVIC_DFAULTS), getreg32(NVIC_BFAULT_ADDR), getreg32(NVIC_AFAULTS)); hfdbg(" R0: %08x %08x %08x %08x %08x %08x %08x %08x\n", regs[REG_R0], regs[REG_R1], regs[REG_R2], regs[REG_R3], regs[REG_R4], regs[REG_R5], regs[REG_R6], regs[REG_R7]); hfdbg(" R8: %08x %08x %08x %08x %08x %08x %08x %08x\n", regs[REG_R8], regs[REG_R9], regs[REG_R10], regs[REG_R11], regs[REG_R12], regs[REG_R13], regs[REG_R14], regs[REG_R15]); #ifdef CONFIG_ARMV7M_USEBASEPRI # ifdef REG_EXC_RETURN hfdbg(" xPSR: %08x BASEPRI: %08x EXC_RETURN: %08x (saved)\n", current_regs[REG_XPSR], current_regs[REG_BASEPRI], current_regs[REG_EXC_RETURN]); # else hfdbg(" xPSR: %08x BASEPRI: %08x (saved)\n", current_regs[REG_XPSR], current_regs[REG_BASEPRI]); # endif #else # ifdef REG_EXC_RETURN hfdbg(" xPSR: %08x PRIMASK: %08x EXC_RETURN: %08x (saved)\n", current_regs[REG_XPSR], current_regs[REG_PRIMASK], current_regs[REG_EXC_RETURN]); # else hfdbg(" xPSR: %08x PRIMASK: %08x (saved)\n", current_regs[REG_XPSR], current_regs[REG_PRIMASK]); # endif #endif (void)irqsave(); lldbg("PANIC!!! Hard fault: %08x\n", getreg32(NVIC_HFAULTS)); PANIC(); return OK; }
void stm32_lowsetup(void) { #if defined(HAVE_UART) uint32_t mapr; #if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) uint32_t cr; #endif /* Enable the selected USARTs and configure GPIO pins need by the * the selected USARTs. NOTE: The serial driver later depends on * this pin configuration -- whether or not a serial console is selected. * * NOTE: Clocking for USART1, USART2, and/or USART3 was already provided in stm32_rcc.c */ mapr = getreg32(STM32_AFIO_MAPR); #ifdef CONFIG_STM32_USART1 /* Assume default pin mapping: * * Alternate USART1_REMAP USART1_REMAP * Function = 0 = 1 * ---------- ------------ ------------ * USART1_TX PA9 PB6 * USART1_RX PA10 PB7 */ #ifdef CONFIG_STM32_USART1_REMAP mapr |= AFIO_MAPR_USART1_REMAP; #else mapr &= ~AFIO_MAPR_USART1_REMAP; #endif putreg32(mapr, STM32_AFIO_MAPR); stm32_configgpio(GPIO_USART1_TX); stm32_configgpio(GPIO_USART1_RX); #endif /* CONFIG_STM32_USART1 */ #ifdef CONFIG_STM32_USART2 /* Assume default pin mapping: * * Alternate USART2_REMAP USART2_REMAP * Function = 0 = 1 * ---------- ------------ ------------ * USART2_CTS PA0 PD3 * USART2_RTS PA1 PD4 * USART2_TX PA2 PD5 * USART2_RX PA3 PD6 * USART3_CK PA4 PD7 */ #ifdef CONFIG_STM32_USART2_REMAP mapr |= AFIO_MAPR_USART2_REMAP; #else mapr &= ~AFIO_MAPR_USART2_REMAP; #endif putreg32(mapr, STM32_AFIO_MAPR); stm32_configgpio(GPIO_USART2_TX); stm32_configgpio(GPIO_USART2_RX); stm32_configgpio(GPIO_USART2_CTS); stm32_configgpio(GPIO_USART2_RTS); #endif /* CONFIG_STM32_USART2 */ #ifdef CONFIG_STM32_USART3 /* Assume default pin mapping: * * Alternate USART3_REMAP[1:0] USART3_REMAP[1:0] USART3_REMAP[1:0] * Function = “00” (no remap) = “01” (partial remap) = “11” (full remap) * ---------_ ------------------ ---------------------- -------------------- * USART3_TX PB10 PC10 PD8 * USART3_RX PB11 PC11 PD9 * USART3_CK PB12 PC12 PD10 * USART3_CTS PB13 PB13 PD11 * USART3_RTS PB14 PB14 PD12 */ mapr &= ~AFIO_MAPR_USART3_REMAP_MASK; #if defined(CONFIG_STM32_USART3_PARTIAL_REMAP) mapr |= AFIO_MAPR_USART3_PARTREMAP; #elif defined(CONFIG_STM32_USART3_FULL_REMAP) mapr |= AFIO_MAPR_USART3_FULLREMAP; #endif putreg32(mapr, STM32_AFIO_MAPR); stm32_configgpio(GPIO_USART3_TX); stm32_configgpio(GPIO_USART3_RX); stm32_configgpio(GPIO_USART3_CTS); stm32_configgpio(GPIO_USART3_RTS); #endif /* CONFIG_STM32_USART3 */ /* Enable and configure the selected console device */ #if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) /* Configure CR2 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); cr &= ~USART_CR2_CLRBITS; cr |= USART_CR2_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); /* Configure CR1 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); cr &= ~USART_CR1_CLRBITS; cr |= USART_CR1_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); /* Configure CR3 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); cr &= ~USART_CR3_CLRBITS; cr |= USART_CR3_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); /* Configure the USART Baud Rate */ putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); /* Enable Rx, Tx, and the USART */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); cr |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE); putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); #endif #endif /* HAVE_UART */ }
static void rtc_waitnotbusy(void) { while ((getreg32(AVR32_RTC_CTRL) & RTC_CTRL_BUSY) != 0); }
void kinetis_pllconfig(void) { uint32_t regval32; uint8_t regval8; /* Transition to FLL Bypassed External (FBE) mode */ #ifdef BOARD_EXTCLOCK /* IRCS = 0 (Internal Reference Clock Select) * LP = 0 (Low Power Select) * EREFS = 0 (External Reference Select) * HGO = 0 (High Gain Oscillator Select) * RANGE = 0 (Oscillator of 32 kHz to 40 kHz) */ putreg8(0, KINETIS_MCG_C2); #else /* Enable external oscillator: * * IRCS = 0 (Internal Reference Clock Select) * LP = 0 (Low Power Select) * EREFS = 1 (External Reference Select) * HGO = 1 (High Gain Oscillator Select) * RANGE = 2 (Oscillator of 8 MHz to 32 MHz) */ putreg8(MCG_C2_EREFS | MCG_C2_HGO | MCG_C2_RANGE_VHIGH, KINETIS_MCG_C2); #endif /* Released latched state of oscillator and GPIO */ regval32 = getreg32(KINETIS_SIM_SCGC4); regval32 |= SIM_SCGC4_LLWU; putreg32(regval32, KINETIS_SIM_SCGC4); regval8 = getreg8(KINETIS_LLWU_CS); regval8 |= LLWU_CS_ACKISO; putreg8(regval8, KINETIS_LLWU_CS); /* Select external oscillator and Reference Divider and clear IREFS to * start the external oscillator. * * IREFSTEN = 0 (Internal Reference Stop Enable) * IRCLKEN = 0 (Internal Reference Clock Enable) * IREFS = 0 (Internal Reference Select) * FRDIV = 3 (FLL External Reference Divider, RANGE!=0 divider=256) * CLKS = 2 (Clock Source Select, External reference clock) */ putreg8(MCG_C1_FRDIV_DIV256 | MCG_C1_CLKS_EXTREF, KINETIS_MCG_C1); /* If we aren't using an oscillator input we don't need to wait for the * oscillator to initialize */ #ifndef BOARD_EXTCLOCK while ((getreg8(KINETIS_MCG_S) & MCG_S_OSCINIT) == 0); #endif /* Wait for Reference clock Status bit to clear */ while ((getreg8(KINETIS_MCG_S) & MCG_S_IREFST) != 0); /* Wait for clock status bits to show that the clock source is the * external reference clock. */ while ((getreg8(KINETIS_MCG_S) & MCG_S_CLKST_MASK) != MCG_S_CLKST_EXTREF); /* We are now in FLL Bypassed External (FBE) mode. Configure PLL * reference clock divider: * * PLLCLKEN = 0 * PLLSTEN = 0 * PRDIV = Determined by PLL reference clock frequency * * Either the external clock or crystal frequency is used to select the * PRDIV value. Only reference clock frequencies are supported that will * produce a 2MHz reference clock to the PLL. */ putreg8(MCG_C5_PRDIV(BOARD_PRDIV), KINETIS_MCG_C5); /* Ensure that MCG_C6 is at the reset default of 0: LOLIE disabled, PLL * disabled, clk monitor disabled, PLL VCO divider cleared. */ putreg8(0, KINETIS_MCG_C6); /* Set system options dividers based on settings from the board.h file. * * MCG = PLL * Core = MCG / BOARD_OUTDIV1 * bus = MCG / BOARD_OUTDIV2 * FlexBus = MCG / BOARD_OUTDIV3 * Flash clock = MCG / BOARD_OUTDIV4 */ kinesis_setdividers(BOARD_OUTDIV1, BOARD_OUTDIV2, BOARD_OUTDIV3, BOARD_OUTDIV4); /* Set the VCO divider, VDIV, is defined in the board.h file. VDIV * selects the amount to divide the VCO output of the PLL. The VDIV bits * establish the multiplication factor applied to the reference clock * frequency. Also set * * LOLIE = 0 (Loss of Lock Interrrupt Enable) * PLLS = 1 (PLL Select) * CME = 0 (Clock Monitor Enable) */ putreg8(MCG_C6_PLLS | MCG_C6_VDIV(BOARD_VDIV), KINETIS_MCG_C6); /* Wait for the PLL status bit to set */ while ((getreg8(KINETIS_MCG_S) & MCG_S_PLLST) == 0); /* Wait for the PLL LOCK bit to set */ while ((getreg8(KINETIS_MCG_S) & MCG_S_LOCK) == 0); /* We are now running in PLL Bypassed External (PBE) mode. Transition to * PLL Engaged External (PEE) mode by setting CLKS to 0 */ regval8 = getreg8(KINETIS_MCG_C1); regval8 &= ~MCG_C1_CLKS_MASK; putreg8(regval8, KINETIS_MCG_C1); /* Wait for clock status bits to update */ while ((getreg8(KINETIS_MCG_S) & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL); /* We are now running in PLL Engaged External (PEE) mode. */ }
static int stm32l4_rnginterrupt(int irq, void *context) { uint32_t rngsr; uint32_t data; rngsr = getreg32(STM32L4_RNG_SR); if (rngsr & RNG_SR_CEIS) /* Check for clock error int stat */ { /* Clear it, we will try again. */ putreg32(rngsr & ~RNG_SR_CEIS, STM32L4_RNG_SR); return OK; } if (rngsr & RNG_SR_SEIS) /* Check for seed error in int stat */ { uint32_t crval; /* Clear seed error, then disable/enable the rng and try again. */ putreg32(rngsr & ~RNG_SR_SEIS, STM32L4_RNG_SR); crval = getreg32(STM32L4_RNG_CR); crval &= ~RNG_CR_RNGEN; putreg32(crval, STM32L4_RNG_CR); crval |= RNG_CR_RNGEN; putreg32(crval, STM32L4_RNG_CR); return OK; } if (!(rngsr & RNG_SR_DRDY)) /* Data ready must be set */ { /* This random value is not valid, we will try again. */ return OK; } data = getreg32(STM32L4_RNG_DR); /* As required by the FIPS PUB (Federal Information Processing Standard * Publication) 140-2, the first random number generated after setting the * RNGEN bit should not be used, but saved for comparison with the next * generated random number. Each subsequent generated random number has to be * compared with the previously generated number. The test fails if any two * compared numbers are equal (continuous random number generator test). */ if (g_rngdev.rd_first) { g_rngdev.rd_first = false; g_rngdev.rd_lastval = data; return OK; } if (g_rngdev.rd_lastval == data) { /* Two subsequent same numbers, we will try again. */ return OK; } /* If we get here, the random number is valid. */ g_rngdev.rd_lastval = data; if (g_rngdev.rd_buflen >= 4) { g_rngdev.rd_buflen -= 4; *(uint32_t *)&g_rngdev.rd_buf[g_rngdev.rd_buflen] = data; } else { while (g_rngdev.rd_buflen > 0) { g_rngdev.rd_buf[--g_rngdev.rd_buflen] = (char)data; data >>= 8; } } if (g_rngdev.rd_buflen == 0) { /* Buffer filled, stop further interrupts. */ stm32l4_rngdisable(); sem_post(&g_rngdev.rd_readsem); } return OK; }
static uint32_t i2c_read(int offset) { return getreg32(I2C_BASE + offset); }
/* Set command delay strategy */ putreg32(MPMC_DYNREADCONFIG_CMDDEL, LPC31_MPMC_DYNREADCONFIG); /* Configure device config register nSDCE0 for proper width SDRAM: * Type: 256Mb (16Mx16), 4 banks, row length=13, column length=9 * Buffer disabled, writes not protected. */ putreg32((MPMC_DYNCONFIG0_MDSDRAM | MPMC_DYNCONFIG_HP16_16MX16), LPC31_MPMC_DYNCONFIG0); /* Disable buffers + writes not protected */ regval = getreg32(LPC31_MPMC_DYNCONFIG0); regval &= ~(MPMC_DYNCONFIG0_B | MPMC_DYNCONFIG0_P); putreg32(regval, LPC31_MPMC_DYNCONFIG0); /* Set RAS/CAS delays*/ putreg32((MPMC_DYNRASCAS0_RAS2CLK | MPMC_DYNRASCAS0_CAS2CLK), LPC31_MPMC_DYNRASCAS0); /* Configure SDRAM timing */ putreg32(lpc31_ns2clk(H3131_SDRAM_TRP, HCLK2), LPC31_MPMC_DYNTRP); putreg32(lpc31_ns2clk(H3131_SDRAM_TRAS, HCLK2), LPC31_MPMC_DYNTRAS); putreg32(lpc31_ns2clk(H3131_SDRAM_TREX, HCLK2), LPC31_MPMC_DYNTSREX); putreg32(H3131_SDRAM_TAPR, LPC31_MPMC_DYNTAPR); putreg32(H3131_SDRAM_TDAL + lpc31_ns2clk(H3131_SDRAM_TRP, HCLK2),
void up_dumpnvic(FAR const char *msg) { #ifdef CONFIG_DEBUG_INFO irqstate_t flags; int i; /* The following requires exclusive access to the NVIC/SYSCON registers */ flags = enter_critical_section(); _info("NVIC: %s\n", msg); _info(" ISER: %08x ICER: %08x ISPR: %08x ICPR: %08x\n", getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER), getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); for (i = 0 ; i < 8; i += 4) { _info(" IPR%d: %08x IPR%d: %08x IPR%d: %08x IPR%d: %08x\n", i, getreg32(ARMV6M_NVIC_IPR(i)), i+1, getreg32(ARMV6M_NVIC_IPR(i+1)), i+2, getreg32(ARMV6M_NVIC_IPR(i+2)), i+3, getreg32(ARMV6M_NVIC_IPR(i+3))); } _info("SYSCON:\n"); _info(" CPUID: %08x ICSR: %08x AIRCR: %08x SCR: %08x\n", getreg32(ARMV6M_SYSCON_CPUID), getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR), getreg32(ARMV6M_SYSCON_SCR)); _info(" CCR: %08x SHPR2: %08x SHPR3: %08x\n", getreg32(ARMV6M_SYSCON_CCR), getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); leave_critical_section(flags); #endif }
static inline uint32_t lpc43_read_RIT_timer(void) { return getreg32(LPC43_RIT_COUNTER); }
void open1788_sdram_initialize(void) { uint32_t regval; int i; /* Reconfigure delays: * * CMDDLY: Programmable delay value for EMC outputs in command delayed * mode. The delay amount is roughly CMDDLY * 250 picoseconds. * FBCLKDLY: Programmable delay value for the feedback clock that controls * input data sampling. The delay amount is roughly (FBCLKDLY+1) * 250 * picoseconds. * CLKOUT0DLY: Programmable delay value for the CLKOUT0 output. This would * typically be used in clock delayed mode. The delay amount is roughly * (CLKOUT0DLY+1) * 250 picoseconds. * CLKOUT1DLY: Programmable delay value for the CLKOUT1 output. This would * typically be used in clock delayed mode. The delay amount is roughly * (CLKOUT1DLY+1) * 250 picoseconds. */ regval = SYSCON_EMCDLYCTL_CMDDLY(32) | SYSCON_EMCDLYCTL_FBCLKDLY(32) | SYSCON_EMCDLYCTL_CLKOUT0DLY(1) | SYSCON_EMCDLYCTL_CLKOUT1DLY(1); putreg32(regval, LPC17_SYSCON_EMCDLYCTL); /* Configure the SDRAM */ putreg32( EMC_NS2CLK(20), LPC17_EMC_DYNAMICRP); /* TRP = 20 nS */ putreg32( 15, LPC17_EMC_DYNAMICRAS); /* RAS = 42ns to 100K ns, */ putreg32( 0, LPC17_EMC_DYNAMICSREX); /* TSREX = 1 clock */ putreg32( 1, LPC17_EMC_DYNAMICAPR); /* TAPR = 2 clocks? */ putreg32(EMC_NS2CLK(20) + 2, LPC17_EMC_DYNAMICDAL); /* TDAL = TRP + TDPL = 20ns + 2clk */ putreg32( 1, LPC17_EMC_DYNAMICWR); /* TWR = 2 clocks */ putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRC); /* H57V2562GTR-75C TRC = 63ns(min)*/ putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRFC); /* H57V2562GTR-75C TRFC = TRC */ putreg32( 15, LPC17_EMC_DYNAMICXSR); /* Exit self-refresh to active */ putreg32( EMC_NS2CLK(63), LPC17_EMC_DYNAMICRRD); /* 3 clock, TRRD = 15ns (min) */ putreg32( 1, LPC17_EMC_DYNAMICMRD); /* 2 clock, TMRD = 2 clocks (min) */ /* Command delayed strategy, using EMCCLKDELAY */ putreg32(EMC_DYNAMICREADCONFIG_RD_CMD, LPC17_EMC_DYNAMICREADCONFIG); /* H57V2562GTR-75C: TCL=3CLK, TRCD = 20ns(min), 3 CLK = 24ns */ putreg32(MDKCFG_RASCAS0VAL, LPC17_EMC_DYNAMICRASCAS0); #ifdef CONFIG_LPC17_SDRAM_16BIT /* For Manley lpc1778 SDRAM: H57V2562GTR-75C, 256Mb, 16Mx16, 4 banks, row=13, column=9: * * 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */ putreg32(EMC_DYNAMICCONFIG_MD_SDRAM | EMC_DYNAMICCONFIG_AM0(13), LPC17_EMC_DYNAMICCONFIG0); #elif defined CONFIG_LPC17_SDRAM_32BIT /* 256Mb, 16Mx16, 4 banks, row=13, column=9, RBC */ putreg32(EMC_DYNAMICCONFIG_MD_SDRAM | EMC_DYNAMICCONFIG_AM0(13) | EMC_DYNAMICCONFIG_AM1, LPC17_EMC_DYNAMICCONFIG0); #endif up_mdelay(100); /* Issue NOP command */ putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_NOP, LPC17_EMC_DYNAMICCONTROL); /* Wait 200 Msec */ up_mdelay(200); /* Issue PALL command */ putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_PALL, LPC17_EMC_DYNAMICCONTROL); putreg32(2, LPC17_EMC_DYNAMICREFRESH); /* ( n * 16 ) -> 32 clock cycles */ /* Wait 128 AHB clock cycles */ for (i = 0; i < 128; i++); /* 64ms/8192 = 7.8125us, nx16x8.33ns < 7.8125us, n < 58.6*/ regval = 64000000 / (1 << 13); regval -= 16; regval >>= 4; regval = regval * LPC17_EMCCLK_MHZ / 1000; putreg32(regval, LPC17_EMC_DYNAMICREFRESH); /* Issue MODE command */ putreg32(EMC_DYNAMICCONTROL_CE | EMC_DYNAMICCONTROL_CS | EMC_DYNAMICCONTROL_I_MODE, LPC17_EMC_DYNAMICCONTROL); #ifdef CONFIG_LPC17_SDRAM_16BIT (void)getreg16(SDRAM_BASE | (0x33 << 12)); /* 8 burst, 3 CAS latency */ #elif defined CONFIG_LPC17_SDRAM_32BIT (void)getreg32(SDRAM_BASE | (0x32 << 13)); /* 4 burst, 3 CAS latency */ #endif /* Issue NORMAL command */ putreg32(EMC_DYNAMICCONTROL_I_NORMAL, LPC17_EMC_DYNAMICCONTROL); /* Enable buffer */ regval = getreg32(LPC17_EMC_DYNAMICCONFIG0); regval |= EMC_DYNAMICCONFIG_B; putreg32(regval, LPC17_EMC_DYNAMICCONFIG0); up_mdelay(12); regval = getreg32(LPC17_SYSCON_EMCDLYCTL); regval &= ~SYSCON_EMCDLYCTL_CMDDLY_MASK; regval |= SYSCON_EMCDLYCTL_CMDDLY(18); putreg32(regval, LPC17_SYSCON_EMCDLYCTL); }
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 mcu123.com 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 * PINSEL1 P0.19/MAT1.2/MOSI1/CAP1.2 Bits 6-7=10 for MOSI1 * PINSEL1 P0.20/MAT1.3/SSEL1/EINT3 Bits 8-9=10 for P0.20 (we'll control it via GPIO or FIO) */ regval32 = getreg32(LPC214X_PINSEL1); regval32 &= ~(LPC214X_PINSEL1_P017_MASK|LPC214X_PINSEL1_P018_MASK| LPC214X_PINSEL1_P019_MASK|LPC214X_PINSEL1_P020_MASK); regval32 |= (LPC214X_PINSEL1_P017_SCK1|LPC214X_PINSEL1_P018_MISO1| LPC214X_PINSEL1_P019_MOSI1|LPC214X_PINSEL1_P020_GPIO); putreg32(regval32, LPC214X_PINSEL1); /* Disable chip select using P0.20 (SSEL1) (low enables) */ regval32 = 1 << 20; putreg32(regval32, CS_SET_REGISTER); regval32 |= getreg32(CS_DIR_REGISTER); putreg32(regval32, 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; }
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; } } /* If this is a value-line part and we are using the HSE as the PLL */ # if defined(CONFIG_STM32_VALUELINE) && (STM32_CFGR_PLLSRC == RCC_CFGR_PLLSRC) # if (STM32_CFGR_PLLXTPRE >> 17) != (STM32_CFGR2_PREDIV1 & 1) # error STM32_CFGR_PLLXTPRE must match the LSB of STM32_CFGR2_PREDIV1 # endif /* Set the HSE prescaler */ regval = STM32_CFGR2_PREDIV1; putreg32(regval, STM32_RCC_CFGR2); # endif #endif /* Value-line devices don't implement flash prefetch/waitstates */ #ifndef CONFIG_STM32_VALUELINE /* Enable FLASH prefetch buffer and 2 wait states */ regval = getreg32(STM32_FLASH_ACR); regval &= ~FLASH_ACR_LATENCY_MASK; regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); 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 */ 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 /* 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 */ stm32_rcc_enablelsi(); #endif }
static inline void sam3u_pmcsetup(void) { uint32_t regval; /* Enable main oscillator (if it has not already been selected) */ if ((getreg32(SAM3U_CKGR_MOR) & CKGR_MOR_MOSCSEL) == 0) { /* "When the MOSCXTEN bit and the MOSCXTCNT are written in CKGR_MOR to * enable the main oscillator, the MOSCXTS bit in the Power Management * Controller Status Register (PMC_SR) is cleared and the counter starts * counting down on the slow clock divided by 8 from the MOSCXTCNT * value. ... When the counter reaches 0, the MOSCXTS bit is set, * indicating that the main clock is valid." */ putreg32(BOARD_CKGR_MOR, SAM3U_CKGR_MOR); sam3u_pmcwait(PMC_INT_MOSCXTS); } /* "Switch to the main oscillator. The selection is made by writing the * MOSCSEL bit in the Main Oscillator Register (CKGR_MOR). The switch of * the Main Clock source is glitch free, so there is no need to run out * of SLCK, PLLACK or UPLLCK in order to change the selection. The MOSCSELS * bit of the power Management Controller Status Register (PMC_SR) allows * knowing when the switch sequence is done." * * MOSCSELS: Main Oscillator Selection Status * 0 = Selection is done * 1 = Selection is in progress */ putreg32((BOARD_CKGR_MOR|CKGR_MOR_MOSCSEL), SAM3U_CKGR_MOR); sam3u_pmcwait(PMC_INT_MOSCSELS); /* "Select the master clock. "The Master Clock selection is made by writing * the CSS field (Clock Source Selection) in PMC_MCKR (Master Clock Register). * The prescaler supports the division by a power of 2 of the selected clock * between 1 and 64, and the division by 3. The PRES field in PMC_MCKR programs * the prescaler. Each time PMC_MCKR is written to define a new Master Clock, * the MCKRDY bit is cleared in PMC_SR. It reads 0 until the Master Clock is * established. */ regval = getreg32(SAM3U_PMC_MCKR); regval &= ~PMC_MCKR_CSS_MASK; regval |= PMC_MCKR_CSS_MAIN; putreg32(regval, SAM3U_PMC_MCKR); sam3u_pmcwait(PMC_INT_MCKRDY); /* Settup PLLA and wait for LOCKA */ putreg32(BOARD_CKGR_PLLAR, SAM3U_CKGR_PLLAR); sam3u_pmcwait(PMC_INT_LOCKA); /* Setup UTMI for USB and wait for LOCKU */ #ifdef CONFIG_USBDEV regval = getreg32(SAM3U_CKGR_UCKR); regval |= BOARD_CKGR_UCKR; putreg32(regval, SAM3U_CKGR_UCKR); sam3u_pmcwait(PMC_INT_LOCKU); #endif /* Switch to the fast clock and wait for MCKRDY */ putreg32(BOARD_PMC_MCKR_FAST, SAM3U_PMC_MCKR); sam3u_pmcwait(PMC_INT_MCKRDY); putreg32(BOARD_PMC_MCKR, SAM3U_PMC_MCKR); sam3u_pmcwait(PMC_INT_MCKRDY); }
static uint32_t tim_getreg(FAR struct stm32_chan_s *chan, int offset) { return getreg32(chan->tbase + offset); }
static inline uint32_t pic32mx_getreg(uintptr_t uart_base, unsigned int offset) { return getreg32(uart_base + offset); }
static void nuc_dumpnvic(const char *msg, int irq) { irqstate_t flags; flags = irqsave(); slldbg("NVIC (%s, irq=%d):\n", msg, irq); slldbg(" ISER: %08x ICER: %08x\n", getreg32(ARMV6M_NVIC_ISER), getreg32(ARMV6M_NVIC_ICER)); slldbg(" ISPR: %08x ICPR: %08x\n", getreg32(ARMV6M_NVIC_ISPR), getreg32(ARMV6M_NVIC_ICPR)); slldbg(" IRQ PRIO: %08x %08x %08x %08x\n", getreg32(ARMV6M_NVIC_IPR0), getreg32(ARMV6M_NVIC_IPR1), getreg32(ARMV6M_NVIC_IPR2), getreg32(ARMV6M_NVIC_IPR3)); slldbg(" %08x %08x %08x %08x\n", getreg32(ARMV6M_NVIC_IPR4), getreg32(ARMV6M_NVIC_IPR5), getreg32(ARMV6M_NVIC_IPR6), getreg32(ARMV6M_NVIC_IPR7)); slldbg("SYSCON:\n"); slldbg(" CPUID: %08x\n", getreg32(ARMV6M_SYSCON_CPUID)); slldbg(" ICSR: %08x AIRCR: %08x\n", getreg32(ARMV6M_SYSCON_ICSR), getreg32(ARMV6M_SYSCON_AIRCR)); slldbg(" SCR: %08x CCR: %08x\n", getreg32(ARMV6M_SYSCON_SCR), getreg32(ARMV6M_SYSCON_CCR)); slldbg(" SHPR2: %08x SHPR3: %08x\n", getreg32(ARMV6M_SYSCON_SHPR2), getreg32(ARMV6M_SYSCON_SHPR3)); irqrestore(flags); }
void up_boot_standby_mode(void) { uint32_t gpio_off_mask; uint32_t regval; int i; DEBUGASSERT((getreg32(STM32_PWR_CR) & PWR_CR_DBP) != 0); /* * This function is called from up_boot.c, stm32_boardinitialize(). OS is not * running yet. Regulators and chip-selects have been initialized. IWDG not * enabled. If board has HWWDG, we must enable it from this function before * going to standby mode. */ regval = getreg32(CONFIG_STANDBYMODE_MAGIC_BKREG); if (regval != CONFIG_STANDBYMODE_MAGIC) { g_board_wakeup_from_standby = (regval == CONFIG_STANDBYMODE_MAGIC + 1); /* Standby mode was not requested, continue with regular boot. */ putreg32(0, CONFIG_STANDBYMODE_MAGIC_BKREG); for (i = 0; i < 4; i++) up_lowputc('r'); return; } #if defined(CONFIG_STM32_DFU) || defined (CONFIG_BOARD_HALTIAN_HWWDG) up_irqinitialize(); #endif /* Go into standby mode. */ putreg32(CONFIG_STANDBYMODE_MAGIC + 1, CONFIG_STANDBYMODE_MAGIC_BKREG); for (i = 0; i < 4; i++) up_lowputc('s'); /* Setup bootloader to jump directly to firmware. */ putreg32(BOARD_FIRMWARE_BASE_ADDR, CONFIG_BOOTLOADER_ADDR_BKREG); /* Now disable backup register access. If following interrupt handlers * access backup registers, they need to make sure to re-enable access. */ stm32_pwr_enablebkp(false); while (true) { /* Configure SDcard pins. */ gpio_initialize_sdcard_pins(); /* Configure display GPIOs. */ gpio_off_mask = ~(GPIO_PUPD_MASK | GPIO_MODE_MASK | GPIO_OUTPUT_SET); stm32_configgpio(GPIO_CHIP_SELECT_DISPLAY); stm32_configgpio(GPIO_LCD_SSD1309_CMDDATA); stm32_configgpio(GPIO_LCD_SSD1309_RESET); stm32_configgpio((GPIO_SPI2_MOSI & gpio_off_mask) | GPIO_OUTPUT_CLEAR | GPIO_OUTPUT); stm32_configgpio((GPIO_SPI2_SCK & 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(); /* We must kick HWWDG even from standby mode, else it resets device. */ board_wdginitialize_autokick(hwwdg_irq_in_standby); /* Setup 'power'-button as EXTI for wake-up. */ stm32_configgpio(GPIO_BTN_POWERKEY); stm32_gpiosetevent(GPIO_BTN_POWERKEY, true, false, true, button_pressed_down_handler); /* Our standby-mode is really ARM core's stop-mode. Enter stop-mode with MCU internal regulator in low-power mode. */ (void)stm32_pmstop(true); standby_do_trace('p'); } }
static void sam_dumpaic(const char *msg, int irq) { irqstate_t flags; flags = irqsave(); lldbg("AIC (%s, irq=%d):\n", msg, irq); /* Select the register set associated with this irq */ putreg32(irq, SAM_AIC_SSR); /* Then dump all of the (readable) register contents */ lldbg(" SSR: %08x SMR: %08x SVR: %08x IVR: %08x\n", getreg32(SAM_AIC_SSR), getreg32(SAM_AIC_SMR), getreg32(SAM_AIC_SVR), getreg32(SAM_AIC_IVR)); lldbg(" FVR: %08x ISR: %08x\n", getreg32(SAM_AIC_FVR), getreg32(SAM_AIC_ISR)); lldbg(" IPR: %08x %08x %08x %08x\n", getreg32(SAM_AIC_IPR0), getreg32(SAM_AIC_IPR1), getreg32(SAM_AIC_IPR2), getreg32(SAM_AIC_IPR3)); lldbg(" IMR: %08x CISR: %08x SPU: %08x FFSR: %08x\n", getreg32(SAM_AIC_IMR), getreg32(SAM_AIC_CISR), getreg32(SAM_AIC_SPU), getreg32(SAM_AIC_FFSR)); lldbg(" DCR: %08x WPMR: %08x WPMR: %08x\n", getreg32(SAM_AIC_DCR), getreg32(SAM_AIC_WPMR), getreg32(SAM_AIC_WPMR)); irqrestore(flags); }
static inline void rcc_enableahb(void) { uint32_t regval; #if defined(CONFIG_STM32_CONNECTIVITYLINE) && defined(CONFIG_STM32_OTGFS) /* USB clock divider for USB OTG FS. This bit must be valid before * enabling the USB clock in the RCC_AHBENR register. This bit can't be * reset if the USB clock is enabled. */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_OTGFSPRE; regval |= STM32_CFGR_OTGFSPRE; putreg32(regval, STM32_RCC_CFGR); #endif /* Always enable FLITF clock and SRAM clock */ regval = RCC_AHBENR_FLITFEN | RCC_AHBENR_SRAMEN; #ifdef CONFIG_STM32_DMA1 /* DMA 1 clock enable */ regval |= RCC_AHBENR_DMA1EN; #endif #ifdef CONFIG_STM32_DMA2 /* DMA 2 clock enable */ regval |= RCC_AHBENR_DMA2EN; #endif #ifdef CONFIG_STM32_CRC /* CRC clock enable */ regval |= RCC_AHBENR_CRCEN; #endif #ifdef CONFIG_STM32_FSMC /* FSMC clock enable */ regval |= RCC_AHBENR_FSMCEN; #endif #ifdef CONFIG_STM32_SDIO /* SDIO clock enable */ regval |= RCC_AHBENR_SDIOEN; #endif #ifdef CONFIG_STM32_CONNECTIVITYLINE #ifdef CONFIG_STM32_OTGFS /* USB OTG FS clock enable */ regval |= RCC_AHBENR_OTGFSEN; #endif #ifdef CONFIG_STM32_ETHMAC /* Ethernet clock enable */ regval |= (RCC_AHBENR_ETHMACEN | RCC_AHBENR_ETHMACTXEN | RCC_AHBENR_ETHMACRXEN); #endif #endif putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ }
static void sam3u_dumpnvic(const char *msg, int irq) { irqstate_t flags; flags = irqsave(); slldbg("NVIC (%s, irq=%d):\n", msg, irq); slldbg(" INTCTRL: %08x VECTAB: %08x\n", getreg32(NVIC_INTCTRL), getreg32(NVIC_VECTAB)); #if 0 slldbg(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n", getreg32(NVIC_SYSHCON_MEMFAULTENA), getreg32(NVIC_SYSHCON_BUSFAULTENA), getreg32(NVIC_SYSHCON_USGFAULTENA), getreg32(NVIC_SYSTICK_CTRL_ENABLE)); #endif slldbg(" IRQ ENABLE: %08x\n", getreg32(NVIC_IRQ0_31_ENABLE)); slldbg(" SYSH_PRIO: %08x %08x %08x\n", getreg32(NVIC_SYSH4_7_PRIORITY), getreg32(NVIC_SYSH8_11_PRIORITY), getreg32(NVIC_SYSH12_15_PRIORITY)); slldbg(" IRQ PRIO: %08x %08x %08x %08x\n", getreg32(NVIC_IRQ0_3_PRIORITY), getreg32(NVIC_IRQ4_7_PRIORITY), getreg32(NVIC_IRQ8_11_PRIORITY), getreg32(NVIC_IRQ12_15_PRIORITY)); slldbg(" %08x %08x %08x %08x\n", getreg32(NVIC_IRQ16_19_PRIORITY), getreg32(NVIC_IRQ20_23_PRIORITY), getreg32(NVIC_IRQ24_27_PRIORITY), getreg32(NVIC_IRQ28_31_PRIORITY)); irqrestore(flags); }
static inline void rcc_enableapb1(void) { uint32_t regval; #ifdef CONFIG_STM32_USB /* USB clock divider for USB FS device. This bit must be valid before * enabling the USB clock in the RCC_APB1ENR register. This bit can't be * reset if the USB clock is enabled. */ regval = getreg32(STM32_RCC_CFGR); regval &= ~RCC_CFGR_USBPRE; regval |= STM32_CFGR_USBPRE; putreg32(regval, STM32_RCC_CFGR); #endif /* 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_TIM12 /* Timer 12 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM12EN; #endif #endif #ifdef CONFIG_STM32_TIM13 /* Timer 13 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM13EN; #endif #endif #ifdef CONFIG_STM32_TIM14 /* Timer 14 clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB1ENR_TIM14EN; #endif #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 */ regval |= RCC_APB1ENR_USART2EN; #endif #ifdef CONFIG_STM32_USART3 /* USART 3 clock enable */ regval |= RCC_APB1ENR_USART3EN; #endif #ifdef CONFIG_STM32_UART4 /* UART 4 clock enable */ regval |= RCC_APB1ENR_UART4EN; #endif #ifdef CONFIG_STM32_UART5 /* UART 5 clock enable */ regval |= RCC_APB1ENR_UART5EN; #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_CAN1 /* CAN1 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 #ifdef CONFIG_STM32_BKP /* Backup interface clock enable */ regval |= RCC_APB1ENR_BKPEN; #endif #ifdef CONFIG_STM32_PWR /* Power interface clock enable */ regval |= RCC_APB1ENR_PWREN; #endif #if defined(CONFIG_STM32_DAC1) || defined(CONFIG_STM32_DAC2) /* DAC interface clock enable */ regval |= RCC_APB1ENR_DACEN; #endif #ifdef CONFIG_STM32_CEC /* CEC clock enable */ regval |= RCC_APB1ENR_CECEN; #endif putreg32(regval, STM32_RCC_APB1ENR); }
void stm32_lowsetup(void) { #if defined(HAVE_UART) #if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) uint32_t cr; #endif /* Enable the selected USARTs and configure GPIO pins need by the * the selected USARTs. NOTE: The serial driver later depends on * this pin configuration -- whether or not a serial console is selected. * * NOTE: Clocking for USART1, USART2, and/or USART3 was already provided in stm32_rcc.c */ #ifdef CONFIG_STM32_USART1 stm32_configgpio(GPIO_USART1_TX); stm32_configgpio(GPIO_USART1_RX); # ifdef GPIO_USART1_CTS stm32_configgpio(GPIO_USART1_CTS); stm32_configgpio(GPIO_USART1_RTS); # endif #endif #ifdef CONFIG_STM32_USART2 stm32_configgpio(GPIO_USART2_TX); stm32_configgpio(GPIO_USART2_RX); # ifdef GPIO_USART2_CTS stm32_configgpio(GPIO_USART2_CTS); stm32_configgpio(GPIO_USART2_RTS); # endif #endif #ifdef CONFIG_STM32_USART3 stm32_configgpio(GPIO_USART3_TX); stm32_configgpio(GPIO_USART3_RX); # ifdef GPIO_USART3_CTS stm32_configgpio(GPIO_USART3_CTS); stm32_configgpio(GPIO_USART3_RTS); # endif #endif #ifdef CONFIG_STM32_UART4 stm32_configgpio(GPIO_UART4_TX); stm32_configgpio(GPIO_UART4_RX); #endif #ifdef CONFIG_STM32_UART5 stm32_configgpio(GPIO_UART5_TX); stm32_configgpio(GPIO_UART5_RX); #endif #ifdef CONFIG_STM32_USART6 stm32_configgpio(GPIO_USART6_TX); stm32_configgpio(GPIO_USART6_RX); # ifdef GPIO_USART6_CTS stm32_configgpio(GPIO_USART6_CTS); stm32_configgpio(GPIO_USART6_RTS); # endif #endif /* Enable and configure the selected console device */ #if defined(HAVE_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) /* Configure CR2 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); cr &= ~USART_CR2_CLRBITS; cr |= USART_CR2_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR2_OFFSET); /* Configure CR1 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); cr &= ~USART_CR1_CLRBITS; cr |= USART_CR1_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); /* Configure CR3 */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); cr &= ~USART_CR3_CLRBITS; cr |= USART_CR3_SETBITS; putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR3_OFFSET); /* Configure the USART Baud Rate */ putreg32(STM32_BRR_VALUE, STM32_CONSOLE_BASE + STM32_USART_BRR_OFFSET); /* Enable Rx, Tx, and the USART */ cr = getreg32(STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); cr |= (USART_CR1_UE|USART_CR1_TE|USART_CR1_RE); putreg32(cr, STM32_CONSOLE_BASE + STM32_USART_CR1_OFFSET); #endif #endif /* HAVE_UART */ }
static inline void rcc_enableapb2(void) { uint32_t regval; /* Set the appropriate bits in the APB2ENR register to enabled the * selected APB2 peripherals. */ /* Enable GPIOA, GPIOB, ... and AFIO clocks */ regval = getreg32(STM32_RCC_APB2ENR); regval |= (RCC_APB2ENR_AFIOEN #if STM32_NGPIO > 0 | RCC_APB2ENR_IOPAEN #endif #if STM32_NGPIO > 16 | RCC_APB2ENR_IOPBEN #endif #if STM32_NGPIO > 32 | RCC_APB2ENR_IOPCEN #endif #if STM32_NGPIO > 48 | RCC_APB2ENR_IOPDEN #endif #if STM32_NGPIO > 64 | RCC_APB2ENR_IOPEEN #endif #if STM32_NGPIO > 80 | RCC_APB2ENR_IOPFEN #endif #if STM32_NGPIO > 96 | RCC_APB2ENR_IOPGEN #endif ); #ifdef CONFIG_STM32_ADC1 /* ADC 1 interface clock enable */ regval |= RCC_APB2ENR_ADC1EN; #endif #ifdef CONFIG_STM32_ADC2 /* ADC 2 interface clock enable */ regval |= RCC_APB2ENR_ADC2EN; #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_TIM8 /* TIM8 Timer clock enable */ #ifdef CONFIG_STM32_FORCEPOWER regval |= RCC_APB2ENR_TIM8EN; #endif #endif #ifdef CONFIG_STM32_USART1 /* USART1 clock enable */ regval |= RCC_APB2ENR_USART1EN; #endif #ifdef CONFIG_STM32_ADC3 /* ADC3 interface clock enable */ regval |= RCC_APB2ENR_ADC3EN; #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 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 /* 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 #ifdef CONFIG_STM32_UART7 /* UART7 clock enable */ regval |= RCC_APB1ENR_UART7EN; #endif #ifdef CONFIG_STM32_UART8 /* UART8 clock enable */ regval |= RCC_APB1ENR_UART8EN; #endif putreg32(regval, STM32_RCC_APB1ENR); /* Enable peripherals */ }
static void stm32_stdclockconfig(void) { uint32_t regval; /* Enable 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); /* Set flash wait states * Sysclk runs with 72MHz -> 2 waitstates. * 0WS from 0-24MHz * 1WS from 24-48MHz * 2WS from 48-72MHz */ regval = getreg32(STM32_FLASH_ACR); regval &= ~FLASH_ACR_LATENCY_MASK; regval |= (FLASH_ACR_LATENCY_2 | FLASH_ACR_PRTFBE); putreg32(regval, STM32_FLASH_ACR); /* Set up PLL input scaling (with source = PLL2) */ regval = getreg32(STM32_RCC_CFGR2); regval &= ~(RCC_CFGR2_PREDIV2_MASK | RCC_CFGR2_PLL2MUL_MASK | RCC_CFGR2_PREDIV1SRC_MASK | RCC_CFGR2_PREDIV1_MASK); regval |= (STM32_PLL_PREDIV2 | STM32_PLL_PLL2MUL | RCC_CFGR2_PREDIV1SRC_PLL2 | STM32_PLL_PREDIV1); putreg32(regval, STM32_RCC_CFGR2); /* Set the PCLK2 divider */ regval = getreg32(STM32_RCC_CFGR); regval &= ~(RCC_CFGR_PPRE2_MASK | RCC_CFGR_HPRE_MASK); regval |= STM32_RCC_CFGR_PPRE2; regval |= RCC_CFGR_HPRE_SYSCLK; 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); /* Enable PLL2 */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLL2ON; putreg32(regval, STM32_RCC_CR); /* Wait for PLL2 ready */ while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL2RDY) == 0); #if defined(CONFIG_STM32_MII_MCO) || defined(CONFIG_STM32_RMII_MCO) /* Setup PLL3 for MII/RMII clock on MCO */ regval = getreg32(STM32_RCC_CFGR2); regval &= ~(RCC_CFGR2_PLL3MUL_MASK); regval |= STM32_PLL_PLL3MUL; putreg32(regval, STM32_RCC_CFGR2); /* Switch PLL3 on */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLL3ON; putreg32(regval, STM32_RCC_CR); while ((getreg32(STM32_RCC_CR) & RCC_CR_PLL3RDY) == 0); #endif /* Set main PLL source and multiplier */ regval = getreg32(STM32_RCC_CFGR); regval &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL_MASK); regval |= (RCC_CFGR_PLLSRC | STM32_PLL_PLLMUL); putreg32(regval, STM32_RCC_CFGR); /* Switch main PLL on */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLLON; putreg32(regval, STM32_RCC_CR); while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLRDY) == 0); /* Select 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 PLL is used as the system clock source */ while ((getreg32(STM32_RCC_CFGR) & RCC_CFGR_SWS_PLL) == 0); }
static void stm32_stdclockconfig(void) { uint32_t regval; volatile int32_t timeout; #ifdef STM32_BOARD_USEHSI /* Enable Internal High-Speed Clock (HSI) */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_HSION; /* Enable HSI */ putreg32(regval, STM32_RCC_CR); /* Wait until the HSI is ready (or until a timeout elapsed) */ for (timeout = HSIRDY_TIMEOUT; timeout > 0; timeout--) { /* Check if the HSIRDY flag is the set in the CR */ if ((getreg32(STM32_RCC_CR) & RCC_CR_HSIRDY) != 0) { /* If so, then break-out with timeout > 0 */ break; } } #else /* if STM32_BOARD_USEHSE */ /* 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; } } #endif /* 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_MASK; regval |= PWR_CR_VOS_SCALE_1; 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 */ #ifdef STM32_BOARD_USEHSI regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN |STM32_PLLCFG_PLLP | RCC_PLLCFG_PLLSRC_HSI | STM32_PLLCFG_PLLQ); #else /* if STM32_BOARD_USEHSE */ regval = (STM32_PLLCFG_PLLM | STM32_PLLCFG_PLLN |STM32_PLLCFG_PLLP | RCC_PLLCFG_PLLSRC_HSE | STM32_PLLCFG_PLLQ); #endif 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) { } #if defined(CONFIG_STM32_STM32F429) /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ regval = getreg32(STM32_PWR_CR); regval |= PWR_CR_ODEN; putreg32(regval, STM32_PWR_CR); while ((getreg32(STM32_PWR_CSR) & PWR_CSR_ODRDY) == 0) { } regval = getreg32(STM32_PWR_CR); regval |= PWR_CR_ODSWEN; putreg32(regval, STM32_PWR_CR); while ((getreg32(STM32_PWR_CSR) & PWR_CSR_ODSWRDY) == 0) { } #endif /* 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) { } #ifdef CONFIG_STM32_LTDC /* Configure PLLSAI */ regval = getreg32(STM32_RCC_PLLSAICFGR); regval |= (STM32_RCC_PLLSAICFGR_PLLSAIN | STM32_RCC_PLLSAICFGR_PLLSAIR | STM32_RCC_PLLSAICFGR_PLLSAIQ); putreg32(regval, STM32_RCC_PLLSAICFGR); regval = getreg32(STM32_RCC_DCKCFGR); regval |= STM32_RCC_DCKCFGR_PLLSAIDIVR; putreg32(regval, STM32_RCC_DCKCFGR); /* Enable PLLSAI */ regval = getreg32(STM32_RCC_CR); regval |= RCC_CR_PLLSAION; putreg32(regval, STM32_RCC_CR); /* Wait until the PLLSAI is ready */ while ((getreg32(STM32_RCC_CR) & RCC_CR_PLLSAIRDY) == 0) { } #endif #if defined(CONFIG_STM32_IWDG) || defined(CONFIG_RTC_LSICLOCK) /* Low speed internal clock source LSI */ 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 MCO1 pin selects LSE as source. */ stm32_rcc_enablelse(); #endif } }