/**
******************************************************************************************************************************************************************************************
*@file                       cpu.c
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "cpu_nvic.h"



#define AIRCR_VECTKEY_MASK    ((uint32_t)0x05FA0000)


/**
  * @brief  Configures the priority grouping: pre-emption priority and subpriority.
  * @param  nvic_priority_group: specifies the priority grouping bits length. 
  *   This parameter can be one of the following values:
  *     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
  *                                4 bits for subpriority
  *     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
  *                                3 bits for subpriority
  *     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
  *                                2 bits for subpriority
  *     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
  *                                1 bits for subpriority
  *     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
  *                                0 bits for subpriority
  * @retval None
  */
void nvic_priority_group_config(uint32_t nvic_priority_group)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(nvic_priority_group));
  
  /* Set the PRIGROUP[10:8] bits according to nvic_priority_group value */
  SCB->AIRCR = AIRCR_VECTKEY_MASK | nvic_priority_group;
}

/**
  * @brief  Initializes the NVIC peripheral according to the specified
  *   parameters in the nvic_init_struct.
  * @param  nvic_init_struct: pointer to a nvic_init_type_def structure that contains
  *   the configuration information for the specified NVIC peripheral.
  * @retval None
  */
void nvic_init(nvic_init_type_def* nvic_init_struct)
{
  uint32_t tmp_priority ,tmp_priority_grouping;
  
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(nvic_init_struct->nvic_irq_channel_cmd));
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(nvic_init_struct->nvic_irq_channel_preemption_priority));  
  assert_param(IS_NVIC_SUB_PRIORITY(nvic_init_struct->nvic_irq_channel_subpriority));
    
  if (nvic_init_struct->nvic_irq_channel_cmd != DISABLE)
  {
    /* Compute the Corresponding IRQ Priority --------------------------------*/    
		tmp_priority_grouping = NVIC_GetPriorityGrouping();
		tmp_priority = NVIC_EncodePriority(tmp_priority_grouping,nvic_init_struct->nvic_irq_channel_preemption_priority,\
		nvic_init_struct->nvic_irq_channel_subpriority);
		NVIC_SetPriority((IRQn_Type)nvic_init_struct->nvic_irq_channel,tmp_priority);
    
    /* Enable the Selected IRQ Channels --------------------------------------*/
		NVIC_EnableIRQ((IRQn_Type)nvic_init_struct->nvic_irq_channel);    
  }
  else
  {
    /* Disable the Selected IRQ Channels -------------------------------------*/
    NVIC_DisableIRQ((IRQn_Type)nvic_init_struct->nvic_irq_channel);
  }
}

/**
  * @brief  Sets the vector table location and offset.
  * @param  nvic_vect_tab: specifies if the vector table is in RAM or FLASH memory.
  *   This parameter can be one of the following values:
  *     @arg NVIC_VectTab_RAM
  *     @arg NVIC_VectTab_FLASH
  * @param  offset: Vector Table base offset field. This value must be a multiple of 0x100.
  * @retval None
  */
void nvic_set_vector_table(uint32_t nvic_vect_tab, uint32_t offset)
{ 
  /* Check the parameters */
  assert_param(IS_NVIC_VECTTAB(nvic_vect_tab));
  assert_param(IS_NVIC_OFFSET(offset));  
   
  SCB->VTOR = nvic_vect_tab | (offset & (uint32_t)0x1FFFFF80);
}


