/**
 ******************************************************************************
 * @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
 *
 ******************************************************************************
 */

#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

#include "stm32l073xx.h"

#define DELKA_DAT 9000

// zdrojove a cilove pole dat
uint8_t DMADataZdroj[DELKA_DAT];
uint8_t DMADataCil[DELKA_DAT];

void nastavDMA()
{
    // zapne hodinovy signal pro DMA
    RCC->AHBENR |= RCC_AHBENR_DMAEN;

    // nastavi DMA kanalu 1 na prenost z pameti do pameti, inkremetaci adresy pameti i
    // periferie (v tomto pripade take pamet), velikost dat 8 bitu (pameti i periferie)
    // a povoli preruseni pri prenosu vsech dat
    DMA1_Channel1->CCR |= (DMA_CCR_MEM2MEM | DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_TCIE);

    // velikost dat 32 bitu (pameti i periferie)
    DMA1_Channel1->CCR |= (DMA_CCR_MSIZE_1 | DMA_CCR_PSIZE_1);

    // povoli linku preruseni DMA ARM jadra
    NVIC->ISER[0] |= (1 << DMA1_Channel1_IRQn);
}

void prenosDMA(void* DMADataZdroj, void* DMADataCil, uint16_t delka)
{
    // nastavi pocet dat k prenosu
    DMA1_Channel1->CNDTR = delka;

    // nastavi zdrojovou adresu dat
    DMA1_Channel1->CPAR = DMADataZdroj;

    // nastavi cilovou adresu dat
    DMA1_Channel1->CMAR = DMADataCil;

    // zapne DMA
    DMA1_Channel1->CCR |= DMA_CCR_EN;
}

void DMA1_Channel1_IRQHandler(void)
{
	// vynuluje priznak preruseni
	DMA1->IFCR |= (DMA_IFCR_CTCIF1 | DMA_IFCR_CGIF1);

	// vypne DMA
	DMA1_Channel1->CCR &= ~DMA_CCR_EN;

    // prenos uint8_t
    //prenosDMA(DMADataZdroj, DMADataCil, DELKA_DAT);

    // prenos jako uint32_t
    prenosDMA(DMADataZdroj, DMADataCil, DELKA_DAT/4);
}

int main(void)
{
	// reset nastaveni vicerychlostniho oscilatoru
	//RCC->ICSCR &= ~(RCC_ICSCR_MSIRANGE_Msk);

	// nastavi kmitocet vicerychlostniho oscilatoru na 4 MHz
	//RCC->ICSCR |= ((6 << RCC_ICSCR_MSIRANGE_Pos) & RCC_ICSCR_MSIRANGE_Msk);

    // priprava zdrojovych dat
    for(uint32_t index = 0U; index < DELKA_DAT; index++)
    {
    	DMADataZdroj[index] = index;
    }

    nastavDMA();

    // prenos uint8_t
    prenosDMA(DMADataZdroj, DMADataCil, DELKA_DAT);

    // prenos jako uint32_t
    //prenosDMA(DMADataZdroj, DMADataCil, DELKA_DAT/4);

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

    asm("wfi");

    while(1)
    {
    	// prenos uint8_t
    	/*for(uint32_t index = 0U; index < DELKA_DAT; index++)
		{
			DMADataCil[index] = DMADataZdroj[index];
		}*/

    	// prenos jako uint32_t
        /*for(uint32_t index = 0U; index < DELKA_DAT; index+= 4)
        {
        	*(uint32_t*)(&DMADataCil[index]) = *((uint32_t*)(&DMADataZdroj[index]));
        }*/
    }
}
