shithub: p9-stm32-example-bare

ref: 385ecf9c11ba7114801e877090951e1785698051
dir: /clock.c/

View raw version
#include	<u.h>
#include	"dat.h"
#include	"fns.h"
#include	"include/stm32f103xb.h"

/*
 * SYSCLK has PLL as a source. The PLL is driven by the HSE,
 * with a x4 multiplier. The crystal is 8MHz, meaning,
 * 32MHz system ticks.
 */

void
clockinit()
{
	/* configure AHB and APB GPIO ports */
	RCC->APB1ENR |=	RCC_APB1ENR_USART2EN;		// USART2
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN		|	// PORTA
					RCC_APB2ENR_IOPCEN		|	// PORTC
					RCC_APB2ENR_USART1EN	|	// USART1
					RCC_APB2ENR_AFIOEN;			// AFIO
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;			// DMA

	/* Clear CIR flags */
	RCC->CIR =  RCC_CIR_HSIRDYF	|
				RCC_CIR_HSERDYF	|
				RCC_CIR_PLLRDYF	|
				RCC_CIR_CSSF	|
				RCC_CIR_CSSC;

	/* Set HSEON bit */
	RCC->CR = RCC_CR_HSEON;
	while(!(RCC->CR | RCC_CR_HSERDY));

	/* configure, enable PLL and wait */
	RCC->CFGR = RCC_CFGR_PLLSRC		|	// PLL source
				RCC_CFGR_PLLMULL6	|	// PLL multiplication x6
				RCC_CFGR_PPRE1_DIV2	|	// PPRE1 not divided
				RCC_CFGR_PPRE2_DIV2	|	// PPRE2 not divided
				RCC_CFGR_HPRE_DIV1;		// HPRE divided by 2

	RCC->CR |= RCC_CR_PLLON;
	while(!(RCC->CR & RCC_CR_PLLRDY));

	/* select PLL as clock source */
	RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_PLL) | RCC_CFGR_SW_PLL;
	while(!(RCC->CFGR & RCC_CFGR_SWS_PLL));
}

void
_wait(ulong useconds)
{
	// Since each tick is 1/64MHz = 7.8 
	for(int i = 0; i < useconds; i++) {
		for(int j = 0; j < 12; j++);
	}
}