//--------------------------------------------------------------
// File     : stm32_ub_system.c
// Datum    : 02.08.2015
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F746
// IDE      : OpenSTM32
// GCC      : 4.9 2015q2
// Module   : CubeHAL
// Funktion : System Funktionen
//--------------------------------------------------------------


//--------------------------------------------------------------
// Includes
//--------------------------------------------------------------
#include "stm32_ub_system.h"



//--------------------------------------------------------------
// interne Funktionen
//--------------------------------------------------------------
static void P_MPU_Config(void);
static void P_CPU_CACHE_ENABLE(void);
static void P_SystemClock_Config(void);


//--------------------------------------------------------------
// init vom System
//--------------------------------------------------------------
void UB_System_Init(void)
{
  P_MPU_Config();

  P_CPU_CACHE_ENABLE();
  HAL_Init();
  P_SystemClock_Config();
}


//--------------------------------------------------------------
// einschalten vom Clock eines Ports
// LED_PORT : [GPIOA bis GPIOK]
//--------------------------------------------------------------
void UB_System_ClockEnable(GPIO_TypeDef* LED_PORT)
{
  if(LED_PORT==GPIOA) __GPIOA_CLK_ENABLE();
  if(LED_PORT==GPIOB) __GPIOB_CLK_ENABLE();
  if(LED_PORT==GPIOC) __GPIOC_CLK_ENABLE();
  if(LED_PORT==GPIOD) __GPIOD_CLK_ENABLE();
  if(LED_PORT==GPIOE) __GPIOE_CLK_ENABLE();
  if(LED_PORT==GPIOF) __GPIOF_CLK_ENABLE();
  if(LED_PORT==GPIOG) __GPIOG_CLK_ENABLE();
  if(LED_PORT==GPIOH) __GPIOH_CLK_ENABLE();
  if(LED_PORT==GPIOI) __GPIOI_CLK_ENABLE();
  if(LED_PORT==GPIOJ) __GPIOJ_CLK_ENABLE();
  if(LED_PORT==GPIOK) __GPIOK_CLK_ENABLE();
}

//--------------------------------------------------------------
// Delay in ms
//--------------------------------------------------------------
void HAL_Delay(__IO uint32_t Delay)
{
  while(Delay)
  {
    if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
    {
      Delay--;
    }
  }
}

//--------------------------------------------------------------
// interne Funktion
//--------------------------------------------------------------
static void P_MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct;

  /* Disable the MPU */
  HAL_MPU_Disable();

  /* Configure the MPU attributes as WT for SRAM */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.BaseAddress = 0x20010000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256KB;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.SubRegionDisable = 0x00;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

  HAL_MPU_ConfigRegion(&MPU_InitStruct);

  /* Enable the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

//--------------------------------------------------------------
// interne Funktion
//--------------------------------------------------------------
static void P_CPU_CACHE_ENABLE(void)
{
  /* Invalidate I-Cache : ICIALLU register*/
  SCB_InvalidateICache();

  /* Enable branch prediction */
  SCB->CCR |= (1 <<18);
  __DSB();

  /* Enable I-Cache */
  SCB_EnableICache();

  /* Enable D-Cache */
  SCB_InvalidateDCache();
  SCB_EnableDCache();
}

//--------------------------------------------------------------
// interne Funktion
//--------------------------------------------------------------
/*
static void P_SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;

  // Enable Power Control clock
  __HAL_RCC_PWR_CLK_ENABLE();

  // The voltage scaling allows optimizing the power consumption when the device is
  //   clocked below the maximum system frequency, to update the voltage scaling value
  //   regarding system frequency refer to product datasheet.
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  // Enable HSE Oscillator and activate PLL with HSE as source
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 400;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 8;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);


  // activate the OverDrive to reach the 180 Mhz Frequency
   HAL_PWREx_ActivateOverDrive();

  // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
}
*/

static void P_SystemClock_Config(void)
{
	  RCC_ClkInitTypeDef RCC_ClkInitStruct;
	  RCC_OscInitTypeDef RCC_OscInitStruct;

	  // Enable HSE Oscillator and activate PLL with HSE as source
	  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
	  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	  RCC_OscInitStruct.PLL.PLLM = 25;
	  RCC_OscInitStruct.PLL.PLLN = 432;
	  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	  RCC_OscInitStruct.PLL.PLLQ = 9;
	  HAL_RCC_OscConfig(&RCC_OscInitStruct);

	  // Activate the OverDrive to reach the 216 MHz Frequency
	  HAL_PWREx_EnableOverDrive();

	  // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
	  RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
	  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

	  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);
}


//--------------------------------------------------------------
void NMI_Handler(void)
{
}
//--------------------------------------------------------------
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}
//--------------------------------------------------------------
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}
//--------------------------------------------------------------
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}
//--------------------------------------------------------------
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}
//--------------------------------------------------------------
void SVC_Handler(void)
{
}
//--------------------------------------------------------------
void DebugMon_Handler(void)
{
}
//--------------------------------------------------------------
void PendSV_Handler(void)
{
}

