#include "stm32f4_discovery.h"
#include "stm32f4xx_conf.h" // again, added because ST didn't put it here ?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

GPIO_InitTypeDef  GPIO_InitStructure;


void print(USART_TypeDef* USARTx, char *t)
{
while(*t)
	{
	//assert_param(IS_USART_ALL_PERIPH(USARTx));
	//  assert_param(IS_USART_DATA(Data));
	while((USARTx->SR & USART_FLAG_TC)==0);
  	USARTx->DR = *t++;
	}
}


void scan(USART_TypeDef* USARTx, char *string)
{
char c;
        do      {
                do {
			while((USARTx->SR & USART_FLAG_RXNE)==0);
                        c = USARTx->DR;
                        } while ((USARTx->SR & USART_FLAG_FE)==1);
                *string++ = c;
		while((USARTx->SR & USART_FLAG_TC)==0);
		USARTx->DR = c;
                } while ( c != '\r' );
	while((USARTx->SR & USART_FLAG_TC)==0);
	USARTx->DR = '\n';
        string[-1]=0;
}


usart2_init(uint32_t baud)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //for USART1 and USART6
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //for USART2, USART3, UART4 or UART5

/* GPIOA clock enable */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

/* GPIOA Configuration:  USART2 TX on PA2, RX on PA3 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 


/* Connect USART2 pins to AF */ 
	// TX = PA2, RX = PA3
 	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
 	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
	USART_InitStructure.USART_BaudRate = baud;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);

	USART_Cmd(USART2, ENABLE); // enable USART2
}


int main(void)
{
usart2_init(115200);

RCC_ClocksTypeDef RCC_ClocksStatus;

char c[64];

//USART_SetPrescaler(USART2,1);
  while (1)
  {

RCC_GetClocksFreq(&RCC_ClocksStatus);
  print(USART2, "uart testik\n"); 
sprintf(c,"HSE_VALUE %u HSI_VALUE %u\n",HSE_VALUE,HSI_VALUE); print(USART2,c);

sprintf(c,"RCC->CFGR & RCC_CFGR_SWS %d\n",RCC->CFGR & RCC_CFGR_SWS); print(USART2,c);
uint32_t pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
uint32_t pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
uint32_t plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN)>>6;
uint32_t pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
uint32_t pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
sprintf(c,"pllsource %u\n",pllsource); print(USART2,c);
sprintf(c,"pllm %u plln %u pllp %u\n",pllm,plln,pllp); print(USART2,c);
sprintf(c,"pllvco %u\n",pllvco); print(USART2,c);
sprintf(c,"FINAL = pllvco/pllp %u\n",pllvco/pllp); print(USART2,c);

sprintf(c,"SYSCLK_Frequency %u\n",RCC_ClocksStatus.SYSCLK_Frequency); print(USART2,c);
sprintf(c,"HCLK_Frequency %u\n",RCC_ClocksStatus.HCLK_Frequency); print(USART2,c);
sprintf(c,"PCLK1_Frequency %u\n",RCC_ClocksStatus.PCLK1_Frequency); print(USART2,c);
sprintf(c,"PCLK2_Frequency %u\n",RCC_ClocksStatus.PCLK2_Frequency); print(USART2,c);
    
print(USART2,"Enter text: ");
scan(USART2,c);
print(USART2,"Your input was: "); print(USART2,c); print(USART2,"\n");
  }
}

void _sbrk(void) {}

