Subversion Repositories DashDisplay

Rev

Rev 60 | Rev 62 | 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.  
  26. #include "libPLX/plx.h"
  27. #include "libSerial/serial.H"
  28. #include "libSmallPrintf/small_printf.h"
  29. #include "libNMEA/nmea.h"
  30. #include "switches.h"
  31.  
  32. /* USER CODE END Includes */
  33.  
  34. /* Private typedef -----------------------------------------------------------*/
  35. /* USER CODE BEGIN PTD */
  36.  
  37. /* USER CODE END PTD */
  38.  
  39. /* Private define ------------------------------------------------------------*/
  40. /* USER CODE BEGIN PD */
  41. /* USER CODE END PD */
  42.  
  43. /* Private macro -------------------------------------------------------------*/
  44. /* USER CODE BEGIN PM */
  45.  
  46. /* USER CODE END PM */
  47.  
  48. /* Private variables ---------------------------------------------------------*/
  49.  SPI_HandleTypeDef hspi1;
  50.  
  51. TIM_HandleTypeDef htim2;
  52. TIM_HandleTypeDef htim3;
  53. TIM_HandleTypeDef htim9;
  54.  
  55. UART_HandleTypeDef huart4;
  56. UART_HandleTypeDef huart1;
  57. UART_HandleTypeDef huart2;
  58. UART_HandleTypeDef huart3;
  59.  
  60. /* USER CODE BEGIN PV */
  61. /* Private variables ---------------------------------------------------------*/
  62.  
  63. context_t contexts[MAX_DISPLAYS];
  64.  
  65. /* timeout when the ignition is switched off */
  66. #define IGNITION_OFF_TIMEOUT 30000UL
  67.  
  68. #define LOGGER_INTERVAL 500UL
  69.  
  70. const int DialTimeout = 10000; // about 10 seconds after twiddle, save the dial position.
  71.  
  72. nvram_info_t dial_nvram[MAX_DISPLAYS] __attribute__((section(".NVRAM_Data")));
  73.  
  74. info_t Info[MAXRDG];
  75.  
  76. /// \brief storage for incoming data
  77. data_t Data;
  78.  
  79. int PLXItems;
  80.  
  81. uint32_t Latch_Timer = IGNITION_OFF_TIMEOUT;
  82.  
  83. // location for GPS data
  84. Location loc;
  85.  
  86. /* USER CODE END PV */
  87.  
  88. /* Private function prototypes -----------------------------------------------*/
  89. void SystemClock_Config(void);
  90. static void MX_GPIO_Init(void);
  91. static void MX_SPI1_Init(void);
  92. static void MX_USART1_UART_Init(void);
  93. static void MX_USART2_UART_Init(void);
  94. static void MX_USART3_UART_Init(void);
  95. static void MX_TIM3_Init(void);
  96. static void MX_TIM9_Init(void);
  97. static void MX_TIM2_Init(void);
  98. static void MX_UART4_Init(void);
  99. /* USER CODE BEGIN PFP */
  100.  
  101. // the dial is the switch number we are using.
  102. // suppress is the ItemIndex we wish to suppress on this display
  103. int DisplayCurrent(int dial, int suppress)
  104. {
  105.   if (contexts[dial].knobPos < 0)
  106.     return -1;
  107.   return cc_display(dial, suppress);
  108. }
  109.  
  110. /// \note this code doesnt work so it leaves speed as 9600.
  111. /// \brief Setup Bluetooth module
  112. void initModule(usart_ctl *ctl, uint32_t baudRate)
  113. {
  114.   char initBuf[30];
  115.   // switch to command mode
  116.   HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin, GPIO_PIN_RESET);
  117.   HAL_Delay(500);
  118.   int initLen = small_sprintf(initBuf, "AT+UART=%ul,1,2\n", baudRate);
  119.   setBaud(ctl, 38400);
  120.   sendString(ctl, initBuf, initLen);
  121.   TxWaitEmpty(ctl);
  122.   // switch back to normal comms at new baud rate
  123.  
  124.   HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin, GPIO_PIN_SET);
  125.   setBaud(ctl, baudRate);
  126.   HAL_Delay(100);
  127. }
  128.  
  129. // workspace for RMC data read from GPS module.
  130. uint8_t rmc_buff[80];
  131. uint16_t rmc_length;
  132.  
  133. uint8_t rmc_callback(uint8_t *data, uint16_t length)
  134. {
  135.   rmc_length = length<sizeof(rmc_buff)?length : sizeof(rmc_buff);
  136.   memcpy(rmc_buff, data, length);
  137.   return 0;
  138.  
  139. }
  140.  
  141. /* USER CODE END PFP */
  142.  
  143. /* Private user code ---------------------------------------------------------*/
  144. /* USER CODE BEGIN 0 */
  145.  
  146. /* USER CODE END 0 */
  147.  
  148. /**
  149.   * @brief  The application entry point.
  150.   * @retval int
  151.   */
  152. int main(void)
  153. {
  154.   /* USER CODE BEGIN 1 */
  155.   __HAL_RCC_SPI1_CLK_ENABLE();
  156.   __HAL_RCC_USART1_CLK_ENABLE(); // PLX main port
  157.   __HAL_RCC_USART2_CLK_ENABLE(); // debug port
  158.   __HAL_RCC_USART3_CLK_ENABLE(); // Bluetooth port
  159.   __HAL_RCC_UART4_CLK_ENABLE();  // NMEA0183 port
  160.  
  161.   __HAL_RCC_TIM3_CLK_ENABLE();
  162.  
  163.   __HAL_RCC_TIM9_CLK_ENABLE();
  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.   // Switch handler called on sysTick interrupt.
  181.   InitSwitches();
  182.  
  183.   /* USER CODE END SysInit */
  184.  
  185.   /* Initialize all configured peripherals */
  186.   MX_GPIO_Init();
  187.   MX_SPI1_Init();
  188.   MX_USART1_UART_Init();
  189.   MX_USART2_UART_Init();
  190.   MX_USART3_UART_Init();
  191.   MX_TIM3_Init();
  192.   MX_TIM9_Init();
  193.   MX_TIM2_Init();
  194.   MX_UART4_Init();
  195.   /* USER CODE BEGIN 2 */
  196.  
  197.   /* Turn on USART1 IRQ */
  198.   HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
  199.   HAL_NVIC_EnableIRQ(USART1_IRQn);
  200.  
  201.   /* Turn on USART2 IRQ  */
  202.   HAL_NVIC_SetPriority(USART2_IRQn, 4, 0);
  203.   HAL_NVIC_EnableIRQ(USART2_IRQn);
  204.  
  205.   /* turn on USART3 IRQ */
  206.   HAL_NVIC_SetPriority(USART3_IRQn, 4, 0);
  207.   HAL_NVIC_EnableIRQ(USART3_IRQn);
  208.  
  209.   /* turn on UART4 IRQ */
  210.   HAL_NVIC_SetPriority(UART4_IRQn, 4, 0);
  211.   HAL_NVIC_EnableIRQ(UART4_IRQn);
  212.  
  213.   /* setup the USART control blocks */
  214.   init_usart_ctl(&uc1, &huart1);
  215.   init_usart_ctl(&uc2, &huart2);
  216.   init_usart_ctl(&uc3, &huart3);
  217.   init_usart_ctl(&uc4, &huart4);
  218.  
  219.   EnableSerialRxInterrupt(&uc1);
  220.   EnableSerialRxInterrupt(&uc2);
  221.   EnableSerialRxInterrupt(&uc3);
  222.   EnableSerialRxInterrupt(&uc4);
  223.  
  224.   HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
  225.  
  226.   HAL_TIM_Encoder_Start(&htim9, TIM_CHANNEL_ALL);
  227.  
  228.   initModule(&uc3, 9600);
  229.  
  230.   // Initialise UART for 4800 baud NMEA
  231.   setBaud(&uc2, 4800);
  232.  
  233.   // Initialuse UART4 for 4800 baud NMEA.
  234.   setBaud(&uc4, 4800);
  235.  
  236.   cc_init();
  237.  
  238.   int i;
  239.   for (i = 0; i < 2; i++)
  240.   {
  241.     dial_pos[i] = 0; // default to items 0 and 1
  242.     contexts[i].knobPos = -1;
  243.   }
  244.  
  245.   /* reset the display timeout, latch on power from accessories */
  246.   Latch_Timer = IGNITION_OFF_TIMEOUT;
  247.   HAL_GPIO_WritePin(POWER_LATCH_GPIO_Port, POWER_LATCH_Pin, GPIO_PIN_RESET);
  248.  
  249.   setRmcCallback(&rmc_callback);
  250.  
  251.   /* USER CODE END 2 */
  252.  
  253.   /* Infinite loop */
  254.   /* USER CODE BEGIN WHILE */
  255.   while (1)
  256.   {
  257.  
  258.     /* while ignition is on, keep resetting power latch timer */
  259.     if (HAL_GPIO_ReadPin(IGNITION_GPIO_Port, IGNITION_Pin) == GPIO_PIN_RESET)
  260.     {
  261.       Latch_Timer = HAL_GetTick() + IGNITION_OFF_TIMEOUT;
  262.     }
  263.     else
  264.     {
  265.       /* if the ignition has been off for a while, then turn off power */
  266.       if (HAL_GetTick() > Latch_Timer)
  267.       {
  268.         HAL_GPIO_WritePin(POWER_LATCH_GPIO_Port, POWER_LATCH_Pin,
  269.                           GPIO_PIN_RESET);
  270.       }
  271.     }
  272.  
  273.     uint32_t timeout = 0; //
  274.  
  275.     uint32_t nextTick = HAL_GetTick() + LOGGER_INTERVAL;
  276.     uint8_t log = 0;
  277.     // PLX decoder protocols
  278.     char PLXPacket = 0;
  279.     for (i = 0; i < MAXRDG; i++)
  280.     {
  281.       Info[i].Max = 0;
  282.       Info[i].Min = 0xFFF; // 12 bit max value
  283.     }
  284.  
  285.     int PLXPtr = 0;
  286.  
  287.     while (1)
  288.     {
  289.  
  290.       // poll GPS Position/time on UART4
  291.       (void) updateLocation(&loc, &uc4);
  292.       if (loc.good)
  293.       {
  294.  
  295.         loc.good = false;
  296.       }
  297.       if (loc.valid == 'V')
  298.         memset(loc.time, '-', 6);
  299.  
  300.       // Handle the bluetooth pairing / reset function by pressing both buttons.
  301.       if ((push_pos[0] == 1) && (push_pos[1] == 1))
  302.       {
  303.         HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
  304.                           GPIO_PIN_RESET);
  305.       }
  306.       else
  307.       {
  308.         HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
  309.                           GPIO_PIN_SET);
  310.       }
  311.  
  312.       uint16_t cc = SerialCharsReceived(&uc1);
  313.       int chr;
  314.       if (cc == 0)
  315.       {
  316.         timeout++;
  317.         if (timeout % 1000 == 0)
  318.         {
  319.           const char msg[] = "Timeout\r\n";
  320.           sendString(&uc3, msg, sizeof(msg));
  321.         }
  322.  
  323.         if (timeout > 60000)
  324.         {
  325.  
  326.           // do turn off screen
  327.         }
  328.       }
  329.       for (chr = 0; chr < cc; chr++)
  330.       {
  331.         char c = GetCharSerial(&uc1);
  332.  
  333.         if (c == PLX_Start) // at any time if the start byte appears, reset the pointers
  334.         {
  335.           PLXPtr = 0; // reset the pointer
  336.           PLXPacket = 1;
  337.           timeout = 0; // Reset the timer
  338.           if (HAL_GetTick() > nextTick)
  339.           {
  340.             nextTick = HAL_GetTick() + LOGGER_INTERVAL;
  341.             log = 1;
  342.           }
  343.           else
  344.             log = 0;
  345.         }
  346.         else if (c == PLX_Stop)
  347.         {
  348.           if (PLXPacket)
  349.           {
  350.             // we can now decode the selected parameter
  351.             PLXItems = PLXPtr / sizeof(PLX_SensorInfo); // total
  352.             // saturate the rotary switch position
  353.  
  354.             // process min/max
  355.             for (i = 0; i < PLXItems; i++)
  356.             {
  357.               Info[i].observation = ConvPLX(Data.Sensor[i].AddrH,
  358.                                             Data.Sensor[i].AddrL);
  359.               Info[i].instance = Data.Sensor[i].Instance;
  360.               Info[i].data = ConvPLX(Data.Sensor[i].ReadingH,
  361.                                      Data.Sensor[i].ReadingL);
  362.               if (Info[i].data > Info[i].Max)
  363.               {
  364.                 Info[i].Max = Info[i].data;
  365.               }
  366.               if (Info[i].data < Info[i].Min)
  367.               {
  368.                 Info[i].Min = Info[i].data;
  369.               }
  370.  
  371.               // Send items  to BT if it is in connected state
  372.               if (HAL_GPIO_ReadPin(BT_STATE_GPIO_Port, BT_STATE_Pin) == GPIO_PIN_SET)
  373.               {
  374.                 if (rmc_length)
  375.                 {
  376.                   sendString(&uc3, rmc_buff, rmc_length);
  377.                   rmc_length = 0;
  378.                 }
  379.  
  380.                 if (log)
  381.                 {
  382.  
  383.                   char outbuff[100];
  384.  
  385.                   int cnt = small_sprintf(outbuff,
  386.                                           "$PLLOG,%d,%d,%d",
  387.                                           Info[i].observation,
  388.                                           Info[i].instance,
  389.                                           Info[i].data);
  390.  
  391.                   // NMEA style checksum
  392.                   int ck;
  393.                   int sum = 0;
  394.                   for (ck = 1; ck < cnt; ck++)
  395.                     sum += outbuff[ck];
  396.                   cnt += small_sprintf(outbuff + cnt, "*%02X\n",
  397.                                        sum & 0xFF);
  398.                   sendString(&uc3, outbuff, cnt);
  399.                 }
  400.               }
  401.             }
  402.  
  403.             // now to display the information
  404.             int suppress = DisplayCurrent(0, -1);
  405.             DisplayCurrent(1, suppress);
  406.           }
  407.           PLXPtr = 0;
  408.           PLXPacket = 0;
  409.         }
  410.         else if (c > PLX_Stop) // illegal char, restart reading
  411.         {
  412.           PLXPacket = 0;
  413.           PLXPtr = 0;
  414.         }
  415.         else if (PLXPacket && PLXPtr < sizeof(Data.Bytes))
  416.         {
  417.           Data.Bytes[PLXPtr++] = c;
  418.         }
  419.       }
  420.  
  421.       HAL_Delay(1);
  422.  
  423.       for (i = 0; i < MAX_DISPLAYS; i++)
  424.       {
  425.         if (dial_pos[i] < 0)
  426.           dial_pos[i] = PLXItems - 1;
  427.         if (dial_pos[i] >= PLXItems)
  428.           dial_pos[i] = 0;
  429.  
  430.         int prevPos = contexts[i].knobPos;
  431.         if (contexts[i].knobPos >= 0)
  432.           contexts[i].knobPos = dial_pos[i];
  433.         // if the dial position was changed then reset timer
  434.         if (prevPos != contexts[i].knobPos)
  435.           contexts[i].dial_timer = DialTimeout;
  436.  
  437.         cc_check_nvram(i);
  438.         if (contexts[i].knobPos >= 0)
  439.           dial_pos[i] = contexts[i].knobPos;
  440.       }
  441.     }
  442.     /* USER CODE END WHILE */
  443.  
  444.     /* USER CODE BEGIN 3 */
  445.   }
  446.   /* USER CODE END 3 */
  447. }
  448.  
  449. /**
  450.   * @brief System Clock Configuration
  451.   * @retval None
  452.   */
  453. void SystemClock_Config(void)
  454. {
  455.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  456.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  457.  
  458.   /** Configure the main internal regulator output voltage
  459.   */
  460.   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  461.  
  462.   /** Initializes the RCC Oscillators according to the specified parameters
  463.   * in the RCC_OscInitTypeDef structure.
  464.   */
  465.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  466.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  467.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  468.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  469.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  470.   RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
  471.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  472.   {
  473.     Error_Handler();
  474.   }
  475.  
  476.   /** Initializes the CPU, AHB and APB buses clocks
  477.   */
  478.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  479.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  480.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  481.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  482.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  483.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  484.  
  485.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  486.   {
  487.     Error_Handler();
  488.   }
  489. }
  490.  
  491. /**
  492.   * @brief SPI1 Initialization Function
  493.   * @param None
  494.   * @retval None
  495.   */
  496. static void MX_SPI1_Init(void)
  497. {
  498.  
  499.   /* USER CODE BEGIN SPI1_Init 0 */
  500.  
  501.   /* USER CODE END SPI1_Init 0 */
  502.  
  503.   /* USER CODE BEGIN SPI1_Init 1 */
  504.  
  505.   /* USER CODE END SPI1_Init 1 */
  506.   /* SPI1 parameter configuration*/
  507.   hspi1.Instance = SPI1;
  508.   hspi1.Init.Mode = SPI_MODE_MASTER;
  509.   hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  510.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  511.   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  512.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  513.   hspi1.Init.NSS = SPI_NSS_SOFT;
  514.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  515.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  516.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  517.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  518.   hspi1.Init.CRCPolynomial = 10;
  519.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  520.   {
  521.     Error_Handler();
  522.   }
  523.   /* USER CODE BEGIN SPI1_Init 2 */
  524.  
  525.   /* USER CODE END SPI1_Init 2 */
  526.  
  527. }
  528.  
  529. /**
  530.   * @brief TIM2 Initialization Function
  531.   * @param None
  532.   * @retval None
  533.   */
  534. static void MX_TIM2_Init(void)
  535. {
  536.  
  537.   /* USER CODE BEGIN TIM2_Init 0 */
  538.  
  539.   /* USER CODE END TIM2_Init 0 */
  540.  
  541.   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  542.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  543.  
  544.   /* USER CODE BEGIN TIM2_Init 1 */
  545.  
  546.   /* USER CODE END TIM2_Init 1 */
  547.   htim2.Instance = TIM2;
  548.   htim2.Init.Prescaler = 0;
  549.   htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  550.   htim2.Init.Period = 65535;
  551.   htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  552.   htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  553.   if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  554.   {
  555.     Error_Handler();
  556.   }
  557.   sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  558.   if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  559.   {
  560.     Error_Handler();
  561.   }
  562.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  563.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  564.   if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  565.   {
  566.     Error_Handler();
  567.   }
  568.   /* USER CODE BEGIN TIM2_Init 2 */
  569.  
  570.   /* USER CODE END TIM2_Init 2 */
  571.  
  572. }
  573.  
  574. /**
  575.   * @brief TIM3 Initialization Function
  576.   * @param None
  577.   * @retval None
  578.   */
  579. static void MX_TIM3_Init(void)
  580. {
  581.  
  582.   /* USER CODE BEGIN TIM3_Init 0 */
  583.  
  584.   /* USER CODE END TIM3_Init 0 */
  585.  
  586.   TIM_Encoder_InitTypeDef sConfig = {0};
  587.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  588.  
  589.   /* USER CODE BEGIN TIM3_Init 1 */
  590.  
  591.   /* USER CODE END TIM3_Init 1 */
  592.   htim3.Instance = TIM3;
  593.   htim3.Init.Prescaler = 0;
  594.   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  595.   htim3.Init.Period = 65535;
  596.   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  597.   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  598.   sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
  599.   sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  600.   sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  601.   sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  602.   sConfig.IC1Filter = 15;
  603.   sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  604.   sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  605.   sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  606.   sConfig.IC2Filter = 15;
  607.   if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)
  608.   {
  609.     Error_Handler();
  610.   }
  611.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  612.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  613.   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  614.   {
  615.     Error_Handler();
  616.   }
  617.   /* USER CODE BEGIN TIM3_Init 2 */
  618.  
  619.   /* USER CODE END TIM3_Init 2 */
  620.  
  621. }
  622.  
  623. /**
  624.   * @brief TIM9 Initialization Function
  625.   * @param None
  626.   * @retval None
  627.   */
  628. static void MX_TIM9_Init(void)
  629. {
  630.  
  631.   /* USER CODE BEGIN TIM9_Init 0 */
  632.  
  633.   /* USER CODE END TIM9_Init 0 */
  634.  
  635.   TIM_Encoder_InitTypeDef sConfig = {0};
  636.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  637.  
  638.   /* USER CODE BEGIN TIM9_Init 1 */
  639.  
  640.   /* USER CODE END TIM9_Init 1 */
  641.   htim9.Instance = TIM9;
  642.   htim9.Init.Prescaler = 0;
  643.   htim9.Init.CounterMode = TIM_COUNTERMODE_UP;
  644.   htim9.Init.Period = 65535;
  645.   htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  646.   htim9.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  647.   sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
  648.   sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  649.   sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  650.   sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  651.   sConfig.IC1Filter = 15;
  652.   sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  653.   sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  654.   sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  655.   sConfig.IC2Filter = 0;
  656.   if (HAL_TIM_Encoder_Init(&htim9, &sConfig) != HAL_OK)
  657.   {
  658.     Error_Handler();
  659.   }
  660.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  661.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  662.   if (HAL_TIMEx_MasterConfigSynchronization(&htim9, &sMasterConfig) != HAL_OK)
  663.   {
  664.     Error_Handler();
  665.   }
  666.   /* USER CODE BEGIN TIM9_Init 2 */
  667.  
  668.   /* USER CODE END TIM9_Init 2 */
  669.  
  670. }
  671.  
  672. /**
  673.   * @brief UART4 Initialization Function
  674.   * @param None
  675.   * @retval None
  676.   */
  677. static void MX_UART4_Init(void)
  678. {
  679.  
  680.   /* USER CODE BEGIN UART4_Init 0 */
  681.  
  682.   /* USER CODE END UART4_Init 0 */
  683.  
  684.   /* USER CODE BEGIN UART4_Init 1 */
  685.  
  686.   /* USER CODE END UART4_Init 1 */
  687.   huart4.Instance = UART4;
  688.   huart4.Init.BaudRate = 4800;
  689.   huart4.Init.WordLength = UART_WORDLENGTH_8B;
  690.   huart4.Init.StopBits = UART_STOPBITS_1;
  691.   huart4.Init.Parity = UART_PARITY_NONE;
  692.   huart4.Init.Mode = UART_MODE_TX_RX;
  693.   huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  694.   huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  695.   if (HAL_UART_Init(&huart4) != HAL_OK)
  696.   {
  697.     Error_Handler();
  698.   }
  699.   /* USER CODE BEGIN UART4_Init 2 */
  700.  
  701.   /* USER CODE END UART4_Init 2 */
  702.  
  703. }
  704.  
  705. /**
  706.   * @brief USART1 Initialization Function
  707.   * @param None
  708.   * @retval None
  709.   */
  710. static void MX_USART1_UART_Init(void)
  711. {
  712.  
  713.   /* USER CODE BEGIN USART1_Init 0 */
  714.  
  715.   /* USER CODE END USART1_Init 0 */
  716.  
  717.   /* USER CODE BEGIN USART1_Init 1 */
  718.  
  719.   /* USER CODE END USART1_Init 1 */
  720.   huart1.Instance = USART1;
  721.   huart1.Init.BaudRate = 19200;
  722.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
  723.   huart1.Init.StopBits = UART_STOPBITS_1;
  724.   huart1.Init.Parity = UART_PARITY_NONE;
  725.   huart1.Init.Mode = UART_MODE_TX_RX;
  726.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  727.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  728.   if (HAL_UART_Init(&huart1) != HAL_OK)
  729.   {
  730.     Error_Handler();
  731.   }
  732.   /* USER CODE BEGIN USART1_Init 2 */
  733.  
  734.   /* USER CODE END USART1_Init 2 */
  735.  
  736. }
  737.  
  738. /**
  739.   * @brief USART2 Initialization Function
  740.   * @param None
  741.   * @retval None
  742.   */
  743. static void MX_USART2_UART_Init(void)
  744. {
  745.  
  746.   /* USER CODE BEGIN USART2_Init 0 */
  747.  
  748.   /* USER CODE END USART2_Init 0 */
  749.  
  750.   /* USER CODE BEGIN USART2_Init 1 */
  751.  
  752.   /* USER CODE END USART2_Init 1 */
  753.   huart2.Instance = USART2;
  754.   huart2.Init.BaudRate = 115200;
  755.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  756.   huart2.Init.StopBits = UART_STOPBITS_1;
  757.   huart2.Init.Parity = UART_PARITY_NONE;
  758.   huart2.Init.Mode = UART_MODE_TX_RX;
  759.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  760.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  761.   if (HAL_UART_Init(&huart2) != HAL_OK)
  762.   {
  763.     Error_Handler();
  764.   }
  765.   /* USER CODE BEGIN USART2_Init 2 */
  766.  
  767.   /* USER CODE END USART2_Init 2 */
  768.  
  769. }
  770.  
  771. /**
  772.   * @brief USART3 Initialization Function
  773.   * @param None
  774.   * @retval None
  775.   */
  776. static void MX_USART3_UART_Init(void)
  777. {
  778.  
  779.   /* USER CODE BEGIN USART3_Init 0 */
  780.  
  781.   /* USER CODE END USART3_Init 0 */
  782.  
  783.   /* USER CODE BEGIN USART3_Init 1 */
  784.  
  785.   /* USER CODE END USART3_Init 1 */
  786.   huart3.Instance = USART3;
  787.   huart3.Init.BaudRate = 19200;
  788.   huart3.Init.WordLength = UART_WORDLENGTH_8B;
  789.   huart3.Init.StopBits = UART_STOPBITS_1;
  790.   huart3.Init.Parity = UART_PARITY_NONE;
  791.   huart3.Init.Mode = UART_MODE_TX_RX;
  792.   huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  793.   huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  794.   if (HAL_UART_Init(&huart3) != HAL_OK)
  795.   {
  796.     Error_Handler();
  797.   }
  798.   /* USER CODE BEGIN USART3_Init 2 */
  799.  
  800.   /* USER CODE END USART3_Init 2 */
  801.  
  802. }
  803.  
  804. /**
  805.   * @brief GPIO Initialization Function
  806.   * @param None
  807.   * @retval None
  808.   */
  809. static void MX_GPIO_Init(void)
  810. {
  811.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  812.  
  813.   /* GPIO Ports Clock Enable */
  814.   __HAL_RCC_GPIOH_CLK_ENABLE();
  815.   __HAL_RCC_GPIOA_CLK_ENABLE();
  816.   __HAL_RCC_GPIOC_CLK_ENABLE();
  817.   __HAL_RCC_GPIOB_CLK_ENABLE();
  818.  
  819.   /*Configure GPIO pin Output Level */
  820.   HAL_GPIO_WritePin(SPI_NSS1_GPIO_Port, SPI_NSS1_Pin, GPIO_PIN_SET);
  821.  
  822.   /*Configure GPIO pin Output Level */
  823.   HAL_GPIO_WritePin(GPIOA, SPI_CD_Pin|BT_BUTTON_Pin, GPIO_PIN_RESET);
  824.  
  825.   /*Configure GPIO pin Output Level */
  826.   HAL_GPIO_WritePin(GPIOC, SPI_RESET_Pin|POWER_LATCH_Pin|USB_PWR_Pin, GPIO_PIN_RESET);
  827.  
  828.   /*Configure GPIO pin Output Level */
  829.   HAL_GPIO_WritePin(SPI_NSS2_GPIO_Port, SPI_NSS2_Pin, GPIO_PIN_SET);
  830.  
  831.   /*Configure GPIO pins : SPI_NSS1_Pin SPI_CD_Pin */
  832.   GPIO_InitStruct.Pin = SPI_NSS1_Pin|SPI_CD_Pin;
  833.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  834.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  835.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  836.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  837.  
  838.   /*Configure GPIO pins : SPI_RESET_Pin SPI_NSS2_Pin POWER_LATCH_Pin USB_PWR_Pin */
  839.   GPIO_InitStruct.Pin = SPI_RESET_Pin|SPI_NSS2_Pin|POWER_LATCH_Pin|USB_PWR_Pin;
  840.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  841.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  842.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  843.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  844.  
  845.   /*Configure GPIO pins : BT_STATE_Pin SW1_PUSH_Pin SW2_PUSH_Pin */
  846.   GPIO_InitStruct.Pin = BT_STATE_Pin|SW1_PUSH_Pin|SW2_PUSH_Pin;
  847.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  848.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  849.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  850.  
  851.   /*Configure GPIO pin : IGNITION_Pin */
  852.   GPIO_InitStruct.Pin = IGNITION_Pin;
  853.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  854.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  855.   HAL_GPIO_Init(IGNITION_GPIO_Port, &GPIO_InitStruct);
  856.  
  857.   /*Configure GPIO pin : BT_BUTTON_Pin */
  858.   GPIO_InitStruct.Pin = BT_BUTTON_Pin;
  859.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  860.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  861.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  862.   HAL_GPIO_Init(BT_BUTTON_GPIO_Port, &GPIO_InitStruct);
  863.  
  864. }
  865.  
  866. /* USER CODE BEGIN 4 */
  867.  
  868. /* USER CODE END 4 */
  869.  
  870. /**
  871.   * @brief  This function is executed in case of error occurrence.
  872.   * @retval None
  873.   */
  874. void Error_Handler(void)
  875. {
  876.   /* USER CODE BEGIN Error_Handler_Debug */
  877.   /* User can add his own implementation to report the HAL error return state */
  878.  
  879.   /* USER CODE END Error_Handler_Debug */
  880. }
  881.  
  882. #ifdef  USE_FULL_ASSERT
  883. /**
  884.   * @brief  Reports the name of the source file and the source line number
  885.   *         where the assert_param error has occurred.
  886.   * @param  file: pointer to the source file name
  887.   * @param  line: assert_param error line source number
  888.   * @retval None
  889.   */
  890. void assert_failed(uint8_t *file, uint32_t line)
  891. {
  892.   /* USER CODE BEGIN 6 */
  893.   /* User can add his own implementation to report the file name and line number,
  894.      tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  895.   /* USER CODE END 6 */
  896. }
  897. #endif /* USE_FULL_ASSERT */
  898.