Subversion Repositories AFRtranscoder

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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"
3 mjames 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);
2 mjames 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
 
3 mjames 52
IWDG_HandleTypeDef hiwdg;
53
 
2 mjames 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);
3 mjames 85
static void MX_IWDG_Init(void);
2 mjames 86
/* USER CODE BEGIN PFP */
87
 
88
// user provided callback symbol
89
void libPLXcallbackSendUserData()
90
{
91
 
3 mjames 92
  HAL_GPIO_TogglePin(YELLOW_LED_GPIO_Port, YELLOW_LED_Pin);
2 mjames 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);
3 mjames 123
 
124
  HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, heaterEnable);
2 mjames 125
}
126
 
3 mjames 127
// refresh watchdog timer
128
void watchdogWrite()
129
{
130
  HAL_IWDG_Refresh(&hiwdg);
131
}
132
 
2 mjames 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 */
3 mjames 147
  //  initialise_monitor_handles();
2 mjames 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();
3 mjames 173
  MX_IWDG_Init();
2 mjames 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();
3 mjames 195
    watchdogWrite();
196
 
197
    HAL_Delay(10);
2 mjames 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
   */
3 mjames 217
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE;
2 mjames 218
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
219
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
220
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
3 mjames 221
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
2 mjames 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
/**
3 mjames 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
/**
2 mjames 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 */
3 mjames 429
  HAL_GPIO_WritePin(GPIOA, GREEN_LED_Pin | YELLOW_LED_Pin | SPI_CD_Pin | SPI_NSS_Pin, GPIO_PIN_RESET);
2 mjames 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 */
3 mjames 435
  HAL_GPIO_WritePin(enableAFRN_GPIO_Port, enableAFRN_Pin, GPIO_PIN_SET);
2 mjames 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
 
3 mjames 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;
2 mjames 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 */