Subversion Repositories EngineBay2

Rev

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