/**
 ******************************************************************************
 * @file           : main.c
 * @author         : Auto-generated by STM32CubeIDE
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */

#include "stm32l073xx.h"

#if !defined(__SOFT_FP__) && defined(__ARM_FP)
  #warning "FPU is not initialized, but the project is compiling for an FPU. Please initialize the FPU before use."
#endif

#define VELIKOST_DAT 1000
uint32_t data1[VELIKOST_DAT];

void prenosDat(uint32_t pocetIteraci)
{
	uint32_t data2[VELIKOST_DAT];

	for(uint32_t x = 0U; x < pocetIteraci; x++)
	{
		for(uint32_t y = 0U; y < VELIKOST_DAT; y++)
		{
			data1[y] = (data2[y])++;
		}
	}
}

void nastavUart(void)
{
	// zapne hodinovy signal pro port A
	RCC->IOPENR |= RCC_IOPENR_IOPAEN;

	// vynuluje nastaveni rezimu PA2, PA3 (vstupni rezim)
	GPIOA->MODER &= ~(GPIO_MODER_MODE2 | GPIO_MODER_MODE3);

	// nastavi  PA2 a PA3 do alternativniho rezimu
	GPIOA->MODER |= (GPIO_MODER_MODE2_1 | GPIO_MODER_MODE3_1);

	// nastavi pinu PA2 a PA3 alternativni rezim 4 - UART
	GPIOA->AFR[0] |= ((4U << GPIO_AFRL_AFSEL2_Pos) | (4U << GPIO_AFRL_AFSEL3_Pos));

	// zapne hodinovy signal pro USART2
	RCC->APB1ENR |= RCC_APB1ENR_USART2EN;

	// 16 MHz / 1667 = 9598 Baud
	USART2->BRR = 218U;

	// nastaveni 7bitove adresy a jeji hodnoty
	USART2->CR2 |= (USART_CR2_ADDM7 | 0xAA << USART_CR2_ADD);

	// povoli USART, odesilani dat, prijem dat a funkci pri odstavenem rezimu
	USART2->CR1 |= (USART_CR1_UE | USART_CR1_TE | USART_CR1_RE | USART_CR1_UESM);
}

void nastavExti13()
{
	// zapne hodinovy signal pro port C
	RCC->IOPENR |= RCC_IOPENR_IOPCEN;

	// nastavi PC13 jako vstupni pin
	GPIOC->MODER &= ~GPIO_MODER_MODE13;

	// zapne hodinovy signal pro System Configuration Controller
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;

	// pripoji externi preruseni 13 na port C
	SYSCFG->EXTICR[3] |= SYSCFG_EXTICR4_EXTI13_PC;

	// nastavi reakci linky 13 na sestupnou hranu signalu
	EXTI->FTSR |= EXTI_FTSR_FT13;

	// povoli externi preruseni linky 13
	EXTI->IMR |= EXTI_IMR_IM13;

	// povoli externi preruseni linky 4 az 15 ARM jadra
	NVIC->ISER[0] |= (1U << EXTI4_15_IRQn);
}

void EXTI4_15_IRQHandler(void)
{
	USART2->TDR = 'x';

	// vynulovani priznaku preruseni
	EXTI->PR |= EXTI_PR_PIF13;

	// vynulovani priznaku preruseni v jadru ARM
	NVIC->ICPR[0] |= (1 << EXTI4_15_IRQn);
}

int main(void)
{
	nastavExti13();

	nastavUart();

	// posle znak
	USART2->TDR = '1';

	// vrati se do spiciho rezimu po opusteni ISR
	//SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;

	// zapni spici rezim probuzeny prerusenim
	asm("wfi");

	// umozni kterekoliv udalosti probuzeni ze spiciho rezimu
	//SCB->SCR |= SCB_SCR_SEVONPEND_Msk;

	// zapni spici rezim probuzeny udalosti
	//asm("wfe");

	// posle znak
	USART2->TDR = '2';

	// cekej, dokud neni znak odeslan
	while((USART2->ISR & USART_ISR_TXE) != USART_ISR_TXE);

	// vymaze priznaky preruseni prijatych dat
	//USART2->RQR |= USART_RQR_RXFRQ;
	//NVIC->ICPR[0] |= (1 << USART2_IRQn);

	asm("wfi");
	//asm("wfe");

	// posle znak
	USART2->TDR = '3';

	while(1);
}
