Subversion Repositories EngineBay2

Rev

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