Subversion Repositories EDIS_Ignition

Rev

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