Subversion Repositories EngineBay2

Rev

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