Subversion Repositories EDIS_Ignition

Rev

Rev 21 | 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.  * Copyright (c) 2023 STMicroelectronics.
  10.  * All rights reserved.
  11.  *
  12.  * This software is licensed under terms that can be found in the LICENSE file
  13.  * in the root directory of this software component.
  14.  * If no LICENSE file comes with this software, it is provided AS-IS.
  15.  *
  16.  ******************************************************************************
  17.  */
  18. /* USER CODE END Header */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "main.h"
  21.  
  22. // #define TEST_CODE
  23.  
  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "memory.h"
  27. #include "display.h"
  28. #include "bmp280driver.h"
  29. #include "libMisc/fixI2C.h"
  30. #include "libPlx/plx.h"
  31. #include "libSerial/serial.h"
  32. #include "libIgnTiming/timing.h"
  33. #include "libIgnTiming/edis.h"
  34. #include "libIgnTiming/rpm.h"
  35. #include "saveTiming.h"
  36. #include "libPLX/commsLib.h"
  37. /* USER CODE END Includes */
  38.  
  39. /* Private typedef -----------------------------------------------------------*/
  40. /* USER CODE BEGIN PTD */
  41.  
  42. /* USER CODE END PTD */
  43.  
  44. /* Private define ------------------------------------------------------------*/
  45. /* USER CODE BEGIN PD */
  46. /* USER CODE END PD */
  47.  
  48. /* Private macro -------------------------------------------------------------*/
  49. /* USER CODE BEGIN PM */
  50.  
  51. /* USER CODE END PM */
  52.  
  53. /* Private variables ---------------------------------------------------------*/
  54. CAN_HandleTypeDef hcan;
  55.  
  56. I2C_HandleTypeDef hi2c1;
  57.  
  58. IWDG_HandleTypeDef hiwdg;
  59.  
  60. SPI_HandleTypeDef hspi1;
  61.  
  62. TIM_HandleTypeDef htim1;
  63. TIM_HandleTypeDef htim2;
  64. TIM_HandleTypeDef htim3;
  65.  
  66. UART_HandleTypeDef huart2;
  67.  
  68. /* USER CODE BEGIN PV */
  69. int const T100MS = 100;
  70.  
  71. int const DISPLAY_REINITIALISE = 60 * 1000;
  72. /// @brief compensated pressure in mb * 100
  73. uint32_t compensatedManifoldPressure = 0;
  74. /// @brief compensated atmospheric pressure
  75. uint32_t compensatedAtmosphericPressure = 0;
  76. /// @brief compensated temperature
  77. int32_t compensatedTemperature = -10000;
  78.  
  79. int32_t timing = 0;
  80.  
  81. // 1.5 degrees error in timing wheel this time ..
  82. int const TIMING_OFFSET = ((  -15) * TIMING_SCALE) /10;
  83.  
  84. // Switch over to doubDARK_RPM = 1200;
  85. // default atmospheric pressure - should be 1014
  86. uint32_t const DEFAULT_ATMOSPHERIC_PRESSURE = 1014 * 100;
  87.  
  88. uint32_t const DEFAULT_ATMOSPHERIC_TEMPERATURE = 25 * 100;
  89.  
  90. // Serial buffers
  91. #define TX_BUFFER_SIZE 128
  92. #define RX_BUFFER_SIZE 128
  93. unsigned volatile char tx_buffer[TX_BUFFER_SIZE];
  94. unsigned volatile char rx_buffer[RX_BUFFER_SIZE];
  95.  
  96. /* USER CODE END PV */
  97.  
  98. /* Private function prototypes -----------------------------------------------*/
  99. void SystemClock_Config(void);
  100. static void MX_GPIO_Init(void);
  101. static void MX_CAN_Init(void);
  102. static void MX_I2C1_Init(void);
  103. static void MX_TIM1_Init(void);
  104. static void MX_TIM2_Init(void);
  105. static void MX_SPI1_Init(void);
  106. static void MX_USART2_UART_Init(void);
  107. static void MX_TIM3_Init(void);
  108. static void MX_IWDG_Init(void);
  109. /* USER CODE BEGIN PFP */
  110.  
  111. void libPLXcallbackRecievedData(PLX_SensorInfo *info)
  112. {
  113.   (void)info;
  114. }
  115.  
  116. void libPLXcallbackSendUserData(struct usart_ctl *handle)
  117. {
  118.   // send MAP
  119.   PLX_SensorInfo info;
  120.   ConvToPLXInstance(libPLXgetNextInstance(PLX_MAP), &info);
  121.   ConvToPLXAddr(PLX_MAP, &info);
  122.   ConvToPLXReading(ConveriMFDData2Raw(PLX_MAP, PRESSURE_kPa, (float)(compensatedManifoldPressure) / 100.0), &info);
  123.   sendInfo(handle, &info);
  124.  
  125.   // send timing
  126.   ConvToPLXInstance(libPLXgetNextInstance(PLX_Timing), &info);
  127.   ConvToPLXAddr(PLX_Timing, &info);
  128.   ConvToPLXReading(ConveriMFDData2Raw(PLX_Timing, 0, (float)(timing) / TIMING_SCALE), &info);
  129.   sendInfo(handle, &info);
  130.  
  131.   // send temperature
  132.   ConvToPLXInstance(libPLXgetNextInstance(PLX_AIT), &info);
  133.   ConvToPLXAddr(PLX_AIT, &info);
  134.   ConvToPLXReading(ConveriMFDData2Raw(PLX_AIT, 0, (float)(compensatedTemperature) / 100.0), &info);
  135.   sendInfo(handle, &info);
  136. }
  137.  
  138. void triggerSAW()
  139. {
  140.   // trigger SAW timer, timer 1##pragma endregion
  141.  
  142.   __HAL_TIM_ENABLE(&htim1);
  143. }
  144.  
  145. /* USER CODE END PFP */
  146.  
  147. /* Private user code ---------------------------------------------------------*/
  148. /* USER CODE BEGIN 0 */
  149. void watchdogWrite()
  150. {
  151.   HAL_IWDG_Refresh(&hiwdg);
  152. }
  153.  
  154. /* USER CODE END 0 */
  155.  
  156. /**
  157.  * @brief  The application entry point.
  158.  * @retval int
  159.  */
  160. int main(void)
  161. {
  162.   /* USER CODE BEGIN 1 */
  163.  
  164.   /* USER CODE END 1 */
  165.  
  166.   /* MCU Configuration--------------------------------------------------------*/
  167.  
  168.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  169.   HAL_Init();
  170.  
  171.   /* USER CODE BEGIN Init */
  172.  
  173.   /* USER CODE END Init */
  174.  
  175.   /* Configure the system clock */
  176.   SystemClock_Config();
  177.  
  178.   /* USER CODE BEGIN SysInit */
  179.  
  180.   /* USER CODE END SysInit */
  181.  
  182.   /* Initialize all configured peripherals */
  183.   MX_GPIO_Init();
  184.   MX_CAN_Init();
  185.   MX_I2C1_Init();
  186.   MX_TIM1_Init();
  187.   MX_TIM2_Init();
  188.   MX_SPI1_Init();
  189.   MX_USART2_UART_Init();
  190.   MX_TIM3_Init();
  191.   MX_IWDG_Init();
  192.   /* USER CODE BEGIN 2 */
  193.  
  194.   init_usart_ctl(&uc2, &huart2, tx_buffer,
  195.                  rx_buffer,
  196.                  TX_BUFFER_SIZE,
  197.                  RX_BUFFER_SIZE);
  198.  
  199.   cc_init();
  200.  
  201.   HAL_TIM_Base_MspInit(&htim1);
  202.  
  203.   HAL_TIM_Base_Start(&htim1);
  204.   HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
  205.  
  206.   // initialise all the STMCubeMX stuff
  207.   HAL_TIM_Base_MspInit(&htim2);
  208.   // Start the counter
  209.   HAL_TIM_Base_Start(&htim2);
  210.   // Start the input capture and the rising edge interrupt
  211.   HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
  212.   // Start the input capture and the falling edge interrupt
  213.   HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
  214.  
  215.   __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 5); // delay of 5 uS
  216.  
  217.   // HAL_I2C_ClearBusyFlagErrata_2_14_7(&hi2c1);
  218.   MX_I2C1_Init();
  219.   init_bmp(&hi2c1, &bmpManifold, &confManifold);
  220.   init_bmp(&hi2c1, &bmpAtmosphere, &confAtmosphere);
  221.  
  222.   uint32_t nextTick = HAL_GetTick();
  223.   uint32_t displayOff = nextTick + 10000;
  224.   uint32_t displayReinitialise = nextTick + DISPLAY_REINITIALISE; // every minute, reinitialise display because of risk of noise
  225.  
  226.   uint8_t intensity = 2;
  227.  
  228.   ResetRxBuffer(&uc2);
  229.  
  230.   resetPLX();
  231.  
  232.   // HAL_IWDG_Init(&hiwdg);
  233.   /* USER CODE END 2 */
  234.  
  235.   /* Infinite loop */
  236.   /* USER CODE BEGIN WHILE */
  237.   while (1)
  238.   {
  239.  
  240.     int button = HAL_GPIO_ReadPin(PUSHBUTTON_GPIO_Port, PUSHBUTTON_Pin) == GPIO_PIN_RESET;
  241.  
  242.     if (button)
  243.     {
  244.       intensity = 2;
  245.       displayOff = HAL_GetTick() + 30000;
  246.     }
  247.  
  248.     switch (intensity)
  249.     {
  250.     case 2:
  251.       if (HAL_GetTick() > displayOff)
  252.       {
  253.         intensity = 1;
  254.         displayOff += 60000;
  255.       }
  256.  
  257.       break;
  258.     case 1:
  259.       if (HAL_GetTick() > displayOff)
  260.       {
  261.         intensity = 1; // was 0
  262.       }
  263.     default:
  264.       break;
  265.     }
  266.     // periodically write to the display and clear it
  267.     if (HAL_GetTick() > displayReinitialise)
  268.     {
  269.       displayReinitialise += DISPLAY_REINITIALISE;
  270.       cc_display(0, intensity, 1);
  271.     }
  272.     else
  273.       cc_display(0, intensity, 0);
  274.  
  275.     if (HAL_GetTick() > nextTick)
  276.     {
  277.       nextTick = HAL_GetTick() + T100MS;
  278.       uint8_t manifoldStatus = 1;
  279.       uint8_t temperatureStatus = 1;
  280.       uint8_t atmosphericStatus = 1;
  281.       /* Reading the raw data from manifold sensor */
  282.       struct bmp280_uncomp_data ucomp_data;
  283.  
  284.       uint8_t rslt = bmp280_get_uncomp_data(&ucomp_data, &bmpManifold);
  285.  
  286.       if (rslt == BMP280_OK)
  287.       {
  288.         // always calculate temperature then pressure so the pressure is correctly calibrated
  289.         temperatureStatus = bmp280_get_comp_temp_32bit(&compensatedTemperature, ucomp_data.uncomp_temp, &bmpManifold);
  290.         manifoldStatus = bmp280_get_comp_pres_32bit(&compensatedManifoldPressure, ucomp_data.uncomp_press, &bmpManifold);
  291.       }
  292.       // get atmospheric data
  293.       rslt = bmp280_get_uncomp_data(&ucomp_data, &bmpAtmosphere);
  294.       // now to read the environmental pressure
  295.       if (rslt == BMP280_OK)
  296.       {
  297.         // always calculate temperature then pressure so the pressure is correctly calibrated
  298.         temperatureStatus = bmp280_get_comp_temp_32bit(&compensatedTemperature, ucomp_data.uncomp_temp, &bmpAtmosphere);
  299.         atmosphericStatus = bmp280_get_comp_pres_32bit(&compensatedAtmosphericPressure, ucomp_data.uncomp_press, &bmpAtmosphere);
  300.       }
  301.       if (manifoldStatus != BMP280_OK)
  302.         compensatedManifoldPressure = DEFAULT_ATMOSPHERIC_PRESSURE;
  303.       if (temperatureStatus != BMP280_OK)
  304.         compensatedTemperature = DEFAULT_ATMOSPHERIC_TEMPERATURE;
  305.       if (atmosphericStatus != BMP280_OK)
  306.         compensatedAtmosphericPressure = DEFAULT_ATMOSPHERIC_PRESSURE;
  307. #if defined TEST_CODE
  308.       compensatedManifoldPressure = 100000;
  309.       compensatedTemperature = 4000;
  310. #endif
  311.  
  312.       int32_t vacuum = compensatedAtmosphericPressure - compensatedManifoldPressure;
  313.       if (vacuum < 0)
  314.         vacuum = 0;
  315.       // if the BMP280 pressure is good, then allow it through, otherwise drop to
  316.       // centrifugal advance only.
  317.       // feed difference and add default pressure
  318.       cc_feed_env(compensatedAtmosphericPressure, 100000 - vacuum, compensatedTemperature);
  319.  
  320.       // compute RPM value, feed to display
  321. #if defined TEST_CODE
  322.       int rpm = 1000;
  323. #else
  324.       int rpm = CalculateRPM();
  325. #endif
  326.       if (rpm > 0)
  327.       {
  328.         cc_feed_rpm(rpm);
  329.         // compute timing value, feed to display
  330.         timing = mapTiming(rpm, vacuum / 100);
  331.         cc_feed_timing(timing);
  332.         // enable double spark below 1200  (DUAL_SPARK_RPM) rpm
  333.         int microsecs = mapTimingToMicroseconds(timing + TIMING_OFFSET,  rpm  < DUAL_SPARK_RPM);
  334.         __HAL_TIM_SET_AUTORELOAD(&htim1, microsecs + SAW_DELAY);
  335.       }
  336.     }
  337.  
  338.     // Handle PLX
  339.     libPLXpollData(&uc2);
  340.  
  341.     /* USER CODE END WHILE */
  342.  
  343.     /* USER CODE BEGIN 3 */
  344.     watchdogWrite();
  345.  
  346.     HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  347.  
  348.     // todo occasionally     saveTimingInfoToNvram();
  349.   }
  350.   /* USER CODE END 3 */
  351. }
  352.  
  353. /**
  354.  * @brief System Clock Configuration
  355.  * @retval None
  356.  */
  357. void SystemClock_Config(void)
  358. {
  359.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  360.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  361.  
  362.   /** Initializes the RCC Oscillators according to the specified parameters
  363.    * in the RCC_OscInitTypeDef structure.
  364.    */
  365.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE;
  366.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  367.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  368.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  369.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  370.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  371.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  372.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  373.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  374.   {
  375.     Error_Handler();
  376.   }
  377.  
  378.   /** Initializes the CPU, AHB and APB buses clocks
  379.    */
  380.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  381.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  382.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  383.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  384.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  385.  
  386.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  387.   {
  388.     Error_Handler();
  389.   }
  390. }
  391.  
  392. /**
  393.  * @brief CAN Initialization Function
  394.  * @param None
  395.  * @retval None
  396.  */
  397. static void MX_CAN_Init(void)
  398. {
  399.  
  400.   /* USER CODE BEGIN CAN_Init 0 */
  401.  
  402.   /* USER CODE END CAN_Init 0 */
  403.  
  404.   /* USER CODE BEGIN CAN_Init 1 */
  405.  
  406.   /* USER CODE END CAN_Init 1 */
  407.   hcan.Instance = CAN1;
  408.   hcan.Init.Prescaler = 18;
  409.   hcan.Init.Mode = CAN_MODE_NORMAL;
  410.   hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  411.   hcan.Init.TimeSeg1 = CAN_BS1_3TQ;
  412.   hcan.Init.TimeSeg2 = CAN_BS2_4TQ;
  413.   hcan.Init.TimeTriggeredMode = DISABLE;
  414.   hcan.Init.AutoBusOff = DISABLE;
  415.   hcan.Init.AutoWakeUp = DISABLE;
  416.   hcan.Init.AutoRetransmission = DISABLE;
  417.   hcan.Init.ReceiveFifoLocked = DISABLE;
  418.   hcan.Init.TransmitFifoPriority = DISABLE;
  419.   if (HAL_CAN_Init(&hcan) != HAL_OK)
  420.   {
  421.     Error_Handler();
  422.   }
  423.   /* USER CODE BEGIN CAN_Init 2 */
  424.  
  425.   /* USER CODE END CAN_Init 2 */
  426. }
  427.  
  428. /**
  429.  * @brief I2C1 Initialization Function
  430.  * @param None
  431.  * @retval None
  432.  */
  433. static void MX_I2C1_Init(void)
  434. {
  435.  
  436.   /* USER CODE BEGIN I2C1_Init 0 */
  437.  
  438.   /* USER CODE END I2C1_Init 0 */
  439.  
  440.   /* USER CODE BEGIN I2C1_Init 1 */
  441.  
  442.   /* USER CODE END I2C1_Init 1 */
  443.   hi2c1.Instance = I2C1;
  444.   hi2c1.Init.ClockSpeed = 100000;
  445.   hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  446.   hi2c1.Init.OwnAddress1 = 0;
  447.   hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  448.   hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  449.   hi2c1.Init.OwnAddress2 = 0;
  450.   hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  451.   hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  452.   if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  453.   {
  454.     Error_Handler();
  455.   }
  456.   /* USER CODE BEGIN I2C1_Init 2 */
  457.  
  458.   /* USER CODE END I2C1_Init 2 */
  459. }
  460.  
  461. /**
  462.  * @brief IWDG Initialization Function
  463.  * @param None
  464.  * @retval None
  465.  */
  466. static void MX_IWDG_Init(void)
  467. {
  468.  
  469.   /* USER CODE BEGIN IWDG_Init 0 */
  470.  
  471.   /* USER CODE END IWDG_Init 0 */
  472.  
  473.   /* USER CODE BEGIN IWDG_Init 1 */
  474.  
  475.   /* USER CODE END IWDG_Init 1 */
  476.   hiwdg.Instance = IWDG;
  477.   hiwdg.Init.Prescaler = IWDG_PRESCALER_4;
  478.   hiwdg.Init.Reload = 1000;
  479.   if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  480.   {
  481.     Error_Handler();
  482.   }
  483.   /* USER CODE BEGIN IWDG_Init 2 */
  484.  
  485.   /* USER CODE END IWDG_Init 2 */
  486. }
  487.  
  488. /**
  489.  * @brief SPI1 Initialization Function
  490.  * @param None
  491.  * @retval None
  492.  */
  493. static void MX_SPI1_Init(void)
  494. {
  495.  
  496.   /* USER CODE BEGIN SPI1_Init 0 */
  497.  
  498.   /* USER CODE END SPI1_Init 0 */
  499.  
  500.   /* USER CODE BEGIN SPI1_Init 1 */
  501.  
  502.   /* USER CODE END SPI1_Init 1 */
  503.   /* SPI1 parameter configuration*/
  504.   hspi1.Instance = SPI1;
  505.   hspi1.Init.Mode = SPI_MODE_MASTER;
  506.   hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  507.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  508.   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  509.   hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  510.   hspi1.Init.NSS = SPI_NSS_SOFT;
  511.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
  512.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  513.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  514.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  515.   hspi1.Init.CRCPolynomial = 10;
  516.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  517.   {
  518.     Error_Handler();
  519.   }
  520.   /* USER CODE BEGIN SPI1_Init 2 */
  521.  
  522.   /* USER CODE END SPI1_Init 2 */
  523. }
  524.  
  525. /**
  526.  * @brief TIM1 Initialization Function
  527.  * @param None
  528.  * @retval None
  529.  */
  530. static void MX_TIM1_Init(void)
  531. {
  532.  
  533.   /* USER CODE BEGIN TIM1_Init 0 */
  534.  
  535.   /* USER CODE END TIM1_Init 0 */
  536.  
  537.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  538.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  539.   TIM_OC_InitTypeDef sConfigOC = {0};
  540.   TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};
  541.  
  542.   /* USER CODE BEGIN TIM1_Init 1 */
  543.  
  544.   /* USER CODE END TIM1_Init 1 */
  545.   htim1.Instance = TIM1;
  546.   htim1.Init.Prescaler = 71;
  547.   htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  548.   htim1.Init.Period = 65535;
  549.   htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  550.   htim1.Init.RepetitionCounter = 0;
  551.   htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  552.   if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  553.   {
  554.     Error_Handler();
  555.   }
  556.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  557.   if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  558.   {
  559.     Error_Handler();
  560.   }
  561.   if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
  562.   {
  563.     Error_Handler();
  564.   }
  565.   if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
  566.   {
  567.     Error_Handler();
  568.   }
  569.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
  570.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  571.   if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  572.   {
  573.     Error_Handler();
  574.   }
  575.   sConfigOC.OCMode = TIM_OCMODE_PWM1;
  576.   sConfigOC.Pulse = SAW_DELAY;
  577.   sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  578.   sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
  579.   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  580.   sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
  581.   sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
  582.   if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  583.   {
  584.     Error_Handler();
  585.   }
  586.   sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  587.   sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  588.   sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  589.   sBreakDeadTimeConfig.DeadTime = 0;
  590.   sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  591.   sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  592.   sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  593.   if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  594.   {
  595.     Error_Handler();
  596.   }
  597.   /* USER CODE BEGIN TIM1_Init 2 */
  598.  
  599.   /* USER CODE END TIM1_Init 2 */
  600.   HAL_TIM_MspPostInit(&htim1);
  601. }
  602.  
  603. /**
  604.  * @brief TIM2 Initialization Function
  605.  * @param None
  606.  * @retval None
  607.  */
  608. static void MX_TIM2_Init(void)
  609. {
  610.  
  611.   /* USER CODE BEGIN TIM2_Init 0 */
  612.  
  613.   /* USER CODE END TIM2_Init 0 */
  614.  
  615.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  616.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  617.   TIM_IC_InitTypeDef sConfigIC = {0};
  618.  
  619.   /* USER CODE BEGIN TIM2_Init 1 */
  620.  
  621.   /* USER CODE END TIM2_Init 1 */
  622.   htim2.Instance = TIM2;
  623.   htim2.Init.Prescaler = 719;
  624.   htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  625.   htim2.Init.Period = 65535;
  626.   htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  627.   htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  628.   if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  629.   {
  630.     Error_Handler();
  631.   }
  632.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  633.   if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  634.   {
  635.     Error_Handler();
  636.   }
  637.   if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
  638.   {
  639.     Error_Handler();
  640.   }
  641.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  642.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  643.   if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  644.   {
  645.     Error_Handler();
  646.   }
  647.   sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  648.   sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  649.   sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  650.   sConfigIC.ICFilter = 0;
  651.   if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
  652.   {
  653.     Error_Handler();
  654.   }
  655.   sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
  656.   sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
  657.   if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
  658.   {
  659.     Error_Handler();
  660.   }
  661.   /* USER CODE BEGIN TIM2_Init 2 */
  662.  
  663.   /* USER CODE END TIM2_Init 2 */
  664. }
  665.  
  666. /**
  667.  * @brief TIM3 Initialization Function
  668.  * @param None
  669.  * @retval None
  670.  */
  671. static void MX_TIM3_Init(void)
  672. {
  673.  
  674.   /* USER CODE BEGIN TIM3_Init 0 */
  675.  
  676.   /* USER CODE END TIM3_Init 0 */
  677.  
  678.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  679.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  680.  
  681.   /* USER CODE BEGIN TIM3_Init 1 */
  682.  
  683.   /* USER CODE END TIM3_Init 1 */
  684.   htim3.Instance = TIM3;
  685.   htim3.Init.Prescaler = 719;
  686.   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  687.   htim3.Init.Period = 10000;
  688.   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  689.   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  690.   if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  691.   {
  692.     Error_Handler();
  693.   }
  694.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  695.   if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  696.   {
  697.     Error_Handler();
  698.   }
  699.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  700.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  701.   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  702.   {
  703.     Error_Handler();
  704.   }
  705.   /* USER CODE BEGIN TIM3_Init 2 */
  706.  
  707.   /* USER CODE END TIM3_Init 2 */
  708. }
  709.  
  710. /**
  711.  * @brief USART2 Initialization Function
  712.  * @param None
  713.  * @retval None
  714.  */
  715. static void MX_USART2_UART_Init(void)
  716. {
  717.  
  718.   /* USER CODE BEGIN USART2_Init 0 */
  719.  
  720.   /* USER CODE END USART2_Init 0 */
  721.  
  722.   /* USER CODE BEGIN USART2_Init 1 */
  723.  
  724.   /* USER CODE END USART2_Init 1 */
  725.   huart2.Instance = USART2;
  726.   huart2.Init.BaudRate = 19200;
  727.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  728.   huart2.Init.StopBits = UART_STOPBITS_1;
  729.   huart2.Init.Parity = UART_PARITY_NONE;
  730.   huart2.Init.Mode = UART_MODE_TX_RX;
  731.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  732.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  733.   if (HAL_UART_Init(&huart2) != HAL_OK)
  734.   {
  735.     Error_Handler();
  736.   }
  737.   /* USER CODE BEGIN USART2_Init 2 */
  738.  
  739.   /* USER CODE END USART2_Init 2 */
  740. }
  741.  
  742. /**
  743.  * @brief GPIO Initialization Function
  744.  * @param None
  745.  * @retval None
  746.  */
  747. static void MX_GPIO_Init(void)
  748. {
  749.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  750.   /* USER CODE BEGIN MX_GPIO_Init_1 */
  751.   /* USER CODE END MX_GPIO_Init_1 */
  752.  
  753.   /* GPIO Ports Clock Enable */
  754.   __HAL_RCC_GPIOC_CLK_ENABLE();
  755.   __HAL_RCC_GPIOD_CLK_ENABLE();
  756.   __HAL_RCC_GPIOA_CLK_ENABLE();
  757.   __HAL_RCC_GPIOB_CLK_ENABLE();
  758.  
  759.   /*Configure GPIO pin Output Level */
  760.   HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
  761.  
  762.   /*Configure GPIO pin Output Level */
  763.   HAL_GPIO_WritePin(GPIOA, SPI1_NSS_Pin | SPI1_RESET_Pin, GPIO_PIN_RESET);
  764.  
  765.   /*Configure GPIO pin Output Level */
  766.   HAL_GPIO_WritePin(SPI1_CD_GPIO_Port, SPI1_CD_Pin, GPIO_PIN_RESET);
  767.  
  768.   /*Configure GPIO pin : LED_Pin */
  769.   GPIO_InitStruct.Pin = LED_Pin;
  770.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  771.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  772.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  773.   HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
  774.  
  775.   /*Configure GPIO pins : SPI1_NSS_Pin SPI1_RESET_Pin */
  776.   GPIO_InitStruct.Pin = SPI1_NSS_Pin | SPI1_RESET_Pin;
  777.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  778.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  779.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  780.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  781.  
  782.   /*Configure GPIO pin : SPI1_CD_Pin */
  783.   GPIO_InitStruct.Pin = SPI1_CD_Pin;
  784.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  785.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  786.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  787.   HAL_GPIO_Init(SPI1_CD_GPIO_Port, &GPIO_InitStruct);
  788.  
  789.   /*Configure GPIO pin : PUSHBUTTON_Pin */
  790.   GPIO_InitStruct.Pin = PUSHBUTTON_Pin;
  791.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  792.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  793.   HAL_GPIO_Init(PUSHBUTTON_GPIO_Port, &GPIO_InitStruct);
  794.  
  795.   /*Configure GPIO pin : dualSpark_Pin */
  796.   GPIO_InitStruct.Pin = dualSpark_Pin;
  797.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  798.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  799.   HAL_GPIO_Init(dualSpark_GPIO_Port, &GPIO_InitStruct);
  800.  
  801.   /* USER CODE BEGIN MX_GPIO_Init_2 */
  802.   /* USER CODE END MX_GPIO_Init_2 */
  803. }
  804.  
  805. /* USER CODE BEGIN 4 */
  806.  
  807. /* USER CODE END 4 */
  808.  
  809. /**
  810.  * @brief  This function is executed in case of error occurrence.
  811.  * @retval None
  812.  */
  813. void Error_Handler(void)
  814. {
  815.   /* USER CODE BEGIN Error_Handler_Debug */
  816.   /* User can add his own implementation to report the HAL error return state */
  817.   __disable_irq();
  818.   while (1)
  819.   {
  820.   }
  821.   /* USER CODE END Error_Handler_Debug */
  822. }
  823.  
  824. #ifdef USE_FULL_ASSERT
  825. /**
  826.  * @brief  Reports the name of the source file and the source line number
  827.  *         where the assert_param error has occurred.
  828.  * @param  file: pointer to the source file name
  829.  * @param  line: assert_param error line source number
  830.  * @retval None
  831.  */
  832. void assert_failed(uint8_t *file, uint32_t line)
  833. {
  834.   /* USER CODE BEGIN 6 */
  835.   /* User can add his own implementation to report the file name and line number,
  836.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  837.   /* USER CODE END 6 */
  838. }
  839. #endif /* USE_FULL_ASSERT */
  840.