Subversion Repositories AFRtranscoder

Rev

Rev 2 | 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. /* Private includes ----------------------------------------------------------*/
  23. /* USER CODE BEGIN Includes */
  24. #include "libSerial/serial.h"
  25. #include "libPLX/commsLib.h"
  26. #include "libTinyWB/tinyWB.h"
  27.  
  28. // Semihosting enable : see
  29. // https://community.st.com/t5/stm32-mcus/how-to-use-semihosting-with-stm32cubeide-and-stm32/ta-p/49742
  30. /// #include <stdio.h>
  31. // extern void initialise_monitor_handles(void);
  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.  
  42. /* USER CODE END PD */
  43.  
  44. /* Private macro -------------------------------------------------------------*/
  45. /* USER CODE BEGIN PM */
  46.  
  47. /* USER CODE END PM */
  48.  
  49. /* Private variables ---------------------------------------------------------*/
  50. CAN_HandleTypeDef hcan;
  51.  
  52. IWDG_HandleTypeDef hiwdg;
  53.  
  54. SPI_HandleTypeDef hspi1;
  55.  
  56. UART_HandleTypeDef huart1;
  57. UART_HandleTypeDef huart2;
  58.  
  59. /* USER CODE BEGIN PV */
  60. #define MIN_RPM_FOR_HEAT 400
  61. /// 20 seconds to warm up before enabling the heater
  62. #define MIN_RPM_TIME_ACTIVE 20000
  63.  
  64. uint8_t volatile tx1Buffer[TX_USART_BUFF_SIZ];
  65. uint8_t volatile tx2Buffer[TX_USART_BUFF_SIZ];
  66. uint8_t volatile rx1Buffer[RX_USART_BUFF_SIZ];
  67. uint8_t volatile rx2Buffer[RX_USART_BUFF_SIZ];
  68.  
  69. float AFRValue = 14.7;
  70. float temperature = 0;
  71.  
  72. uint32_t timeValue = 0;
  73.  
  74. uint8_t heaterEnable = 0;
  75.  
  76. /* USER CODE END PV */
  77.  
  78. /* Private function prototypes -----------------------------------------------*/
  79. void SystemClock_Config(void);
  80. static void MX_GPIO_Init(void);
  81. static void MX_CAN_Init(void);
  82. static void MX_SPI1_Init(void);
  83. static void MX_USART1_UART_Init(void);
  84. static void MX_USART2_UART_Init(void);
  85. static void MX_IWDG_Init(void);
  86. /* USER CODE BEGIN PFP */
  87.  
  88. // user provided callback symbol
  89. void libPLXcallbackSendUserData()
  90. {
  91.  
  92.   HAL_GPIO_TogglePin(YELLOW_LED_GPIO_Port, YELLOW_LED_Pin);
  93.   // send AFR
  94.   PLX_SensorInfo info;
  95.   ConvToPLXInstance(libPLXgetNextInstance(PLX_AFR), &info);
  96.   ConvToPLXAddr(PLX_AFR, &info);
  97.   ConvToPLXReading(ConveriMFDData2Raw(PLX_AFR, AFR_Gasoline, AFRValue), &info);
  98.   sendInfo(&uc2, &info);
  99. }
  100.  
  101. // this setup actually turns the heater on if the RPM is not reported at all
  102. // after timeout, or once the RPM is reported, it delays timeout after RPM exceeds the lower limit
  103.  
  104. // User provided callback symbol on receipt of data
  105. void libPLXcallbackRecievedData(PLX_SensorInfo *info)
  106. {
  107.   uint16_t addr = ConvPLXAddr(info);
  108.   if (addr == PLX_RPM)
  109.   {
  110.     uint16_t rpm = ConveriMFDRaw2Data(PLX_RPM, 0, ConvPLXReading(info));
  111.     // reset time value if the engine isnt running at correct RPM
  112.     if (rpm < MIN_RPM_FOR_HEAT)
  113.       timeValue = HAL_GetTick();
  114.   }
  115. }
  116.  
  117. void checkHeaterEnable(void)
  118. {
  119.  
  120.   heaterEnable = (HAL_GetTick() - timeValue) > MIN_RPM_TIME_ACTIVE;
  121.   // Active low pin to enable AFR if RPM has exceeded minimum for at least the active time
  122.   HAL_GPIO_WritePin(enableAFRN_GPIO_Port, enableAFRN_Pin, heaterEnable ? GPIO_PIN_RESET : GPIO_PIN_SET);
  123.  
  124.   HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, heaterEnable);
  125. }
  126.  
  127. // refresh watchdog timer
  128. void watchdogWrite()
  129. {
  130.   HAL_IWDG_Refresh(&hiwdg);
  131. }
  132.  
  133. /* USER CODE END PFP */
  134.  
  135. /* Private user code ---------------------------------------------------------*/
  136. /* USER CODE BEGIN 0 */
  137.  
  138. /* USER CODE END 0 */
  139.  
  140. /**
  141.  * @brief  The application entry point.
  142.  * @retval int
  143.  */
  144. int main(void)
  145. {
  146.   /* USER CODE BEGIN 1 */
  147.   //  initialise_monitor_handles();
  148.  
  149.   /* USER CODE END 1 */
  150.  
  151.   /* MCU Configuration--------------------------------------------------------*/
  152.  
  153.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  154.   HAL_Init();
  155.  
  156.   /* USER CODE BEGIN Init */
  157.  
  158.   /* USER CODE END Init */
  159.  
  160.   /* Configure the system clock */
  161.   SystemClock_Config();
  162.  
  163.   /* USER CODE BEGIN SysInit */
  164.  
  165.   /* USER CODE END SysInit */
  166.  
  167.   /* Initialize all configured peripherals */
  168.   MX_GPIO_Init();
  169.   MX_CAN_Init();
  170.   MX_SPI1_Init();
  171.   MX_USART1_UART_Init();
  172.   MX_USART2_UART_Init();
  173.   MX_IWDG_Init();
  174.   /* USER CODE BEGIN 2 */
  175.   init_usart_ctl(&uc1, &huart1, tx1Buffer, rx1Buffer, TX_USART_BUFF_SIZ, RX_USART_BUFF_SIZ);
  176.   init_usart_ctl(&uc2, &huart2, tx2Buffer, rx2Buffer, TX_USART_BUFF_SIZ, RX_USART_BUFF_SIZ);
  177.  
  178.   ResetRxBuffer(&uc1);
  179.   ResetRxBuffer(&uc2);
  180.  
  181.   resetPLX();
  182.  
  183.   /* USER CODE END 2 */
  184.  
  185.   /* Infinite loop */
  186.   /* USER CODE BEGIN WHILE */
  187.   while (1)
  188.   {
  189.  
  190.     pollTinyWB(&uc1, &AFRValue, &temperature);
  191.     // Handle PLX
  192.     libPLXpollData(&uc2);
  193.  
  194.     checkHeaterEnable();
  195.     watchdogWrite();
  196.  
  197.     HAL_Delay(10);
  198.     /* USER CODE END WHILE */
  199.  
  200.     /* USER CODE BEGIN 3 */
  201.   }
  202.   /* USER CODE END 3 */
  203. }
  204.  
  205. /**
  206.  * @brief System Clock Configuration
  207.  * @retval None
  208.  */
  209. void SystemClock_Config(void)
  210. {
  211.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  212.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  213.  
  214.   /** Initializes the RCC Oscillators according to the specified parameters
  215.    * in the RCC_OscInitTypeDef structure.
  216.    */
  217.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE;
  218.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  219.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  220.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  221.   RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  222.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  223.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  224.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL8;
  225.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  226.   {
  227.     Error_Handler();
  228.   }
  229.  
  230.   /** Initializes the CPU, AHB and APB buses clocks
  231.    */
  232.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  233.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  234.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  235.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  236.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  237.  
  238.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  239.   {
  240.     Error_Handler();
  241.   }
  242. }
  243.  
  244. /**
  245.  * @brief CAN Initialization Function
  246.  * @param None
  247.  * @retval None
  248.  */
  249. static void MX_CAN_Init(void)
  250. {
  251.  
  252.   /* USER CODE BEGIN CAN_Init 0 */
  253.  
  254.   /* USER CODE END CAN_Init 0 */
  255.  
  256.   /* USER CODE BEGIN CAN_Init 1 */
  257.  
  258.   /* USER CODE END CAN_Init 1 */
  259.   hcan.Instance = CAN1;
  260.   hcan.Init.Prescaler = 16;
  261.   hcan.Init.Mode = CAN_MODE_NORMAL;
  262.   hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  263.   hcan.Init.TimeSeg1 = CAN_BS1_2TQ;
  264.   hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
  265.   hcan.Init.TimeTriggeredMode = DISABLE;
  266.   hcan.Init.AutoBusOff = DISABLE;
  267.   hcan.Init.AutoWakeUp = DISABLE;
  268.   hcan.Init.AutoRetransmission = DISABLE;
  269.   hcan.Init.ReceiveFifoLocked = DISABLE;
  270.   hcan.Init.TransmitFifoPriority = DISABLE;
  271.   if (HAL_CAN_Init(&hcan) != HAL_OK)
  272.   {
  273.     Error_Handler();
  274.   }
  275.   /* USER CODE BEGIN CAN_Init 2 */
  276.  
  277.   /* USER CODE END CAN_Init 2 */
  278. }
  279.  
  280. /**
  281.  * @brief IWDG Initialization Function
  282.  * @param None
  283.  * @retval None
  284.  */
  285. static void MX_IWDG_Init(void)
  286. {
  287.  
  288.   /* USER CODE BEGIN IWDG_Init 0 */
  289.  
  290.   /* USER CODE END IWDG_Init 0 */
  291.  
  292.   /* USER CODE BEGIN IWDG_Init 1 */
  293.  
  294.   /* USER CODE END IWDG_Init 1 */
  295.   hiwdg.Instance = IWDG;
  296.   hiwdg.Init.Prescaler = IWDG_PRESCALER_32;
  297.   hiwdg.Init.Reload = 4095;
  298.   if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  299.   {
  300.     Error_Handler();
  301.   }
  302.   /* USER CODE BEGIN IWDG_Init 2 */
  303.  
  304.   /* USER CODE END IWDG_Init 2 */
  305. }
  306.  
  307. /**
  308.  * @brief SPI1 Initialization Function
  309.  * @param None
  310.  * @retval None
  311.  */
  312. static void MX_SPI1_Init(void)
  313. {
  314.  
  315.   /* USER CODE BEGIN SPI1_Init 0 */
  316.  
  317.   /* USER CODE END SPI1_Init 0 */
  318.  
  319.   /* USER CODE BEGIN SPI1_Init 1 */
  320.  
  321.   /* USER CODE END SPI1_Init 1 */
  322.   /* SPI1 parameter configuration*/
  323.   hspi1.Instance = SPI1;
  324.   hspi1.Init.Mode = SPI_MODE_MASTER;
  325.   hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  326.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  327.   hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  328.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  329.   hspi1.Init.NSS = SPI_NSS_SOFT;
  330.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  331.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  332.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  333.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  334.   hspi1.Init.CRCPolynomial = 10;
  335.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  336.   {
  337.     Error_Handler();
  338.   }
  339.   /* USER CODE BEGIN SPI1_Init 2 */
  340.  
  341.   /* USER CODE END SPI1_Init 2 */
  342. }
  343.  
  344. /**
  345.  * @brief USART1 Initialization Function
  346.  * @param None
  347.  * @retval None
  348.  */
  349. static void MX_USART1_UART_Init(void)
  350. {
  351.  
  352.   /* USER CODE BEGIN USART1_Init 0 */
  353.  
  354.   /* USER CODE END USART1_Init 0 */
  355.  
  356.   /* USER CODE BEGIN USART1_Init 1 */
  357.  
  358.   /* USER CODE END USART1_Init 1 */
  359.   huart1.Instance = USART1;
  360.   huart1.Init.BaudRate = 115200;
  361.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
  362.   huart1.Init.StopBits = UART_STOPBITS_1;
  363.   huart1.Init.Parity = UART_PARITY_NONE;
  364.   huart1.Init.Mode = UART_MODE_TX_RX;
  365.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  366.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  367.   if (HAL_UART_Init(&huart1) != HAL_OK)
  368.   {
  369.     Error_Handler();
  370.   }
  371.   /* USER CODE BEGIN USART1_Init 2 */
  372.  
  373.   /* USER CODE END USART1_Init 2 */
  374. }
  375.  
  376. /**
  377.  * @brief USART2 Initialization Function
  378.  * @param None
  379.  * @retval None
  380.  */
  381. static void MX_USART2_UART_Init(void)
  382. {
  383.  
  384.   /* USER CODE BEGIN USART2_Init 0 */
  385.  
  386.   /* USER CODE END USART2_Init 0 */
  387.  
  388.   /* USER CODE BEGIN USART2_Init 1 */
  389.  
  390.   /* USER CODE END USART2_Init 1 */
  391.   huart2.Instance = USART2;
  392.   huart2.Init.BaudRate = 19200;
  393.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  394.   huart2.Init.StopBits = UART_STOPBITS_1;
  395.   huart2.Init.Parity = UART_PARITY_NONE;
  396.   huart2.Init.Mode = UART_MODE_TX_RX;
  397.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  398.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  399.   if (HAL_UART_Init(&huart2) != HAL_OK)
  400.   {
  401.     Error_Handler();
  402.   }
  403.   /* USER CODE BEGIN USART2_Init 2 */
  404.  
  405.   /* USER CODE END USART2_Init 2 */
  406. }
  407.  
  408. /**
  409.  * @brief GPIO Initialization Function
  410.  * @param None
  411.  * @retval None
  412.  */
  413. static void MX_GPIO_Init(void)
  414. {
  415.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  416.   /* USER CODE BEGIN MX_GPIO_Init_1 */
  417.   /* USER CODE END MX_GPIO_Init_1 */
  418.  
  419.   /* GPIO Ports Clock Enable */
  420.   __HAL_RCC_GPIOC_CLK_ENABLE();
  421.   __HAL_RCC_GPIOD_CLK_ENABLE();
  422.   __HAL_RCC_GPIOA_CLK_ENABLE();
  423.   __HAL_RCC_GPIOB_CLK_ENABLE();
  424.  
  425.   /*Configure GPIO pin Output Level */
  426.   HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
  427.  
  428.   /*Configure GPIO pin Output Level */
  429.   HAL_GPIO_WritePin(GPIOA, GREEN_LED_Pin | YELLOW_LED_Pin | SPI_CD_Pin | SPI_NSS_Pin, GPIO_PIN_RESET);
  430.  
  431.   /*Configure GPIO pin Output Level */
  432.   HAL_GPIO_WritePin(SPI_RESET_GPIO_Port, SPI_RESET_Pin, GPIO_PIN_RESET);
  433.  
  434.   /*Configure GPIO pin Output Level */
  435.   HAL_GPIO_WritePin(enableAFRN_GPIO_Port, enableAFRN_Pin, GPIO_PIN_SET);
  436.  
  437.   /*Configure GPIO pin : LED_Pin */
  438.   GPIO_InitStruct.Pin = LED_Pin;
  439.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  440.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  441.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  442.   HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);
  443.  
  444.   /*Configure GPIO pins : GREEN_LED_Pin YELLOW_LED_Pin SPI_CD_Pin SPI_NSS_Pin */
  445.   GPIO_InitStruct.Pin = GREEN_LED_Pin | YELLOW_LED_Pin | SPI_CD_Pin | SPI_NSS_Pin;
  446.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  447.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  448.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  449.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  450.  
  451.   /*Configure GPIO pin : SPI_RESET_Pin */
  452.   GPIO_InitStruct.Pin = SPI_RESET_Pin;
  453.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  454.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  455.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  456.   HAL_GPIO_Init(SPI_RESET_GPIO_Port, &GPIO_InitStruct);
  457.  
  458.   /*Configure GPIO pin : enableAFRN_Pin */
  459.   GPIO_InitStruct.Pin = enableAFRN_Pin;
  460.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  461.   GPIO_InitStruct.Pull = GPIO_NOPULL;
  462.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  463.   HAL_GPIO_Init(enableAFRN_GPIO_Port, &GPIO_InitStruct);
  464.  
  465.   /* USER CODE BEGIN MX_GPIO_Init_2 */
  466.   /* USER CODE END MX_GPIO_Init_2 */
  467. }
  468.  
  469. /* USER CODE BEGIN 4 */
  470.  
  471. /* USER CODE END 4 */
  472.  
  473. /**
  474.  * @brief  This function is executed in case of error occurrence.
  475.  * @retval None
  476.  */
  477. void Error_Handler(void)
  478. {
  479.   /* USER CODE BEGIN Error_Handler_Debug */
  480.   /* User can add his own implementation to report the HAL error return state */
  481.   __disable_irq();
  482.   while (1)
  483.   {
  484.   }
  485.   /* USER CODE END Error_Handler_Debug */
  486. }
  487.  
  488. #ifdef USE_FULL_ASSERT
  489. /**
  490.  * @brief  Reports the name of the source file and the source line number
  491.  *         where the assert_param error has occurred.
  492.  * @param  file: pointer to the source file name
  493.  * @param  line: assert_param error line source number
  494.  * @retval None
  495.  */
  496. void assert_failed(uint8_t *file, uint32_t line)
  497. {
  498.   /* USER CODE BEGIN 6 */
  499.   /* User can add his own implementation to report the file name and line number,
  500.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  501.   /* USER CODE END 6 */
  502. }
  503. #endif /* USE_FULL_ASSERT */
  504.