Subversion Repositories EngineBay2

Rev

Rev 39 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /* USER CODE BEGIN Header */
  2. /**
  3.  ******************************************************************************
  4.  * @file           : main.c
  5.  * @brief          : Main program body
  6.  ******************************************************************************
  7.  * @attention
  8.  *
  9.  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
  10.  * All rights reserved.</center></h2>
  11.  *
  12.  * This software component is licensed by ST under BSD 3-Clause license,
  13.  * the "License"; You may not use this file except in compliance with the
  14.  * License. You may obtain a copy of the License at:
  15.  *                        opensource.org/licenses/BSD-3-Clause
  16.  *
  17.  ******************************************************************************
  18.  */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22.  
  23. /* Private includes ----------------------------------------------------------*/
  24. /* USER CODE BEGIN Includes */
  25. #include "libSerial/serial.h"
  26. #include "libPLX/plx.h"
  27. #include "misc.h"
  28.  
  29. /* USER CODE END Includes */
  30.  
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* USER CODE BEGIN PTD */
  33.  
  34. /* USER CODE END PTD */
  35.  
  36. /* Private define ------------------------------------------------------------*/
  37. /* USER CODE BEGIN PD */
  38. /* USER CODE END PD */
  39.  
  40. /* Private macro -------------------------------------------------------------*/
  41. /* USER CODE BEGIN PM */
  42. #define ADC_CHANNELS 7
  43.  
  44. // with a dwell angle of 45 degrees , 4 cylinders and a maximum RPM of 5000
  45. // freq = 5000/60 * 2 = 166Hz.
  46. // the TIM2 counter counts in 10uS increments,
  47. // TODO this is wrong algo. Accept FIRST pulse, skip shorter pulses
  48. // Accept the first pulse with over 2.5mS (1/400 sec)  duration as the closure
  49. #define BREAKER_MIN (RPM_COUNT_RATE/400)
  50.  
  51. #define RPM_AVERAGE 4
  52.  
  53. // wait for about 1 second to decide whether or not starter is on
  54.  
  55. #define STARTER_LIMIT 10
  56.  
  57.  
  58. /* USER CODE END PM */
  59.  
  60. /* Private variables ---------------------------------------------------------*/
  61. ADC_HandleTypeDef hadc1;
  62. DMA_HandleTypeDef hdma_adc1;
  63.  
  64. CAN_HandleTypeDef hcan;
  65.  
  66. SPI_HandleTypeDef hspi1;
  67.  
  68. TIM_HandleTypeDef htim2;
  69. TIM_HandleTypeDef htim3;
  70. TIM_HandleTypeDef htim4;
  71.  
  72. UART_HandleTypeDef huart1;
  73.  
  74. /* USER CODE BEGIN PV */
  75.  
  76.  
  77. volatile char TimerFlag = 0;
  78.  
  79. volatile char NoSerialInCTR = 0; // Missing characters coming in on USART1
  80. volatile char NoSerialIn = 0;
  81.  
  82. // storage for ADC
  83. uint16_t ADC_Samples[ADC_CHANNELS];
  84.  
  85. #define Scale 1024.0
  86. const float ADC_Scale = 3.3 / (Scale * 4096.0); // convert to a voltage
  87.  
  88. uint32_t FILT_Samples[ADC_CHANNELS]; // filtered ADC samples * 1024
  89. // Rev counter processing from original RevCounter Project
  90. uint16_t RPM_Diff = 0;
  91. uint16_t RPM_Count_Latch = 0;
  92. // accumulators
  93. uint16_t RPM_Pulsecount = 0;
  94. unsigned int RPM_FilteredWidth = 0;
  95.  
  96. // last time we detected end of dwell i.e. ignition pulse
  97. uint16_t last_dwell_end = 0;
  98. uint16_t RPM_Period[RPM_AVERAGE];
  99. unsigned int RPM_Period_Ptr = 0;
  100.  
  101. unsigned int Coded_RPM = 0;
  102. unsigned int Coded_CHT = 0;
  103.  
  104. uint32_t Power_CHT_Timer;
  105.  
  106. uint16_t Starter_Debounce = 0;
  107.  
  108. /* USER CODE END PV */
  109.  
  110. /* Private function prototypes -----------------------------------------------*/
  111. void SystemClock_Config(void);
  112. static void MX_GPIO_Init(void);
  113. static void MX_DMA_Init(void);
  114. static void MX_ADC1_Init(void);
  115. static void MX_CAN_Init(void);
  116. static void MX_SPI1_Init(void);
  117. static void MX_TIM2_Init(void);
  118. static void MX_TIM3_Init(void);
  119. static void MX_TIM4_Init(void);
  120. static void MX_USART1_UART_Init(void);
  121. /* USER CODE BEGIN PFP */
  122.  
  123. /* USER CODE END PFP */
  124.  
  125. /* Private user code ---------------------------------------------------------*/
  126. /* USER CODE BEGIN 0 */
  127.  
  128. void
  129. plx_sendword (int x)
  130. {
  131.   PutCharSerial (&uc1, ((x) >> 6) & 0x3F);
  132.   PutCharSerial (&uc1, (x) & 0x3F);
  133. }
  134.  
  135. void
  136. init_ADC_filter ()
  137. {
  138.   int i;
  139.   for (i = 0; i < ADC_CHANNELS; i++)
  140.     {
  141.       FILT_Samples[i] = 0;
  142.     }
  143. }
  144.  
  145. void
  146. filter_ADC_samples ()
  147. {
  148.   int i;
  149.   for (i = 0; i < ADC_CHANNELS; i++)
  150.     {
  151.       FILT_Samples[i] += (ADC_Samples[i] * Scale - FILT_Samples[i]) / 2;
  152.     }
  153. }
  154.  
  155. void
  156. ProcessRPM (int instance)
  157. {
  158. // compute the timer values
  159. // snapshot timers
  160.   unsigned long RPM_Pulsewidth;
  161.   // current RPM pulse next slot index
  162.   unsigned long RPM_Count_Val;
  163.   __disable_irq (); // copy the counter value
  164.   RPM_Count_Val = RPM_Count;
  165.   __enable_irq ();
  166. // do calculations
  167. // if there is only one entry, cannot get difference
  168.   if (RPM_Count_Latch != RPM_Count_Val)
  169.     {
  170.       while (1)
  171.         {
  172.           unsigned int base_time;
  173.           unsigned int new_time;
  174.           // if we are at N-1, stop.
  175.           unsigned int next_count = (RPM_Count_Latch + 1) % RPM_SAMPLES;
  176.           if (next_count == RPM_Count_Val)
  177.             {
  178.               break; // completed loop
  179.             }
  180.           char pulse_level = RPM_Level[RPM_Count_Latch];
  181.           base_time = RPM_Time[RPM_Count_Latch];
  182.           new_time = RPM_Time[next_count];
  183.           RPM_Count_Latch = next_count;
  184.  
  185.           RPM_Pulsewidth = new_time - base_time; // not wrapped
  186.  
  187.           // if the pulse was low,
  188.           if (pulse_level == 0 && RPM_Pulsewidth > BREAKER_MIN)
  189.             {
  190.  
  191.               RPM_Diff = new_time - last_dwell_end;
  192.  
  193.               RPM_Period[RPM_Period_Ptr] = RPM_Diff;
  194.               RPM_Period_Ptr = (RPM_Period_Ptr + 1) % RPM_AVERAGE;
  195.               if (RPM_Pulsecount < RPM_AVERAGE)
  196.                 RPM_Pulsecount++; // count one pulse
  197.               last_dwell_end = new_time;
  198.  
  199.             }
  200.         }
  201.  
  202.     }
  203.  
  204.   if (RPM_Pulsecount == RPM_AVERAGE)
  205.     {
  206.       // now have time for N pulses in clocks
  207.       // need to scale by 19.55: one unit is 19.55 RPM
  208.       // 1Hz is 30 RPM
  209.       int i;
  210.       RPM_FilteredWidth = 0;
  211.       for (i = 0; i < RPM_AVERAGE; i++)
  212.         RPM_FilteredWidth += RPM_Period[i];
  213.  
  214.       Coded_RPM = (Scale * 30.0 * RPM_AVERAGE * RPM_COUNT_RATE)
  215.           / (19.55 * RPM_FilteredWidth);
  216.  
  217. #if !defined MY_DEBUG
  218.       // reset here unless we want to debug
  219.       RPM_Pulsecount = 0;
  220.       RPM_FilteredWidth = 0;
  221. #endif
  222.     }
  223.  
  224. // send the current RPM *calculation
  225.   plx_sendword (PLX_RPM);
  226.   PutCharSerial (&uc1, instance);
  227.   plx_sendword (Coded_RPM / Scale);
  228. }
  229.  
  230. // this uses a MAX6675 which is a simple 16 bit read
  231. // SPI is configured for 8 bits so I can use an OLED display if I need it
  232. // must wait > 0.22 seconds between conversion attempts as this is the measurement time
  233. //
  234.  
  235. FunctionalState CHT_Enable = ENABLE;
  236.  
  237. #define CORR 3
  238.  
  239. uint16_t CHT_Observations[2] =
  240.   { 0, 0 };
  241.  
  242. // look for the trigger pin being high then low - the points
  243. // are opening, and skip the reading
  244.  
  245. void
  246. ProcessCHT (int instance)
  247. {
  248.   plx_sendword (PLX_X_CHT);
  249.   PutCharSerial (&uc1, instance);
  250.   plx_sendword (CHT_Observations[instance]);
  251.  
  252. }
  253.  
  254. void
  255. EnableCHT (FunctionalState state)
  256.  
  257. {
  258.   GPIO_InitTypeDef GPIO_InitStruct;
  259.  
  260.   CHT_Enable = state;
  261.  
  262.   /* enable SPI in live mode : assume it and its GPIOs are already initialised in SPI mode */
  263.   if (state == ENABLE)
  264.     {
  265.       HAL_GPIO_WritePin (ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_SET);
  266.       HAL_GPIO_WritePin (SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin, GPIO_PIN_SET);
  267.       HAL_GPIO_WritePin (SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin,
  268.                          GPIO_PIN_SET);
  269.  
  270.       /* put the SPI pins back into SPI AF mode */
  271.       GPIO_InitStruct.Pin = SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin;
  272.       GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  273.       GPIO_InitStruct.Pull = GPIO_NOPULL;
  274.       GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  275.       HAL_GPIO_Init (SPI1_SCK_GPIO_Port, &GPIO_InitStruct);
  276.  
  277.     }
  278.   else
  279.     {
  280.       /*  Power down the SPI interface taking signals all low */
  281.       HAL_GPIO_WritePin (ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_RESET);
  282.       HAL_GPIO_WritePin (SPI_NS_Temp_GPIO_Port, SPI_NS_Temp_Pin,
  283.                          GPIO_PIN_RESET);
  284.       HAL_GPIO_WritePin (SPI_NS_Temp2_GPIO_Port, SPI_NS_Temp2_Pin,
  285.                          GPIO_PIN_RESET);
  286.  
  287.       HAL_GPIO_WritePin (SPI1_SCK_GPIO_Port,
  288.                          SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin,
  289.                          GPIO_PIN_RESET);
  290.  
  291.       /* put the SPI pins back into GPIO mode */
  292.       GPIO_InitStruct.Pin = SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin;
  293.       GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  294.       GPIO_InitStruct.Pull = GPIO_NOPULL;
  295.       GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  296.       HAL_GPIO_Init (SPI1_SCK_GPIO_Port, &GPIO_InitStruct);
  297.  
  298.     }
  299.  
  300. }
  301.  
  302. // 1023 is 20.00 volts.
  303. void
  304. ProcessBatteryVoltage (int instance)
  305. {
  306.   float reading = FILT_Samples[instance] * ADC_Scale;
  307.   reading = reading * 7.8125; // real voltage
  308.   reading = reading * 51.15; // 1023/20
  309.  
  310.   plx_sendword (PLX_Volts);
  311.   PutCharSerial (&uc1, instance);
  312.   plx_sendword ((uint16_t) reading);
  313.  
  314. }
  315.  
  316. /****!
  317.  * @brief this reads the reference voltage within the STM32L151
  318.  * Powers up reference voltage and temperature sensor, waits 3mS  and takes reading
  319.  * Requires that the ADC be powered up
  320.  */
  321.  
  322. uint32_t ADC_VREF_MV = 3300;           // 3.300V typical
  323. const uint16_t STM32REF_MV = 1224;           // 1.224V typical
  324.  
  325. void
  326. CalibrateADC (void)
  327. {
  328.   uint32_t adc_val = FILT_Samples[5];       // as set up in device config
  329.   ADC_VREF_MV = (STM32REF_MV * 4096) / adc_val;
  330. }
  331.  
  332. void
  333. ProcessCPUTemperature (int instance)
  334. {
  335.   int32_t temp_val;
  336.  
  337.   uint16_t TS_CAL30 = *(uint16_t*) (0x1FF8007AUL); /* ADC reading for temperature sensor at 30 degrees C with Vref = 3000mV */
  338.   uint16_t TS_CAL110 = *(uint16_t*) (0x1FF8007EUL); /* ADC reading for temperature sensor at 110 degrees C with Vref = 3000mV */
  339.   /* get the ADC reading corresponding to ADC channel 16 after turning on the ADC */
  340.  
  341.   temp_val = FILT_Samples[5];
  342.  
  343.   /* renormalise temperature value to account for different ADC Vref  : normalise to that which we would get for a 3000mV reference */
  344.   temp_val = temp_val * ADC_VREF_MV / (Scale * 3000UL);
  345.  
  346.   int32_t result = 800 * ((int32_t) temp_val - TS_CAL30);
  347.   result = result / (TS_CAL110 - TS_CAL30) + 300;
  348.  
  349.   if (result < 0)
  350.     {
  351.       result = 0;
  352.     }
  353.   plx_sendword (PLX_FluidTemp);
  354.   PutCharSerial (&uc1, instance);
  355.   plx_sendword (result / 10);
  356.  
  357. }
  358.  
  359. // the MAP sensor is giving us a reading of
  360. // 4.6 volts for 1019mB or 2.27 volts at the ADC input (resistive divider by 2.016)
  361. // I believe the sensor reads  4.5V at 1000kPa and 0.5V at  0kPa
  362. // Calibration is a bit off
  363. // Real   Displayed
  364. // 989    968
  365. // 994.1    986
  366. // 992.3  984
  367.  
  368. void
  369. ProcessMAP (int instance)
  370. {
  371. // Using ADC_Samples[3] as the MAP input
  372.   float reading = FILT_Samples[3] * ADC_Scale;
  373.   reading = reading * 2.016;      // real voltage
  374.   // values computed from slope / intercept of map.ods
  375.   //reading = (reading) * 56.23 + 743.2; // do not assume 0.5 volt offset : reading from 0 to 4.5 instead of 0.5 to 4.5
  376.   // using a pressure gauge.
  377.   reading = (reading) * 150 + 326;
  378.  
  379.   plx_sendword (PLX_MAP);
  380.   PutCharSerial (&uc1, instance);
  381.   plx_sendword ((uint16_t) reading);
  382.  
  383. }
  384.  
  385. // the Oil pressi sensor is giving us a reading of
  386. // 4.5 volts for 100 PSI or  2.25 volts at the ADC input (resistive divider by 2.016)
  387. // I believe the sensor reads  4.5V at 100PSI and 0.5V at  0PSI
  388. // an observation of 1024 is 200PSI, so observation of 512 is 100 PSI.
  389.  
  390. void
  391. ProcessOilPress (int instance)
  392. {
  393. // Using ADC_Samples[2] as the MAP input
  394.   float reading = FILT_Samples[2] * ADC_Scale;
  395.   reading = reading * 2.00; // real voltage
  396.   reading = (reading - 0.5) * 512 / 4;  // this is 1023 * 100/200
  397.  
  398.   plx_sendword (PLX_FluidPressure);
  399.   PutCharSerial (&uc1, instance);
  400.   plx_sendword ((uint16_t) reading);
  401.  
  402. }
  403.  
  404. void
  405. ProcessTiming (int instance)
  406. {
  407.   plx_sendword (PLX_Timing);
  408.   PutCharSerial (&uc1, instance);
  409.   plx_sendword (64 - 15); // make it negative
  410. }
  411.  
  412. /* USER CODE END 0 */
  413.  
  414. /**
  415.   * @brief  The application entry point.
  416.   * @retval int
  417.   */
  418. int main(void)
  419. {
  420.   /* USER CODE BEGIN 1 */
  421.  
  422.   /* USER CODE END 1 */
  423.  
  424.   /* MCU Configuration--------------------------------------------------------*/
  425.  
  426.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  427.   HAL_Init();
  428.  
  429.   /* USER CODE BEGIN Init */
  430.  
  431.   /* USER CODE END Init */
  432.  
  433.   /* Configure the system clock */
  434.   SystemClock_Config();
  435.  
  436.   /* USER CODE BEGIN SysInit */
  437.  
  438.   /* USER CODE END SysInit */
  439.  
  440.   /* Initialize all configured peripherals */
  441.   MX_GPIO_Init();
  442.   MX_DMA_Init();
  443.   MX_ADC1_Init();
  444.   MX_CAN_Init();
  445.   MX_SPI1_Init();
  446.   MX_TIM2_Init();
  447.   MX_TIM3_Init();
  448.   MX_TIM4_Init();
  449.   MX_USART1_UART_Init();
  450.   /* USER CODE BEGIN 2 */
  451.   HAL_MspInit ();
  452.  
  453.   // Not using HAL USART code
  454.   __HAL_RCC_USART1_CLK_ENABLE()
  455.   ; // PLX comms port
  456.   /* setup the USART control blocks */
  457.   init_usart_ctl (&uc1, huart1.Instance);
  458.  
  459.   EnableSerialRxInterrupt (&uc1);
  460.  
  461.   HAL_SPI_MspInit (&hspi1);
  462.  
  463.   HAL_ADC_MspInit (&hadc1);
  464.  
  465.   HAL_ADC_Start_DMA (&hadc1, ADC_Samples, ADC_CHANNELS);
  466.  
  467.   HAL_ADC_Start_IT (&hadc1);
  468.  
  469.   HAL_TIM_Base_MspInit (&htim4);
  470.   HAL_TIM_Base_Start_IT (&htim4);
  471.  
  472.   // initialise all the STMCubeMX stuff
  473.   HAL_TIM_Base_MspInit (&htim2);
  474.   // Start the counter
  475.   HAL_TIM_Base_Start (&htim2);
  476.   // Start the input capture and the interrupt
  477.   HAL_TIM_IC_Start_IT (&htim2, TIM_CHANNEL_1);
  478.  
  479.   HAL_TIM_Base_MspInit (&htim3);
  480.   __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
  481.   uint32_t Ticks = HAL_GetTick () + 100;
  482.   int CalCounter = 0;
  483.  
  484.   Power_CHT_Timer = HAL_GetTick () + 1000; /* wait 10 seconds before powering up the CHT sensor */
  485.  
  486.   /* USER CODE END 2 */
  487.  
  488.   /* Infinite loop */
  489.   /* USER CODE BEGIN WHILE */
  490.   while (1)
  491.     {
  492.     /* USER CODE END WHILE */
  493.  
  494.     /* USER CODE BEGIN 3 */
  495.  
  496.       if (HAL_GetTick () > Ticks)
  497.         {
  498.           Ticks += 100;
  499.           filter_ADC_samples ();
  500.           // delay to calibrate ADC
  501.           if (CalCounter < 1000)
  502.             {
  503.               CalCounter += 100;
  504.             }
  505.  
  506.           if (CalCounter == 900)
  507.             {
  508.               CalibrateADC ();
  509.             }
  510.         }
  511.       /* when the starter motor is on then power down the CHT sensors as they seem to fail */
  512.  
  513.       if (HAL_GPIO_ReadPin (STARTER_ON_GPIO_Port, STARTER_ON_Pin)
  514.           == GPIO_PIN_RESET)
  515.         {
  516.           if (Starter_Debounce < STARTER_LIMIT)
  517.             {
  518.               Starter_Debounce++;
  519.             }
  520.         }
  521.       else
  522.         {
  523.           if (Starter_Debounce > 0)
  524.             {
  525.               Starter_Debounce--;
  526.             }
  527.         }
  528.  
  529.       if (Starter_Debounce == STARTER_LIMIT)
  530.         {
  531.           EnableCHT (DISABLE);
  532.           Power_CHT_Timer = HAL_GetTick () + 1000;
  533.         }
  534.       else
  535.       /* if the Power_CHT_Timer is set then wait for it to timeout, then power up CHT */
  536.         {
  537.           if ((Power_CHT_Timer > 0) && (HAL_GetTick () > Power_CHT_Timer))
  538.             {
  539.               EnableCHT (ENABLE);
  540.               Power_CHT_Timer = 0;
  541.             }
  542.         }
  543.  
  544.       // check to see if we have any incoming data, copy and append if so, if no data then create our own frames.
  545.       int c;
  546.       char send = 0;
  547.  
  548.       // poll the  input for a stop bit or timeout
  549.       if (PollSerial (&uc1))
  550.         {
  551.           resetSerialTimeout ();
  552.           c = GetCharSerial (&uc1);
  553.           if (c != PLX_Stop)
  554.             {
  555.               PutCharSerial (&uc1, c); // echo all but the stop bit
  556.             }
  557.           else
  558.             { // must be a stop character
  559.               send = 1; // start our sending process.
  560.             }
  561.         }
  562.  
  563.       // sort out auto-sending
  564.       if (TimerFlag)
  565.         {
  566.           TimerFlag = 0;
  567.           if (NoSerialIn)
  568.             {
  569.               PutCharSerial (&uc1, PLX_Start);
  570.               send = 1;
  571.             }
  572.         }
  573.       if (send)
  574.         {
  575.           send = 0;
  576.  
  577.           // send the observations
  578.           ProcessRPM (0);
  579.           ProcessCHT (0);
  580.           ProcessCHT (1);
  581.           ProcessBatteryVoltage (0); // Batt 1
  582.           ProcessBatteryVoltage (1); // Batt 2
  583.           ProcessCPUTemperature (0); //  built in temperature sensor
  584.  
  585.           ProcessMAP (0);
  586.           ProcessOilPress (0);
  587.  
  588.           PutCharSerial (&uc1, PLX_Stop);
  589.         }
  590.     }
  591.  
  592.  
  593.   /* USER CODE END 3 */
  594. }
  595.  
  596. /**
  597.   * @brief System Clock Configuration
  598.   * @retval None
  599.   */
  600. void SystemClock_Config(void)
  601. {
  602.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  603.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  604.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  605.  
  606.   /** Initializes the RCC Oscillators according to the specified parameters
  607.   * in the RCC_OscInitTypeDef structure.
  608.   */
  609.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  610.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  611.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  612.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  613.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  614.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  615.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  616.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  617.   {
  618.     Error_Handler();
  619.   }
  620.   /** Initializes the CPU, AHB and APB buses clocks
  621.   */
  622.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  623.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  624.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  625.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  626.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  627.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  628.  
  629.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  630.   {
  631.     Error_Handler();
  632.   }
  633.   PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  634.   PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  635.   if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  636.   {
  637.     Error_Handler();
  638.   }
  639. }
  640.  
  641. /**
  642.   * @brief ADC1 Initialization Function
  643.   * @param None
  644.   * @retval None
  645.   */
  646. static void MX_ADC1_Init(void)
  647. {
  648.  
  649.   /* USER CODE BEGIN ADC1_Init 0 */
  650.  
  651.   /* USER CODE END ADC1_Init 0 */
  652.  
  653.   ADC_ChannelConfTypeDef sConfig = {0};
  654.  
  655.   /* USER CODE BEGIN ADC1_Init 1 */
  656.  
  657.   /* USER CODE END ADC1_Init 1 */
  658.   /** Common config
  659.   */
  660.   hadc1.Instance = ADC1;
  661.   hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  662.   hadc1.Init.ContinuousConvMode = DISABLE;
  663.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  664.   hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
  665.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  666.   hadc1.Init.NbrOfConversion = 7;
  667.   if (HAL_ADC_Init(&hadc1) != HAL_OK)
  668.   {
  669.     Error_Handler();
  670.   }
  671.   /** Configure Regular Channel
  672.   */
  673.   sConfig.Channel = ADC_CHANNEL_0;
  674.   sConfig.Rank = ADC_REGULAR_RANK_1;
  675.   sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  676.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  677.   {
  678.     Error_Handler();
  679.   }
  680.   /** Configure Regular Channel
  681.   */
  682.   sConfig.Channel = ADC_CHANNEL_1;
  683.   sConfig.Rank = ADC_REGULAR_RANK_2;
  684.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  685.   {
  686.     Error_Handler();
  687.   }
  688.   /** Configure Regular Channel
  689.   */
  690.   sConfig.Channel = ADC_CHANNEL_2;
  691.   sConfig.Rank = ADC_REGULAR_RANK_3;
  692.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  693.   {
  694.     Error_Handler();
  695.   }
  696.   /** Configure Regular Channel
  697.   */
  698.   sConfig.Channel = ADC_CHANNEL_3;
  699.   sConfig.Rank = ADC_REGULAR_RANK_4;
  700.   sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  701.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  702.   {
  703.     Error_Handler();
  704.   }
  705.   /** Configure Regular Channel
  706.   */
  707.   sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  708.   sConfig.Rank = ADC_REGULAR_RANK_5;
  709.   sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  710.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  711.   {
  712.     Error_Handler();
  713.   }
  714.   /** Configure Regular Channel
  715.   */
  716.   sConfig.Channel = ADC_CHANNEL_VREFINT;
  717.   sConfig.Rank = ADC_REGULAR_RANK_6;
  718.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  719.   {
  720.     Error_Handler();
  721.   }
  722.   /** Configure Regular Channel
  723.   */
  724.   sConfig.Channel = ADC_CHANNEL_4;
  725.   sConfig.Rank = ADC_REGULAR_RANK_7;
  726.   if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  727.   {
  728.     Error_Handler();
  729.   }
  730.   /* USER CODE BEGIN ADC1_Init 2 */
  731.  
  732.   /* USER CODE END ADC1_Init 2 */
  733.  
  734. }
  735.  
  736. /**
  737.   * @brief CAN Initialization Function
  738.   * @param None
  739.   * @retval None
  740.   */
  741. static void MX_CAN_Init(void)
  742. {
  743.  
  744.   /* USER CODE BEGIN CAN_Init 0 */
  745.  
  746.   /* USER CODE END CAN_Init 0 */
  747.  
  748.   /* USER CODE BEGIN CAN_Init 1 */
  749.  
  750.   /* USER CODE END CAN_Init 1 */
  751.   hcan.Instance = CAN1;
  752.   hcan.Init.Prescaler = 16;
  753.   hcan.Init.Mode = CAN_MODE_NORMAL;
  754.   hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  755.   hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
  756.   hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  757.   hcan.Init.TimeTriggeredMode = DISABLE;
  758.   hcan.Init.AutoBusOff = DISABLE;
  759.   hcan.Init.AutoWakeUp = DISABLE;
  760.   hcan.Init.AutoRetransmission = DISABLE;
  761.   hcan.Init.ReceiveFifoLocked = DISABLE;
  762.   hcan.Init.TransmitFifoPriority = DISABLE;
  763.   if (HAL_CAN_Init(&hcan) != HAL_OK)
  764.   {
  765.     Error_Handler();
  766.   }
  767.   /* USER CODE BEGIN CAN_Init 2 */
  768.  
  769.   /* USER CODE END CAN_Init 2 */
  770.  
  771. }
  772.  
  773. /**
  774.   * @brief SPI1 Initialization Function
  775.   * @param None
  776.   * @retval None
  777.   */
  778. static void MX_SPI1_Init(void)
  779. {
  780.  
  781.   /* USER CODE BEGIN SPI1_Init 0 */
  782.  
  783.   /* USER CODE END SPI1_Init 0 */
  784.  
  785.   /* USER CODE BEGIN SPI1_Init 1 */
  786.  
  787.   /* USER CODE END SPI1_Init 1 */
  788.   /* SPI1 parameter configuration*/
  789.   hspi1.Instance = SPI1;
  790.   hspi1.Init.Mode = SPI_MODE_MASTER;
  791.   hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  792.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  793.   hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  794.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  795.   hspi1.Init.NSS = SPI_NSS_SOFT;
  796.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  797.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  798.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  799.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  800.   hspi1.Init.CRCPolynomial = 10;
  801.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  802.   {
  803.     Error_Handler();
  804.   }
  805.   /* USER CODE BEGIN SPI1_Init 2 */
  806.  
  807.   /* USER CODE END SPI1_Init 2 */
  808.  
  809. }
  810.  
  811. /**
  812.   * @brief TIM2 Initialization Function
  813.   * @param None
  814.   * @retval None
  815.   */
  816. static void MX_TIM2_Init(void)
  817. {
  818.  
  819.   /* USER CODE BEGIN TIM2_Init 0 */
  820.  
  821.   /* USER CODE END TIM2_Init 0 */
  822.  
  823.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  824.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  825.   TIM_IC_InitTypeDef sConfigIC = {0};
  826.  
  827.   /* USER CODE BEGIN TIM2_Init 1 */
  828.  
  829.   /* USER CODE END TIM2_Init 1 */
  830.   htim2.Instance = TIM2;
  831.   htim2.Init.Prescaler = 719;
  832.   htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  833.   htim2.Init.Period = 65535;
  834.   htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  835.   htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  836.   if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  837.   {
  838.     Error_Handler();
  839.   }
  840.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  841.   if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  842.   {
  843.     Error_Handler();
  844.   }
  845.   if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
  846.   {
  847.     Error_Handler();
  848.   }
  849.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  850.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  851.   if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  852.   {
  853.     Error_Handler();
  854.   }
  855.   sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  856.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  857.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  858.   sConfigIC.ICFilter = 15;
  859.   if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  860.   {
  861.     Error_Handler();
  862.   }
  863.   /* USER CODE BEGIN TIM2_Init 2 */
  864.  
  865.   /* USER CODE END TIM2_Init 2 */
  866.  
  867. }
  868.  
  869. /**
  870.   * @brief TIM3 Initialization Function
  871.   * @param None
  872.   * @retval None
  873.   */
  874. static void MX_TIM3_Init(void)
  875. {
  876.  
  877.   /* USER CODE BEGIN TIM3_Init 0 */
  878.  
  879.   /* USER CODE END TIM3_Init 0 */
  880.  
  881.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  882.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  883.   TIM_OC_InitTypeDef sConfigOC = {0};
  884.  
  885.   /* USER CODE BEGIN TIM3_Init 1 */
  886.  
  887.   /* USER CODE END TIM3_Init 1 */
  888.   htim3.Instance = TIM3;
  889.   htim3.Init.Prescaler = 719;
  890.   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  891.   htim3.Init.Period = 99;
  892.   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  893.   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  894.   if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  895.   {
  896.     Error_Handler();
  897.   }
  898.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  899.   if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  900.   {
  901.     Error_Handler();
  902.   }
  903.   if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
  904.   {
  905.     Error_Handler();
  906.   }
  907.   if (HAL_TIM_OnePulse_Init(&htim3, TIM_OPMODE_SINGLE) != HAL_OK)
  908.   {
  909.     Error_Handler();
  910.   }
  911.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
  912.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  913.   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  914.   {
  915.     Error_Handler();
  916.   }
  917.   sConfigOC.OCMode = TIM_OCMODE_TIMING;
  918.   sConfigOC.Pulse = 98;
  919.   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  920.   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  921.   if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  922.   {
  923.     Error_Handler();
  924.   }
  925.   /* USER CODE BEGIN TIM3_Init 2 */
  926.  
  927.   /* USER CODE END TIM3_Init 2 */
  928.  
  929. }
  930.  
  931. /**
  932.   * @brief TIM4 Initialization Function
  933.   * @param None
  934.   * @retval None
  935.   */
  936. static void MX_TIM4_Init(void)
  937. {
  938.  
  939.   /* USER CODE BEGIN TIM4_Init 0 */
  940.  
  941.   /* USER CODE END TIM4_Init 0 */
  942.  
  943.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  944.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  945.  
  946.   /* USER CODE BEGIN TIM4_Init 1 */
  947.  
  948.   /* USER CODE END TIM4_Init 1 */
  949.   htim4.Instance = TIM4;
  950.   htim4.Init.Prescaler = 719;
  951.   htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  952.   htim4.Init.Period = 9999;
  953.   htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  954.   htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  955.   if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  956.   {
  957.     Error_Handler();
  958.   }
  959.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  960.   if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  961.   {
  962.     Error_Handler();
  963.   }
  964.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  965.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  966.   if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  967.   {
  968.     Error_Handler();
  969.   }
  970.   /* USER CODE BEGIN TIM4_Init 2 */
  971.  
  972.   /* USER CODE END TIM4_Init 2 */
  973.  
  974. }
  975.  
  976. /**
  977.   * @brief USART1 Initialization Function
  978.   * @param None
  979.   * @retval None
  980.   */
  981. static void MX_USART1_UART_Init(void)
  982. {
  983.  
  984.   /* USER CODE BEGIN USART1_Init 0 */
  985.  
  986.   /* USER CODE END USART1_Init 0 */
  987.  
  988.   /* USER CODE BEGIN USART1_Init 1 */
  989.  
  990.   /* USER CODE END USART1_Init 1 */
  991.   huart1.Instance = USART1;
  992.   huart1.Init.BaudRate = 19200;
  993.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
  994.   huart1.Init.StopBits = UART_STOPBITS_1;
  995.   huart1.Init.Parity = UART_PARITY_NONE;
  996.   huart1.Init.Mode = UART_MODE_TX_RX;
  997.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  998.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  999.   if (HAL_UART_Init(&huart1) != HAL_OK)
  1000.   {
  1001.     Error_Handler();
  1002.   }
  1003.   /* USER CODE BEGIN USART1_Init 2 */
  1004.  
  1005.   /* USER CODE END USART1_Init 2 */
  1006.  
  1007. }
  1008.  
  1009. /**
  1010.   * Enable DMA controller clock
  1011.   */
  1012. static void MX_DMA_Init(void)
  1013. {
  1014.  
  1015.   /* DMA controller clock enable */
  1016.   __HAL_RCC_DMA1_CLK_ENABLE();
  1017.  
  1018.   /* DMA interrupt init */
  1019.   /* DMA1_Channel1_IRQn interrupt configuration */
  1020.   HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  1021.   HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  1022.  
  1023. }
  1024.  
  1025. /**
  1026.   * @brief GPIO Initialization Function
  1027.   * @param None
  1028.   * @retval None
  1029.   */
  1030. static void MX_GPIO_Init(void)
  1031. {
  1032.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  1033.  
  1034.   /* GPIO Ports Clock Enable */
  1035.   __HAL_RCC_GPIOC_CLK_ENABLE();
  1036.   __HAL_RCC_GPIOD_CLK_ENABLE();
  1037.   __HAL_RCC_GPIOA_CLK_ENABLE();
  1038.   __HAL_RCC_GPIOB_CLK_ENABLE();
  1039.  
  1040.   /*Configure GPIO pin Output Level */
  1041.   HAL_GPIO_WritePin(LED_Blink_GPIO_Port, LED_Blink_Pin, GPIO_PIN_RESET);
  1042.  
  1043.   /*Configure GPIO pin Output Level */
  1044.   HAL_GPIO_WritePin(GPIOB, SPI_NS_Temp_Pin|SPI_NS_Temp2_Pin|ENA_AUX_5V_Pin, GPIO_PIN_RESET);
  1045.  
  1046.   /*Configure GPIO pin : LED_Blink_Pin */
  1047.   GPIO_InitStruct.Pin = LED_Blink_Pin;
  1048.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  1049.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  1050.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  1051.   HAL_GPIO_Init(LED_Blink_GPIO_Port, &GPIO_InitStruct);
  1052.  
  1053.   /*Configure GPIO pins : SPI_NS_Temp_Pin SPI_NS_Temp2_Pin ENA_AUX_5V_Pin */
  1054.   GPIO_InitStruct.Pin = SPI_NS_Temp_Pin|SPI_NS_Temp2_Pin|ENA_AUX_5V_Pin;
  1055.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  1056.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  1057.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  1058.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  1059.  
  1060.   /*Configure GPIO pin : STARTER_ON_Pin */
  1061.   GPIO_InitStruct.Pin = STARTER_ON_Pin;
  1062.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  1063.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  1064.   HAL_GPIO_Init(STARTER_ON_GPIO_Port, &GPIO_InitStruct);
  1065.  
  1066. }
  1067.  
  1068. /* USER CODE BEGIN 4 */
  1069.  
  1070. /* USER CODE END 4 */
  1071.  
  1072. /**
  1073.   * @brief  This function is executed in case of error occurrence.
  1074.   * @retval None
  1075.   */
  1076. void Error_Handler(void)
  1077. {
  1078.   /* USER CODE BEGIN Error_Handler_Debug */
  1079. /* User can add his own implementation to report the HAL error return state */
  1080.  
  1081.   /* USER CODE END Error_Handler_Debug */
  1082. }
  1083.  
  1084. #ifdef  USE_FULL_ASSERT
  1085. /**
  1086.   * @brief  Reports the name of the source file and the source line number
  1087.   *         where the assert_param error has occurred.
  1088.   * @param  file: pointer to the source file name
  1089.   * @param  line: assert_param error line source number
  1090.   * @retval None
  1091.   */
  1092. void assert_failed(uint8_t *file, uint32_t line)
  1093. {
  1094.   /* USER CODE BEGIN 6 */
  1095.   /* User can add his own implementation to report the file name and line number,
  1096.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  1097.   /* USER CODE END 6 */
  1098. }
  1099. #endif /* USE_FULL_ASSERT */
  1100.  
  1101. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1102.