#include<libopencm3/stm32/rcc.h>
#include<libopencm3/stm32/flash.h>
#include<libopencm3/stm32/gpio.h>

int main(void){
	int i;
	int j;
	int k;
	rcc_osc_on(RCC_HSE);
	rcc_wait_for_osc_ready(RCC_HSE);
	rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK);

	rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8);
	rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2);
	flash_set_ws(FLASH_ACR_LATENCY_2WS); // ???

	rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK);
	rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9);
	//rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL7); // 56e6
	rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); // ???
	rcc_osc_on(RCC_PLL);
	rcc_wait_for_osc_ready(RCC_PLL);
	rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK);
	rcc_osc_off(RCC_HSI);
	//rcc_clock_setup_in_hse_8mhz_out_72mhz();
	rcc_periph_clock_enable(RCC_GPIOA);
	rcc_periph_clock_enable(RCC_GPIOB);
	gpio_set(GPIOA,GPIO0|GPIO1|GPIO2);
	gpio_clear(GPIOA,GPIO7);
	gpio_set_mode(GPIOA,GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
		GPIO0|GPIO1|GPIO2|GPIO7);

	gpio_clear(GPIOB,GPIO6|GPIO7|GPIO8|GPIO9);
	gpio_set_mode(GPIOB,GPIO_MODE_OUTPUT_2_MHZ, GPIO_CNF_OUTPUT_PUSHPULL,
		GPIO6|GPIO7|GPIO8|GPIO9);
	
	//j=800000;
	j=1600000;
	void wait(){
//		gpio_set(GPIOB,GPIO3); gpio_clear(GPIOB,GPIO4);
//		gpio_set(GPIOB,GPIO5);// gpio_clear(GPIOB,GPIO4);
		for(i=0;i<j>>3;i++) {
			gpio_set(GPIOB,GPIO6|GPIO8);
			gpio_clear(GPIOB,GPIO7|GPIO9);
			for(k=0;k<8;k++) 
				__asm__("nop");
			gpio_clear(GPIOB,GPIO6|GPIO8);
			gpio_set(GPIOB,GPIO7|GPIO9);
			for(k=0;k<8;k++) 
				__asm__("nop");
		}
//		gpio_clear(GPIOB,GPIO3); gpio_set(GPIOB,GPIO4);
//		gpio_clear(GPIOB,GPIO5); // gpio_set(GPIOB,GPIO4);
	}


	while(1){
		gpio_clear(GPIOA,GPIO2);
		wait();
		gpio_set(GPIOA,GPIO1);
		wait();
		gpio_clear(GPIOA,GPIO0);
		wait();
		gpio_set(GPIOA,GPIO2);
		wait();
		gpio_clear(GPIOA,GPIO1);
		wait();
		gpio_set(GPIOA,GPIO0);
		wait();
	}
	return 0;
}
