/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  *
  * COPYRIGHT(c) 2015 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "usb_device.h"

/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "stm32f1xx_hal_rcc_ex.h"
#include "stm32f1xx_hal_can_ex.h"
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;

TIM_HandleTypeDef htim1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
static CanTxMsgTypeDef        can1TxMessage;
static CanRxMsgTypeDef        can1RxMessage;

uint8_t interface_state = 0 ;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
static void MX_TIM1_Init(void);
static void MX_USART2_UART_Init(void);

/* USER CODE BEGIN PFP */
extern uint8_t CDC_periodic_callback(void);
extern uint8_t CDC_add_buf_to_transmit(uint8_t* Buf, uint16_t Len);
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */
#define RX_BUFFER_SIZE 64
#define APP_TX_DATA_SIZE  1000
#define APP_RX_DATA_SIZE  1000

char rx_buffer2[RX_BUFFER_SIZE];
unsigned char rx_wr_index2=0;


extern uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
extern uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
extern	uint32_t num_bytes;
extern USBD_HandleTypeDef  *hUsbDevice_0;	
extern char status_usb; // переменная - флаг , для обработки событий (usbd_cdc_if.c)

uint8_t halfbyte_to_hexascii(uint8_t _halfbyte)
{
 _halfbyte &= 0x0F ;
 if(_halfbyte >= 10) return('A' + _halfbyte - 10) ; 
	else               return('0' + _halfbyte) ; 
}
void Delay_ms(long int delay)
{
	delay=delay*1000;
	for(long int x=0; x<delay; x++);
}
void led_blink(char blink , int blink_ , long int delay_blink)
{
	 for(char x=0; x<blink; x++)
	 {
		GPIOC->ODR|=0x00000002;  
		Delay_ms(blink_);
		GPIOC->ODR&=~0x00000002; 
		Delay_ms(delay_blink);
		 blink--;
	 }
}

uint8_t hexascii_to_halfbyte(uint8_t _ascii)
{
 if((_ascii >= '0') && (_ascii <= '9')) return(_ascii - '0') ; 
 if((_ascii >= 'a') && (_ascii <= 'f')) return(_ascii - 'a') ; 
 if((_ascii >= 'A') && (_ascii <= 'F')) return(_ascii - 'A') ; 
 return(0xFF)	;
}

void HAL_CAN_RxCpltCallback(CAN_HandleTypeDef* CanHandle)
{
	uint32_t num_bytes ;
	uint8_t buf[200] ;
	static uint32_t time ;
	
	time = __HAL_TIM_GetCounter(&htim1) ; 
/*	
  num_bytes = sprintf((char*)buf,"t%3.3X%1.1X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%4.4X\r", \
		                              CanHandle->pRxMsg->StdId,\
																	CanHandle->pRxMsg->DLC,\
																	CanHandle->pRxMsg->Data[0],\
																	CanHandle->pRxMsg->Data[1],\
																	CanHandle->pRxMsg->Data[2],\
																	CanHandle->pRxMsg->Data[3],\
																	CanHandle->pRxMsg->Data[4],\
																	CanHandle->pRxMsg->Data[5],\
																	CanHandle->pRxMsg->Data[6],\
																	CanHandle->pRxMsg->Data[7],\
																	time
																	);
*/
  num_bytes = 0 ;
	buf[num_bytes++] = 't' ;
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->StdId)>>8);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->StdId)>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->StdId));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->DLC));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[0])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[0]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[1])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[1]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[2])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[2]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[3])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[3]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[4])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[4]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[5])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[5]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[6])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[6]));
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[7])>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((CanHandle->pRxMsg->Data[7]));
	buf[num_bytes++] = halfbyte_to_hexascii((time)>>12);
	buf[num_bytes++] = halfbyte_to_hexascii((time)>>8);
	buf[num_bytes++] = halfbyte_to_hexascii((time)>>4);
	buf[num_bytes++] = halfbyte_to_hexascii((time)>>0);
	buf[num_bytes++] = '\r';
	
	if(interface_state == 1) CDC_add_buf_to_transmit(buf,num_bytes);
	
  HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0);
	
	 led_blink(3, 50, 50);
}



//Функция передачи символа
void Usart2_Send_symbol(uint8_t data) 
{
  while(!(USART2->SR & USART_SR_TC)); //Проверяем установку флага TC - завершения предыдущей передачи 
  USART2->DR = data; //Записываем значение в регистр данных - передаем символ
}

//Функция передачи строки через USART
void Usart2_Send_String(char* str)
{
  uint8_t i=0;
  while(str[i])
  {
    Usart2_Send_symbol(str[i]);
    i++;
  }
  Usart2_Send_symbol('\n');
  Usart2_Send_symbol('\r');
}

void USART2_IRQHandler()
{
    //Проверяем, действительно ли прерывание вызвано приемом нового байта
	char vuart_data;

if (USART2->SR & USART_SR_RXNE) { // ... не пришло ли что-то в UART ?
vuart_data=USART2->DR;
	
	rx_buffer2[rx_wr_index2++]=vuart_data;
			if (rx_wr_index2 == RX_BUFFER_SIZE) rx_wr_index2=0;
}
}



void clear_buffer()
{
	for(unsigned char x=0; x<RX_BUFFER_SIZE; x++){ rx_buffer2[x]=0;}
 rx_wr_index2=0;
}

char string_cmp(char *str1,char *str2)
{
unsigned int x=0;
str1+=0;
str2+=0;
while(str1[x]!=0)
{
if(str1[x] != str2[x])
{
  return 0;
}
x++;
}
return 1;
}

void usb_access()
{
	if(status_usb&0x01)
	{		
		  CDC_Transmit_FS( (uint8_t*)"V0101\r" , 6);
  		//CDC_Transmit_FS( (uint8_t*)'\r' , 1);
		status_usb&=~0x01;
	}
	if(status_usb&0x02)
	{
		   CDC_Transmit_FS( (uint8_t*)"V0101\r" , 6);
	    	//CDC_Transmit_FS( (uint8_t*)'\r' , 1);
		status_usb&=~0x02;
	}
	if(status_usb&0x04)
	{
		 CDC_Transmit_FS( (uint8_t*)"\r" , 1);
		interface_state	= 1 ;
		status_usb&=~0x04;
	}
	if(status_usb&0x08)
	{
		 CDC_Transmit_FS( (uint8_t*)"\r" , 1);
		interface_state	= 0 ;
		status_usb&=~0x08;
	}
	if(status_usb&0x10)
	{
		CDC_Transmit_FS( (uint8_t*)"\r" , 1);
		status_usb&=~0x10;
		
//							char	tmp_byte,i = 1; 

//			hcan1.pTxMsg->StdId = hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->StdId = (hcan1.pTxMsg->StdId << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->StdId = (hcan1.pTxMsg->StdId << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->DLC = hexascii_to_halfbyte(rx_buffer2[i++]);
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[0] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[1] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[2] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[3] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[4] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[5] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[6] = tmp_byte;
//			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
//			hcan1.pTxMsg->Data[7] = tmp_byte;
//		 uint32_t status = HAL_CAN_Transmit(&hcan1, 100);
//			
//			sprintf(buffer_, " CAN1 STATUS=0x%X "  ,  status);
	}
	

}

/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */
unsigned char timer_usb_=0, timer_led=0, timer1=0;
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CAN1_Init();
  MX_TIM1_Init();
  MX_USART2_UART_Init();
  MX_USB_DEVICE_Init();

  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start(&htim1);
	
  hcan1.pTxMsg = &can1TxMessage;
  hcan1.pRxMsg = &can1RxMessage;
	
  CAN_FilterConfTypeDef canFilterConfig;
  canFilterConfig.FilterNumber = 0;
  canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  canFilterConfig.FilterIdHigh = 0x0000;
  canFilterConfig.FilterIdLow = 0x0000;
  canFilterConfig.FilterMaskIdHigh = 0x0000 << 5;
  canFilterConfig.FilterMaskIdLow = 0x0000;
  canFilterConfig.FilterFIFOAssignment = 0;
  canFilterConfig.FilterActivation = ENABLE;
  canFilterConfig.BankNumber = 1;
	HAL_CAN_ConfigFilter(&hcan1, &canFilterConfig);
	
  HAL_CAN_Receive_IT(&hcan1, CAN_FIFO0) ; 
	
		__enable_irq(); //Глобальное включение прерывания
NVIC_EnableIRQ(USART2_IRQn); //Включаем прерывания от UART
NVIC_SetPriority(USART2_IRQn, 1); //Прерывание от UART, приоритет 0, самый высокий
USART2->CR1 |= USART_CR1_RXNEIE; //Прерывание по приему
	
	Usart2_Send_String("Power ON!");
	Usart2_Send_String("Program start...\r\n");
	GPIOC->ODR|=0x00000004;
	

	
	 led_blink(5 , 1000, 200);
	 
	
	    char buffer_[64];
			uint32_t data[4];
		data[0] = RCC->APB1ENR;	
		data[1] = AFIO->MAPR;
		data[2] = RCC->APB1RSTR;
		data[3] = CAN1->MSR;

		
		 uint16_t data16[10];
		 
		 data16[0] = (uint16_t)(data[0]>>16);
		 data16[1] = (uint16_t)(0xFFFF & data[0]);
		 data16[2] = (uint16_t)(data[1]>>16);
		 data16[3] = (uint16_t)(0xFFFF & data[1]);
	 sprintf(buffer_, "APB1ENR=0x%X 0x%X, CAN1->MSR=0x%X"  , data16[0] , data16[1], data[3]);
	  Usart2_Send_String(buffer_);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
		
	char i=0,tmp_byte=0;
		
		if(string_cmp("AT+REV?", rx_buffer2))
		{
			Usart2_Send_String("USB/CAN/RS232 Modul");
			Usart2_Send_String("System V1.0.0!");
			Usart2_Send_String("10.09.2015");
			Usart2_Send_String("Powered by Artos");
		  clear_buffer();
			led_blink(20, 100, 100);
		}
		else if(string_cmp("V", rx_buffer2))
		{
			Usart2_Send_String("V0101\r");
			clear_buffer();
				timer1=0;
				led_blink(3, 3000, 400);
		}
			else if(string_cmp("v", rx_buffer2))
			{
				Usart2_Send_String("VArtos\r");
				clear_buffer();
				timer1=0;
				led_blink(3, 3000, 400);
			}
				else if(string_cmp("C", rx_buffer2))
				{
					 interface_state	= 0 ;
					Usart2_Send_String("CAN Closed\r");
								Usart2_Send_String("\r");
					clear_buffer();
				timer1=0;
				led_blink(3, 3000, 400);
				}
					else if(string_cmp("O", rx_buffer2))
					{
						Usart2_Send_String("CAN Open\r");
						 interface_state	= 1 ;
									Usart2_Send_String("\r");
						clear_buffer();
				    timer1=0;
				    led_blink(3, 3000, 400);
					}
					else if(string_cmp("t", rx_buffer2))
					{
							  	
				    timer1=0;
				    led_blink(3, 200, 400);
						
						i = 1; 

			hcan1.pTxMsg->StdId = hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->StdId = (hcan1.pTxMsg->StdId << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->StdId = (hcan1.pTxMsg->StdId << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->DLC = hexascii_to_halfbyte(rx_buffer2[i++]);
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[0] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[1] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[2] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[3] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[4] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[5] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[6] = tmp_byte;
			tmp_byte = hexascii_to_halfbyte(rx_buffer2[i++]); tmp_byte = (tmp_byte << 4) + hexascii_to_halfbyte(rx_buffer2[i++]);
			hcan1.pTxMsg->Data[7] = tmp_byte;
		 uint32_t status = HAL_CAN_Transmit(&hcan1, 100);
			
			sprintf(buffer_, " CAN1 STATUS=0x%X "  ,  status);
	             Usart2_Send_String(buffer_);
						
						Usart2_Send_String(rx_buffer2);
						Usart2_Send_String("CAN Send\r");
						//Usart2_Send_String("\r");
						
						data[0] = CAN1->MSR;
						data[1] = CAN1->MCR;
						data[2] = CAN1->TSR;
						data[3] = CAN1->ESR;
							 sprintf(buffer_, " CAN1->MSR=0x%X CAN1->MCR=0x%X CAN1->TSR=0x%X CAN1->ESR=0x%X"  ,  data[0], data[1], data[2], data[3]);
	             Usart2_Send_String(buffer_);
		
						clear_buffer();
					}
		else if(!string_cmp(rx_buffer2,0))
		{
			
			
			if(++timer1>20) 
			{
				  Usart2_Send_String(rx_buffer2);
				  Usart2_Send_String("error data!");
				clear_buffer();
				timer1=0;
				led_blink(3, 3000, 400);
			}
		}
		Delay_ms(100);
		

	if(status_usb)
	{
		if(++timer_usb_>20)
		{
			usb_access();
			timer_usb_=0;
		led_blink(3 , 1000, 500); 
		}
	}
	else
	{
		timer_usb_=0;
	}
	
   CDC_periodic_callback();
  }

  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV8;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBPLLCLK_DIV3;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  __HAL_RCC_PLLI2S_ENABLE();

}

/* CAN1 init function */
void MX_CAN1_Init(void)
{

  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 6;
  hcan1.Init.Mode = CAN_MODE_SILENT_LOOPBACK;
  hcan1.Init.SJW = CAN_SJW_1TQ;
  hcan1.Init.BS1 = CAN_BS1_6TQ;
  hcan1.Init.BS2 = CAN_BS2_5TQ;
  hcan1.Init.TTCM = DISABLE;
  hcan1.Init.ABOM = ENABLE;
  hcan1.Init.AWUM = ENABLE;
  hcan1.Init.NART = DISABLE;
  hcan1.Init.RFLM = DISABLE;
  hcan1.Init.TXFP = DISABLE;
  HAL_CAN_Init(&hcan1);

}

/* TIM1 init function */
void MX_TIM1_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 18000;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 60000;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  HAL_TIM_Base_Init(&htim1);

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig);

}

/* USART2 init function */
void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart2);

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin : PC0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PC1 PC2 PC3 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pin : PB7 */
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */ 

/**
  * @}
*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
