
/******************************************************************************
*@file  : acm32g103_core.h
*@brief : This file provides set of firmware functions to manage Leds and 
*         push-button available on ACM32G103 Core Board
******************************************************************************/

#include "acm32g103_coreboard.h"



#define BSP_UARTx   (UART2)

/******************************************************************************
*@brief : LED init
*@param : none
*@return: none
******************************************************************************/
void BSP_LED_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;

    /* Enable the GPIO_LED Clock */
    BSP_LED_CLK_ENABLE();

    GPIO_InitStruct.Pin       = BSP_LED_PIN;
    GPIO_InitStruct.Mode      = BSP_LED_MODE;
    GPIO_InitStruct.Pull      = BSP_LED_PULL;
    GPIO_InitStruct.Drive     = BSP_LED_DRIVE;
    GPIO_InitStruct.Alternate = BSP_LED_ALTERNATE;

    GPIO_Init(BSP_LED_GPIO, &GPIO_InitStruct);

    GPIO_WriteBit(BSP_LED_GPIO, BSP_LED_PIN, GPIO_PIN_SET);
}

/******************************************************************************
*@brief : LED on
*@param : none
*@return: none
******************************************************************************/
void BSP_LED_On(void)
{
    GPIO_WriteBit(BSP_LED_GPIO, BSP_LED_PIN, GPIO_PIN_RESET);
}

/******************************************************************************
*@brief : LED off
*@param : none
*@return: none
******************************************************************************/
void BSP_LED_Off(void)
{
    GPIO_WriteBit(BSP_LED_GPIO, BSP_LED_PIN, GPIO_PIN_SET);
}

/******************************************************************************
*@brief : LED toggle
*@param : none
*@return: none
******************************************************************************/
void BSP_LED_Toggle(void)
{
    GPIO_ToggleBits(BSP_LED_GPIO, BSP_LED_PIN);
}

/******************************************************************************
*@brief : PB init
*@param : none
*@return: none
******************************************************************************/
void BSP_PB_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;

    BSP_PB_CLK_ENABLE();

    GPIO_InitStruct.Pin       = BSP_PB_PIN;
    GPIO_InitStruct.Mode      = BSP_PB_MODE;
    GPIO_InitStruct.Pull      = BSP_PB_PULL;
    GPIO_InitStruct.Drive     = BSP_PB_DRIVE;
    GPIO_InitStruct.Alternate = BSP_PB_ALTERNATE;

    GPIO_Init(BSP_PB_GPIO, &GPIO_InitStruct);

    EXTI_InitStruct.GPIOx     = BSP_PB_GPIO;
    EXTI_InitStruct.Line      = BSP_PB_PIN;
    EXTI_InitStruct.Mode      = EXTI_MODE_IT;
    EXTI_InitStruct.Trigger   = EXTI_TRIGGER_FALLING;
    EXTI_InitStruct.Cmd       = ENABLE;
    
    EXTI_Init(&EXTI_InitStruct);
    
	EXTI_ClearITPendingBit(BSP_PB_PIN);
    
    NVIC_ClearPendingIRQ(BSP_PB_IRQ);
    NVIC_SetPriority(BSP_PB_IRQ, 0x00);
    NVIC_EnableIRQ(BSP_PB_IRQ);
}

/******************************************************************************
*@brief : get PB state
*@param : none
*@return: none
******************************************************************************/
uint32_t BSP_PB_GetState(void)
{
    return (GPIO_ReadPin(BSP_PB_GPIO, BSP_PB_PIN));
}

/******************************************************************************
*@brief : uart1 init
*@param : none
*@return: none
******************************************************************************/
void BSP_UART_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    UART_InitTypeDef   UART_InitStructure;
    
    __RCC_UART2_CLK_ENABLE();
    __RCC_GPIOA_CLK_ENABLE();
    
    /* A2:Tx  A3:Rx */
    GPIO_InitStructure.Pin       = GPIO_PIN_2 | GPIO_PIN_3;
    GPIO_InitStructure.Mode      = GPIO_MODE_AF_PP;
    GPIO_InitStructure.Pull      = GPIO_PULLUP;
    GPIO_InitStructure.Drive     = GPIO_DRIVE_LEVEL3;
    GPIO_InitStructure.Alternate = GPIO_FUNCTION_1;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    UART_InitStructure.BaudRate     = 115200;
    UART_InitStructure.WordLength   = UART_WORDLENGTH_8B;
    UART_InitStructure.StopBits     = UART_STOPBITS_1;
    UART_InitStructure.Parity       = UART_PARITY_NONE;
    UART_InitStructure.HwFlowCtl    = UART_HWCONTROL_NONE;
    UART_InitStructure.Mode         = UART_MODE_RX | UART_MODE_TX;
    UART_Init(BSP_UARTx, &UART_InitStructure);
    
    /* NVIC Config */
    NVIC_ClearPendingIRQ(UART2_IRQn);
    NVIC_SetPriority(UART2_IRQn, 5);
    NVIC_EnableIRQ(UART2_IRQn);
    
    /* Enable UART */
    UART_Cmd(BSP_UARTx, ENABLE);
    
    UART_SetDebugUart(BSP_UARTx);
     
	printfS("\r\n\r\n====== ACM32G103 MCU is runing ======\r\nSysCoreClk: %dHz, HCLK:%dHz\r\nPCLK1:%dHz, PCLK2:%dHz\r\n\r\n",(int)g_SystemCoreClock, (int)RCC_GetHCLKFreq(),(int)RCC_GetPCLK1Freq(),(int)RCC_GetPCLK2Freq());  
    
}

/******************************************************************************
*@brief : uart1 reinit
*@param : none
*@return: none
******************************************************************************/
void BSP_UART_DeInit(void)
{
    UART_DeInit(BSP_UARTx);
}


/******************************************************************************
*@brief : MCO init
*@param : none
*@return: none
******************************************************************************/
void BSP_MCO_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;

    BSP_MCO1_CLK_ENABLE();

    GPIO_InitStruct.Pin       = BSP_MCO1_PIN;
    GPIO_InitStruct.Mode      = BSP_MCO1_MODE;
    GPIO_InitStruct.Pull      = BSP_MCO1_PULL;
    GPIO_InitStruct.Drive     = BSP_MCO1_DRIVE;
    GPIO_InitStruct.Alternate = BSP_MCO1_ALTERNATE;

    GPIO_Init(BSP_MCO1_GPIO, &GPIO_InitStruct);
    
    RCC_MCO1Config(RCC_MCO_HCLK, 80, RCC_MCO1_POL_LOW);
    RCC_MCO1Cmd(ENABLE);
    
    RCC_MCO2Cmd(DISABLE);
}

/******************************************************************************
*@brief : get reset source
*@param : none
*@return: none
******************************************************************************/
void get_reset_source(void)
{
	uint32_t reset;
	
	reset = RCC_GetResetSource();
    RCC_ClearAllResetFlag();
    
	if (reset == 0)
	{
		printfS("reset source£ºunknown\r\n");
        return;
	}
	if (reset & RCC_RESETSOURCE_PWR)
	{
		printfS("reset source: pwr\r\n");
	}
	if (reset & RCC_RESETSOURCE_POR12)
	{
		printfS("reset source: por12\r\n");
	}
	if (reset & RCC_RESETSOURCE_SOFT)
	{
		printfS("reset source: soft\r\n");
	}
	if (reset & RCC_RESETSOURCE_NOMAP)
	{
		printfS("reset source: nomap\r\n");
	}
	if (reset & RCC_RESETSOURCE_EFC)
	{
		printfS("reset source: efc\r\n");
	}
	if (reset & RCC_RESETSOURCE_RSTN)
	{
		printfS("reset source: rstn\r\n");
	}
	if (reset & RCC_RESETSOURCE_SYSREQ)
	{
		printfS("reset source: sysreq\r\n");
	}
	if (reset & RCC_RESETSOURCE_LOCKUP)
	{
		printfS("reset source: lockup\r\n");
	}
	if (reset & RCC_RESETSOURCE_IWDT)
	{
		printfS("reset source: iwdt\r\n");
	}
	if (reset & RCC_RESETSOURCE_WDT)
	{
		printfS("reset source: wdt\r\n");
	}
	if (reset & RCC_RESETSOURCE_LVD)
	{
		printfS("reset source: lvd\r\n");
	}
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{ 
	printfS("failed£ºfile:%s, line:%u\r\n", file, (int)line);
	while (1);
}
#endif