Subversion Repositories EngineBay2

Rev

Rev 52 | Rev 54 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
38 mjames 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) 2021 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 */
49 mjames 25
#include <string.h>
38 mjames 26
#include "libSerial/serial.h"
27
#include "libPLX/plx.h"
50 mjames 28
#include "libPLX/commsLib.h"
38 mjames 29
#include "misc.h"
30
 
48 mjames 31
#include "libIgnTiming/rpm.h"
32
 
38 mjames 33
/* USER CODE END Includes */
34
 
35
/* Private typedef -----------------------------------------------------------*/
36
/* USER CODE BEGIN PTD */
37
 
38
/* USER CODE END PTD */
39
 
40
/* Private define ------------------------------------------------------------*/
41
/* USER CODE BEGIN PD */
42
/* USER CODE END PD */
43
 
44
/* Private macro -------------------------------------------------------------*/
45
/* USER CODE BEGIN PM */
46
#define ADC_CHANNELS 7
47
 
39 mjames 48
#define ADC_MAP_CHAN 2
49
 
50
#define ADC_PRESSURE_CHAN 3
51
 
52
#define ADC_REF_CHAN 5
53
 
54
#define ADC_TEMP_CHAN 6
55
 
38 mjames 56
// wait for about 1 second to decide whether or not starter is on
57
 
58
#define STARTER_LIMIT 10
59
 
60
/* USER CODE END PM */
61
 
62
/* Private variables ---------------------------------------------------------*/
46 mjames 63
ADC_HandleTypeDef hadc1;
38 mjames 64
DMA_HandleTypeDef hdma_adc1;
65
 
66
CAN_HandleTypeDef hcan;
67
 
53 mjames 68
IWDG_HandleTypeDef hiwdg;
69
 
38 mjames 70
SPI_HandleTypeDef hspi1;
71
 
72
TIM_HandleTypeDef htim2;
73
TIM_HandleTypeDef htim3;
74
TIM_HandleTypeDef htim4;
75
 
76
UART_HandleTypeDef huart1;
77
 
78
/* USER CODE BEGIN PV */
79
 
53 mjames 80
// Storage for USART
81
#define USART_TX_BUFF_SIZE 256
82
#define USART_RX_BUFF_SIZE 256
83
uint8_t usartTxBuff[USART_TX_BUFF_SIZE];
84
uint8_t usartRxBuff[USART_RX_BUFF_SIZE];
85
 
38 mjames 86
// storage for ADC
45 mjames 87
uint16_t ADC_Samples[ADC_CHANNELS] = {[0 ... ADC_CHANNELS - 1] = 0};
38 mjames 88
 
45 mjames 89
uint32_t FILT_Samples[ADC_CHANNELS] = {[0 ... ADC_CHANNELS - 1] = 0}; // filtered ADC samples * Scale
38 mjames 90
 
39 mjames 91
#define NOM_VREF 3.3
92
// initial ADC vref
45 mjames 93
float adc_vref = NOM_VREF;
39 mjames 94
 
95
// internal bandgap voltage reference
45 mjames 96
const float STM32REF = 1.2; // 1.2V typical
39 mjames 97
 
98
// scale factor initially assuming
45 mjames 99
float ADC_Scale = 1 / (Scale * 4096) * NOM_VREF;
39 mjames 100
 
38 mjames 101
unsigned int Coded_RPM = 0;
102
unsigned int Coded_CHT = 0;
103
 
42 mjames 104
uint32_t PowerTempTimer;
38 mjames 105
 
106
uint16_t Starter_Debounce = 0;
107
 
108
/* USER CODE END PV */
109
 
110
/* Private function prototypes -----------------------------------------------*/
111
void SystemClock_Config(void);
112
static void MX_GPIO_Init(void);
113
static void MX_DMA_Init(void);
114
static void MX_ADC1_Init(void);
115
static void MX_CAN_Init(void);
116
static void MX_SPI1_Init(void);
117
static void MX_TIM2_Init(void);
118
static void MX_TIM3_Init(void);
119
static void MX_TIM4_Init(void);
120
static void MX_USART1_UART_Init(void);
53 mjames 121
static void MX_IWDG_Init(void);
38 mjames 122
/* USER CODE BEGIN PFP */
123
 
124
/* USER CODE END PFP */
125
 
126
/* Private user code ---------------------------------------------------------*/
127
/* USER CODE BEGIN 0 */
53 mjames 128
void libPLXcallbackRecievedData(PLX_SensorInfo * data)
129
{
130
  (void )data;
38 mjames 131
 
132
}
133
 
53 mjames 134
 
45 mjames 135
void filter_ADC_samples()
38 mjames 136
{
137
  int i;
138
  for (i = 0; i < ADC_CHANNELS; i++)
45 mjames 139
  {
140
    FILT_Samples[i] += (ADC_Samples[i] * Scale - FILT_Samples[i]) / 2;
141
  }
38 mjames 142
}
143
 
39 mjames 144
/****!
145
 * @brief this reads the reference voltage within the STM32L151
146
 * Powers up reference voltage and temperature sensor, waits 3mS  and takes reading
147
 * Requires that the ADC be powered up
148
 */
149
 
45 mjames 150
void CalibrateADC(void)
39 mjames 151
{
45 mjames 152
  float adc_val = FILT_Samples[ADC_REF_CHAN]; // as set up in device config
39 mjames 153
 
45 mjames 154
  float adc_vref = STM32REF * (4096.0 * Scale) / adc_val; // the estimate for checking
39 mjames 155
 
45 mjames 156
  ADC_Scale = 1 / (Scale * 4096) * adc_vref;
39 mjames 157
}
158
 
49 mjames 159
void ProcessRPM(void)
38 mjames 160
{
48 mjames 161
  static unsigned int Coded_RPM = 0;
162
  int32_t rpm = CalculateRPM();
53 mjames 163
  // suppress the EDIS "heartbeat" 90 RPM
164
  if (rpm >= 100)
48 mjames 165
    Coded_RPM = rpm / 19.55;
46 mjames 166
 
45 mjames 167
  // send the current RPM *calculation
53 mjames 168
 
169
  sendPlxInfo(& uc1, PLX_RPM, Coded_RPM/ Scale);
170
 
171
 
38 mjames 172
}
173
 
174
// this uses a MAX6675 which is a simple 16 bit read
175
// SPI is configured for 8 bits so I can use an OLED display if I need it
176
// must wait > 0.22 seconds between conversion attempts as this is the measurement time
177
//
178
 
179
FunctionalState CHT_Enable = ENABLE;
180
 
181
#define CORR 3
182
 
45 mjames 183
uint16_t Temp_Observations[NUM_SPI_TEMP_SENS] = {[0 ... NUM_SPI_TEMP_SENS - 1] = 0};
38 mjames 184
 
42 mjames 185
/// \param item The array index to send
186
/// \param type the code to use for this observation
49 mjames 187
void ProcessTemp(char item, enum PLX_Observations type)
38 mjames 188
{
42 mjames 189
  if (item > NUM_SPI_TEMP_SENS)
190
    return;
53 mjames 191
 
192
  sendPlxInfo(& uc1, type , Temp_Observations[(int)item]);
193
 
38 mjames 194
}
195
 
42 mjames 196
/// \brief Reset the temperature chip select system
197
void resetTempCS(void)
198
{
45 mjames 199
  HAL_GPIO_WritePin(SPI_CS_D_GPIO_Port, SPI_CS_D_Pin, GPIO_PIN_SET);
200
  HAL_GPIO_WritePin(SPI_CS_Clk_GPIO_Port, SPI_CS_Clk_Pin,
201
                    GPIO_PIN_SET);
42 mjames 202
 
45 mjames 203
  for (int i = 0; i < 8; i++)
204
  {
205
    HAL_GPIO_WritePin(SPI_CS_Clk_GPIO_Port, SPI_CS_Clk_Pin,
206
                      GPIO_PIN_RESET);
207
    HAL_GPIO_WritePin(SPI_CS_Clk_GPIO_Port, SPI_CS_Clk_Pin,
208
                      GPIO_PIN_SET);
209
  }
42 mjames 210
 
45 mjames 211
  // prepare for selecting next pin
212
  HAL_GPIO_WritePin(SPI_CS_D_GPIO_Port, SPI_CS_D_Pin, GPIO_PIN_RESET);
42 mjames 213
}
214
 
215
void nextTempCS(void)
216
{
45 mjames 217
  HAL_GPIO_WritePin(SPI_CS_Clk_GPIO_Port, SPI_CS_Clk_Pin,
218
                    GPIO_PIN_RESET);
219
  HAL_GPIO_WritePin(SPI_CS_Clk_GPIO_Port, SPI_CS_Clk_Pin,
220
                    GPIO_PIN_SET);
221
  HAL_GPIO_WritePin(SPI_CS_D_GPIO_Port, SPI_CS_D_Pin, GPIO_PIN_SET);
42 mjames 222
}
223
 
45 mjames 224
void EnableTempSensors(FunctionalState state)
38 mjames 225
 
226
{
227
  GPIO_InitTypeDef GPIO_InitStruct;
228
 
229
  CHT_Enable = state;
230
 
231
  /* enable SPI in live mode : assume it and its GPIOs are already initialised in SPI mode */
232
  if (state == ENABLE)
45 mjames 233
  {
234
    HAL_GPIO_WritePin(ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_SET);
38 mjames 235
 
45 mjames 236
    resetTempCS();
42 mjames 237
 
45 mjames 238
    /* put the SPI pins back into SPI AF mode */
239
    GPIO_InitStruct.Pin = SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin;
240
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
241
    GPIO_InitStruct.Pull = GPIO_NOPULL;
242
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
243
    HAL_GPIO_Init(SPI1_SCK_GPIO_Port, &GPIO_InitStruct);
244
  }
38 mjames 245
  else
45 mjames 246
  {
247
    /*  Power down the SPI interface taking signals all low */
248
    HAL_GPIO_WritePin(ENA_AUX_5V_GPIO_Port, ENA_AUX_5V_Pin, GPIO_PIN_RESET);
38 mjames 249
 
45 mjames 250
    HAL_GPIO_WritePin(SPI1_SCK_GPIO_Port,
251
                      SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin,
252
                      GPIO_PIN_RESET);
38 mjames 253
 
45 mjames 254
    /* put the SPI pins back into GPIO mode */
255
    GPIO_InitStruct.Pin = SPI1_MOSI_Pin | SPI1_MISO_Pin | SPI1_SCK_Pin;
256
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
257
    GPIO_InitStruct.Pull = GPIO_NOPULL;
258
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
259
    HAL_GPIO_Init(SPI1_SCK_GPIO_Port, &GPIO_InitStruct);
260
  }
38 mjames 261
}
262
 
263
// 1023 is 20.00 volts.
49 mjames 264
/// \param item - used to lookup the index of the local reading
265
void ProcessBatteryVoltage(int item)
38 mjames 266
{
49 mjames 267
  float reading = FILT_Samples[item] * ADC_Scale;
38 mjames 268
  reading = reading * 7.8125; // real voltage
45 mjames 269
  reading = reading * 51.15;  // PLC scaling =  1023/20
38 mjames 270
 
53 mjames 271
  sendPlxInfo(& uc1, PLX_Volts, reading);
272
 
38 mjames 273
}
274
 
49 mjames 275
void ProcessCPUTemperature(void)
38 mjames 276
{
45 mjames 277
  // this is defined in the STM32F103 reference manual . #
39 mjames 278
  // V25 = 1.43 volts
279
  // Avg_slope = 4.3mV /degree C
280
  // temperature = {(V25 - VSENSE) / Avg_Slope} + 25
38 mjames 281
 
282
  /* get the ADC reading corresponding to ADC channel 16 after turning on the ADC */
283
 
39 mjames 284
  float temp_val = FILT_Samples[ADC_TEMP_CHAN] * ADC_Scale;
38 mjames 285
  /* renormalise temperature value to account for different ADC Vref  : normalise to that which we would get for a 3000mV reference */
45 mjames 286
  temp_val = (1.43 - temp_val) / 4.3e-3 + 25;
38 mjames 287
 
45 mjames 288
  int32_t result = temp_val;
38 mjames 289
 
53 mjames 290
  sendPlxInfo(& uc1, PLX_FluidTemp, result);
39 mjames 291
 
38 mjames 292
}
293
 
294
// the MAP sensor is giving us a reading of
295
// 4.6 volts for 1019mB or 2.27 volts at the ADC input (resistive divider by 2.016)
296
// I believe the sensor reads  4.5V at 1000kPa and 0.5V at  0kPa
297
// Calibration is a bit off
298
// Real   Displayed
299
// 989    968
300
// 994.1    986
301
// 992.3  984
302
 
49 mjames 303
void ProcessMAP(void)
38 mjames 304
{
45 mjames 305
  // Using ADC_Samples[3] as the MAP input
39 mjames 306
  float reading = FILT_Samples[ADC_MAP_CHAN] * ADC_Scale;
45 mjames 307
  reading = reading * 2.016; // real voltage
38 mjames 308
  // values computed from slope / intercept of map.ods
45 mjames 309
  // 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
38 mjames 310
  // using a pressure gauge.
53 mjames 311
  reading = (reading) * 150 + 326;
312
 
313
  sendPlxInfo(& uc1, PLX_MAP, reading);
38 mjames 314
 
315
}
316
 
317
// the Oil pressi sensor is giving us a reading of
318
// 4.5 volts for 100 PSI or  2.25 volts at the ADC input (resistive divider by 2.016)
319
// I believe the sensor reads  4.5V at 100PSI and 0.5V at  0PSI
320
// an observation of 1024 is 200PSI, so observation of 512 is 100 PSI.
321
 
49 mjames 322
void ProcessOilPress(void)
38 mjames 323
{
45 mjames 324
  // Using ADC_Samples[2] as the MAP input
39 mjames 325
  float reading = FILT_Samples[ADC_PRESSURE_CHAN] * ADC_Scale;
45 mjames 326
  reading = reading * 2.00;            // real voltage
327
  reading = (reading - 0.5) * 512 / 4; // this is 1023 * 100/200
38 mjames 328
 
53 mjames 329
  sendPlxInfo(& uc1, PLX_FluidPressure, reading);
38 mjames 330
 
331
}
332
 
50 mjames 333
 
334
void libPLXcallbackSendUserData()
335
{
336
  // send the observations
337
  ProcessRPM();
338
  ProcessTemp(0, PLX_X_CHT);
339
  ProcessTemp(1, PLX_X_CHT);
340
  ProcessTemp(2, PLX_AIT);
341
  ProcessTemp(3, PLX_AIT);
342
  ProcessBatteryVoltage(0); // Batt 1
343
  ProcessBatteryVoltage(1); // Batt 2
344
  ProcessCPUTemperature();  //  built in temperature sensor
345
 
346
  ProcessMAP();
347
  ProcessOilPress();
348
 
349
  PutCharSerial(&uc1, PLX_Stop);
350
}
38 mjames 351
/* USER CODE END 0 */
352
 
353
/**
46 mjames 354
 * @brief  The application entry point.
355
 * @retval int
356
 */
38 mjames 357
int main(void)
358
{
359
  /* USER CODE BEGIN 1 */
360
 
361
  /* USER CODE END 1 */
362
 
363
  /* MCU Configuration--------------------------------------------------------*/
364
 
365
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
366
  HAL_Init();
367
 
368
  /* USER CODE BEGIN Init */
369
 
370
  /* USER CODE END Init */
371
 
372
  /* Configure the system clock */
373
  SystemClock_Config();
374
 
375
  /* USER CODE BEGIN SysInit */
376
 
377
  /* USER CODE END SysInit */
378
 
379
  /* Initialize all configured peripherals */
380
  MX_GPIO_Init();
381
  MX_DMA_Init();
382
  MX_ADC1_Init();
383
  MX_CAN_Init();
384
  MX_SPI1_Init();
385
  MX_TIM2_Init();
386
  MX_TIM3_Init();
387
  MX_TIM4_Init();
388
  MX_USART1_UART_Init();
53 mjames 389
  MX_IWDG_Init();
38 mjames 390
  /* USER CODE BEGIN 2 */
45 mjames 391
  HAL_MspInit();
38 mjames 392
 
393
  // Not using HAL USART code
45 mjames 394
  __HAL_RCC_USART1_CLK_ENABLE(); // PLX comms port
38 mjames 395
  /* setup the USART control blocks */
53 mjames 396
  init_usart_ctl(&uc1, &huart1,
397
                 usartTxBuff,
398
                 usartRxBuff,
399
                 USART_TX_BUFF_SIZE,
400
                 USART_RX_BUFF_SIZE);
38 mjames 401
 
45 mjames 402
  EnableSerialRxInterrupt(&uc1);
38 mjames 403
 
45 mjames 404
  HAL_SPI_MspInit(&hspi1);
38 mjames 405
 
45 mjames 406
  HAL_ADC_MspInit(&hadc1);
38 mjames 407
 
45 mjames 408
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_Samples, ADC_CHANNELS);
38 mjames 409
 
45 mjames 410
  HAL_ADC_Start_IT(&hadc1);
38 mjames 411
 
45 mjames 412
  HAL_TIM_Base_MspInit(&htim4);
413
  HAL_TIM_Base_Start_IT(&htim4);
38 mjames 414
 
415
  // initialise all the STMCubeMX stuff
45 mjames 416
  HAL_TIM_Base_MspInit(&htim2);
38 mjames 417
  // Start the counter
45 mjames 418
  HAL_TIM_Base_Start(&htim2);
41 mjames 419
  // Start the input capture and the rising edge interrupt
45 mjames 420
  HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
41 mjames 421
  // Start the input capture and the falling edge interrupt
45 mjames 422
  HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2);
38 mjames 423
 
45 mjames 424
  HAL_TIM_Base_MspInit(&htim3);
38 mjames 425
  __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
45 mjames 426
  uint32_t Ticks = HAL_GetTick() + 100;
38 mjames 427
  int CalCounter = 0;
428
 
45 mjames 429
  PowerTempTimer = HAL_GetTick() + 1000; /* wait 10 seconds before powering up the CHT sensor */
38 mjames 430
 
45 mjames 431
  ResetRxBuffer(&uc1);
49 mjames 432
 
50 mjames 433
  resetPLX();
38 mjames 434
  /* USER CODE END 2 */
435
 
436
  /* Infinite loop */
437
  /* USER CODE BEGIN WHILE */
438
  while (1)
45 mjames 439
  {
38 mjames 440
    /* USER CODE END WHILE */
441
 
442
    /* USER CODE BEGIN 3 */
443
 
45 mjames 444
    if (HAL_GetTick() > Ticks)
445
    {
446
      Ticks += 100;
447
      filter_ADC_samples();
448
      // delay to calibrate ADC
449
      if (CalCounter < 1000)
450
      {
451
        CalCounter += 100;
452
      }
38 mjames 453
 
45 mjames 454
      if (CalCounter == 900)
455
      {
456
        CalibrateADC();
457
      }
458
    }
459
    /* when the starter motor is on then power down the CHT sensors as they seem to fail */
38 mjames 460
 
45 mjames 461
    if (HAL_GPIO_ReadPin(STARTER_ON_GPIO_Port, STARTER_ON_Pin) == GPIO_PIN_RESET)
462
    {
463
      if (Starter_Debounce < STARTER_LIMIT)
464
      {
465
        Starter_Debounce++;
466
      }
467
    }
468
    else
469
    {
470
      if (Starter_Debounce > 0)
471
      {
472
        Starter_Debounce--;
473
      }
474
    }
38 mjames 475
 
45 mjames 476
    if (Starter_Debounce == STARTER_LIMIT)
477
    {
478
      EnableTempSensors(DISABLE);
479
      PowerTempTimer = HAL_GetTick() + 1000;
480
    }
481
    else
482
    /* if the PowerTempTimer is set then wait for it to timeout, then power up CHT */
483
    {
484
      if ((PowerTempTimer > 0) && (HAL_GetTick() > PowerTempTimer))
485
      {
486
        EnableTempSensors(ENABLE);
487
        PowerTempTimer = 0;
488
      }
489
    }
38 mjames 490
 
45 mjames 491
    // check to see if we have any incoming data, copy and append if so, if no data then create our own frames.
38 mjames 492
 
50 mjames 493
    // poll the input data and produce automatic output if the timer expires and no serial input data
52 mjames 494
    libPLXpollData(&uc1);
53 mjames 495
 
496
    HAL_IWDG_Refresh(&hiwdg);
45 mjames 497
  }
38 mjames 498
 
499
  /* USER CODE END 3 */
500
}
501
 
502
/**
46 mjames 503
 * @brief System Clock Configuration
504
 * @retval None
505
 */
38 mjames 506
void SystemClock_Config(void)
507
{
508
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
509
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
510
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
511
 
512
  /** Initializes the RCC Oscillators according to the specified parameters
46 mjames 513
   * in the RCC_OscInitTypeDef structure.
514
   */
53 mjames 515
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_HSE;
38 mjames 516
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
517
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
518
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
53 mjames 519
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
38 mjames 520
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
521
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
522
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
523
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
524
  {
525
    Error_Handler();
526
  }
45 mjames 527
 
38 mjames 528
  /** Initializes the CPU, AHB and APB buses clocks
46 mjames 529
   */
530
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
38 mjames 531
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
532
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
533
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
534
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
535
 
536
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
537
  {
538
    Error_Handler();
539
  }
540
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
541
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
542
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
543
  {
544
    Error_Handler();
545
  }
546
}
547
 
548
/**
46 mjames 549
 * @brief ADC1 Initialization Function
550
 * @param None
551
 * @retval None
552
 */
38 mjames 553
static void MX_ADC1_Init(void)
554
{
555
 
556
  /* USER CODE BEGIN ADC1_Init 0 */
557
 
558
  /* USER CODE END ADC1_Init 0 */
559
 
560
  ADC_ChannelConfTypeDef sConfig = {0};
561
 
562
  /* USER CODE BEGIN ADC1_Init 1 */
563
 
564
  /* USER CODE END ADC1_Init 1 */
45 mjames 565
 
38 mjames 566
  /** Common config
46 mjames 567
   */
38 mjames 568
  hadc1.Instance = ADC1;
569
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
570
  hadc1.Init.ContinuousConvMode = DISABLE;
571
  hadc1.Init.DiscontinuousConvMode = DISABLE;
572
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T3_TRGO;
573
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
574
  hadc1.Init.NbrOfConversion = 7;
575
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
576
  {
577
    Error_Handler();
578
  }
45 mjames 579
 
38 mjames 580
  /** Configure Regular Channel
46 mjames 581
   */
38 mjames 582
  sConfig.Channel = ADC_CHANNEL_0;
583
  sConfig.Rank = ADC_REGULAR_RANK_1;
39 mjames 584
  sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
38 mjames 585
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
586
  {
587
    Error_Handler();
588
  }
45 mjames 589
 
38 mjames 590
  /** Configure Regular Channel
46 mjames 591
   */
38 mjames 592
  sConfig.Channel = ADC_CHANNEL_1;
593
  sConfig.Rank = ADC_REGULAR_RANK_2;
594
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
595
  {
596
    Error_Handler();
597
  }
45 mjames 598
 
38 mjames 599
  /** Configure Regular Channel
46 mjames 600
   */
38 mjames 601
  sConfig.Channel = ADC_CHANNEL_2;
602
  sConfig.Rank = ADC_REGULAR_RANK_3;
603
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
604
  {
605
    Error_Handler();
606
  }
45 mjames 607
 
38 mjames 608
  /** Configure Regular Channel
46 mjames 609
   */
38 mjames 610
  sConfig.Channel = ADC_CHANNEL_3;
611
  sConfig.Rank = ADC_REGULAR_RANK_4;
612
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
613
  {
614
    Error_Handler();
615
  }
45 mjames 616
 
38 mjames 617
  /** Configure Regular Channel
46 mjames 618
   */
39 mjames 619
  sConfig.Channel = ADC_CHANNEL_4;
38 mjames 620
  sConfig.Rank = ADC_REGULAR_RANK_5;
621
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
622
  {
623
    Error_Handler();
624
  }
45 mjames 625
 
38 mjames 626
  /** Configure Regular Channel
46 mjames 627
   */
38 mjames 628
  sConfig.Channel = ADC_CHANNEL_VREFINT;
629
  sConfig.Rank = ADC_REGULAR_RANK_6;
630
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
631
  {
632
    Error_Handler();
633
  }
45 mjames 634
 
38 mjames 635
  /** Configure Regular Channel
46 mjames 636
   */
39 mjames 637
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
38 mjames 638
  sConfig.Rank = ADC_REGULAR_RANK_7;
639
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
640
  {
641
    Error_Handler();
642
  }
643
  /* USER CODE BEGIN ADC1_Init 2 */
644
 
645
  /* USER CODE END ADC1_Init 2 */
646
}
647
 
648
/**
46 mjames 649
 * @brief CAN Initialization Function
650
 * @param None
651
 * @retval None
652
 */
38 mjames 653
static void MX_CAN_Init(void)
654
{
655
 
656
  /* USER CODE BEGIN CAN_Init 0 */
657
 
658
  /* USER CODE END CAN_Init 0 */
659
 
660
  /* USER CODE BEGIN CAN_Init 1 */
661
 
662
  /* USER CODE END CAN_Init 1 */
663
  hcan.Instance = CAN1;
664
  hcan.Init.Prescaler = 16;
665
  hcan.Init.Mode = CAN_MODE_NORMAL;
666
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
667
  hcan.Init.TimeSeg1 = CAN_BS1_1TQ;
668
  hcan.Init.TimeSeg2 = CAN_BS2_1TQ;
669
  hcan.Init.TimeTriggeredMode = DISABLE;
670
  hcan.Init.AutoBusOff = DISABLE;
671
  hcan.Init.AutoWakeUp = DISABLE;
672
  hcan.Init.AutoRetransmission = DISABLE;
673
  hcan.Init.ReceiveFifoLocked = DISABLE;
674
  hcan.Init.TransmitFifoPriority = DISABLE;
675
  if (HAL_CAN_Init(&hcan) != HAL_OK)
676
  {
677
    Error_Handler();
678
  }
679
  /* USER CODE BEGIN CAN_Init 2 */
680
 
681
  /* USER CODE END CAN_Init 2 */
682
}
683
 
684
/**
53 mjames 685
 * @brief IWDG Initialization Function
686
 * @param None
687
 * @retval None
688
 */
689
static void MX_IWDG_Init(void)
690
{
691
 
692
  /* USER CODE BEGIN IWDG_Init 0 */
693
 
694
  /* USER CODE END IWDG_Init 0 */
695
 
696
  /* USER CODE BEGIN IWDG_Init 1 */
697
 
698
  /* USER CODE END IWDG_Init 1 */
699
  hiwdg.Instance = IWDG;
700
  hiwdg.Init.Prescaler = IWDG_PRESCALER_64;
701
  hiwdg.Init.Reload = 4095;
702
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
703
  {
704
    Error_Handler();
705
  }
706
  /* USER CODE BEGIN IWDG_Init 2 */
707
 
708
  /* USER CODE END IWDG_Init 2 */
709
}
710
 
711
/**
46 mjames 712
 * @brief SPI1 Initialization Function
713
 * @param None
714
 * @retval None
715
 */
38 mjames 716
static void MX_SPI1_Init(void)
717
{
718
 
719
  /* USER CODE BEGIN SPI1_Init 0 */
720
 
721
  /* USER CODE END SPI1_Init 0 */
722
 
723
  /* USER CODE BEGIN SPI1_Init 1 */
724
 
725
  /* USER CODE END SPI1_Init 1 */
726
  /* SPI1 parameter configuration*/
727
  hspi1.Instance = SPI1;
728
  hspi1.Init.Mode = SPI_MODE_MASTER;
729
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
730
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
731
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
732
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
733
  hspi1.Init.NSS = SPI_NSS_SOFT;
41 mjames 734
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
38 mjames 735
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
736
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
737
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
738
  hspi1.Init.CRCPolynomial = 10;
739
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
740
  {
741
    Error_Handler();
742
  }
743
  /* USER CODE BEGIN SPI1_Init 2 */
744
 
745
  /* USER CODE END SPI1_Init 2 */
746
}
747
 
748
/**
46 mjames 749
 * @brief TIM2 Initialization Function
750
 * @param None
751
 * @retval None
752
 */
38 mjames 753
static void MX_TIM2_Init(void)
754
{
755
 
756
  /* USER CODE BEGIN TIM2_Init 0 */
757
 
758
  /* USER CODE END TIM2_Init 0 */
759
 
760
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
761
  TIM_MasterConfigTypeDef sMasterConfig = {0};
762
  TIM_IC_InitTypeDef sConfigIC = {0};
763
 
764
  /* USER CODE BEGIN TIM2_Init 1 */
765
 
766
  /* USER CODE END TIM2_Init 1 */
767
  htim2.Instance = TIM2;
41 mjames 768
  htim2.Init.Prescaler = 719;
38 mjames 769
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
770
  htim2.Init.Period = 65535;
771
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
772
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
773
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
774
  {
775
    Error_Handler();
776
  }
777
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
778
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
779
  {
780
    Error_Handler();
781
  }
782
  if (HAL_TIM_IC_Init(&htim2) != HAL_OK)
783
  {
784
    Error_Handler();
785
  }
786
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
787
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
788
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
789
  {
790
    Error_Handler();
791
  }
792
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
793
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
794
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
795
  sConfigIC.ICFilter = 15;
796
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
797
  {
798
    Error_Handler();
799
  }
41 mjames 800
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
801
  sConfigIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
802
  sConfigIC.ICFilter = 0;
803
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)
804
  {
805
    Error_Handler();
806
  }
38 mjames 807
  /* USER CODE BEGIN TIM2_Init 2 */
808
 
809
  /* USER CODE END TIM2_Init 2 */
810
}
811
 
812
/**
46 mjames 813
 * @brief TIM3 Initialization Function
814
 * @param None
815
 * @retval None
816
 */
38 mjames 817
static void MX_TIM3_Init(void)
818
{
819
 
820
  /* USER CODE BEGIN TIM3_Init 0 */
821
 
822
  /* USER CODE END TIM3_Init 0 */
823
 
824
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
825
  TIM_MasterConfigTypeDef sMasterConfig = {0};
826
  TIM_OC_InitTypeDef sConfigOC = {0};
827
 
828
  /* USER CODE BEGIN TIM3_Init 1 */
829
 
830
  /* USER CODE END TIM3_Init 1 */
831
  htim3.Instance = TIM3;
41 mjames 832
  htim3.Init.Prescaler = 719;
38 mjames 833
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
41 mjames 834
  htim3.Init.Period = 199;
38 mjames 835
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
836
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
837
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
838
  {
839
    Error_Handler();
840
  }
841
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
842
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
843
  {
844
    Error_Handler();
845
  }
846
  if (HAL_TIM_OC_Init(&htim3) != HAL_OK)
847
  {
848
    Error_Handler();
849
  }
850
  if (HAL_TIM_OnePulse_Init(&htim3, TIM_OPMODE_SINGLE) != HAL_OK)
851
  {
852
    Error_Handler();
853
  }
854
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;
855
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
856
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
857
  {
858
    Error_Handler();
859
  }
860
  sConfigOC.OCMode = TIM_OCMODE_TIMING;
41 mjames 861
  sConfigOC.Pulse = 198;
38 mjames 862
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
863
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
864
  if (HAL_TIM_OC_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
865
  {
866
    Error_Handler();
867
  }
868
  /* USER CODE BEGIN TIM3_Init 2 */
869
 
870
  /* USER CODE END TIM3_Init 2 */
871
}
872
 
873
/**
46 mjames 874
 * @brief TIM4 Initialization Function
875
 * @param None
876
 * @retval None
877
 */
38 mjames 878
static void MX_TIM4_Init(void)
879
{
880
 
881
  /* USER CODE BEGIN TIM4_Init 0 */
882
 
883
  /* USER CODE END TIM4_Init 0 */
884
 
885
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
886
  TIM_MasterConfigTypeDef sMasterConfig = {0};
887
 
888
  /* USER CODE BEGIN TIM4_Init 1 */
889
 
890
  /* USER CODE END TIM4_Init 1 */
891
  htim4.Instance = TIM4;
41 mjames 892
  htim4.Init.Prescaler = 719;
38 mjames 893
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
894
  htim4.Init.Period = 9999;
895
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
896
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
897
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
898
  {
899
    Error_Handler();
900
  }
901
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
902
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
903
  {
904
    Error_Handler();
905
  }
906
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
907
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
908
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
909
  {
910
    Error_Handler();
911
  }
912
  /* USER CODE BEGIN TIM4_Init 2 */
913
 
914
  /* USER CODE END TIM4_Init 2 */
915
}
916
 
917
/**
46 mjames 918
 * @brief USART1 Initialization Function
919
 * @param None
920
 * @retval None
921
 */
38 mjames 922
static void MX_USART1_UART_Init(void)
923
{
924
 
925
  /* USER CODE BEGIN USART1_Init 0 */
926
 
927
  /* USER CODE END USART1_Init 0 */
928
 
929
  /* USER CODE BEGIN USART1_Init 1 */
930
 
931
  /* USER CODE END USART1_Init 1 */
932
  huart1.Instance = USART1;
933
  huart1.Init.BaudRate = 19200;
934
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
935
  huart1.Init.StopBits = UART_STOPBITS_1;
936
  huart1.Init.Parity = UART_PARITY_NONE;
937
  huart1.Init.Mode = UART_MODE_TX_RX;
938
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
939
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
940
  if (HAL_UART_Init(&huart1) != HAL_OK)
941
  {
942
    Error_Handler();
943
  }
944
  /* USER CODE BEGIN USART1_Init 2 */
945
 
946
  /* USER CODE END USART1_Init 2 */
947
}
948
 
949
/**
46 mjames 950
 * Enable DMA controller clock
951
 */
38 mjames 952
static void MX_DMA_Init(void)
953
{
954
 
955
  /* DMA controller clock enable */
956
  __HAL_RCC_DMA1_CLK_ENABLE();
957
 
958
  /* DMA interrupt init */
959
  /* DMA1_Channel1_IRQn interrupt configuration */
960
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
961
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
962
}
963
 
964
/**
46 mjames 965
 * @brief GPIO Initialization Function
966
 * @param None
967
 * @retval None
968
 */
38 mjames 969
static void MX_GPIO_Init(void)
970
{
971
  GPIO_InitTypeDef GPIO_InitStruct = {0};
53 mjames 972
  /* USER CODE BEGIN MX_GPIO_Init_1 */
973
  /* USER CODE END MX_GPIO_Init_1 */
38 mjames 974
 
975
  /* GPIO Ports Clock Enable */
976
  __HAL_RCC_GPIOC_CLK_ENABLE();
977
  __HAL_RCC_GPIOD_CLK_ENABLE();
978
  __HAL_RCC_GPIOA_CLK_ENABLE();
979
  __HAL_RCC_GPIOB_CLK_ENABLE();
980
 
981
  /*Configure GPIO pin Output Level */
982
  HAL_GPIO_WritePin(LED_Blink_GPIO_Port, LED_Blink_Pin, GPIO_PIN_RESET);
983
 
984
  /*Configure GPIO pin Output Level */
46 mjames 985
  HAL_GPIO_WritePin(GPIOB, SPI_CS_Clk_Pin | SPI_CS_D_Pin | ENA_AUX_5V_Pin, GPIO_PIN_RESET);
38 mjames 986
 
987
  /*Configure GPIO pin : LED_Blink_Pin */
988
  GPIO_InitStruct.Pin = LED_Blink_Pin;
989
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
990
  GPIO_InitStruct.Pull = GPIO_NOPULL;
991
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
992
  HAL_GPIO_Init(LED_Blink_GPIO_Port, &GPIO_InitStruct);
993
 
43 mjames 994
  /*Configure GPIO pins : SPI_CS_Clk_Pin SPI_CS_D_Pin ENA_AUX_5V_Pin */
46 mjames 995
  GPIO_InitStruct.Pin = SPI_CS_Clk_Pin | SPI_CS_D_Pin | ENA_AUX_5V_Pin;
38 mjames 996
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
997
  GPIO_InitStruct.Pull = GPIO_NOPULL;
998
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
999
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
1000
 
1001
  /*Configure GPIO pin : STARTER_ON_Pin */
1002
  GPIO_InitStruct.Pin = STARTER_ON_Pin;
1003
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
1004
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1005
  HAL_GPIO_Init(STARTER_ON_GPIO_Port, &GPIO_InitStruct);
53 mjames 1006
 
1007
  /* USER CODE BEGIN MX_GPIO_Init_2 */
1008
  /* USER CODE END MX_GPIO_Init_2 */
38 mjames 1009
}
1010
 
1011
/* USER CODE BEGIN 4 */
1012
 
1013
/* USER CODE END 4 */
1014
 
1015
/**
46 mjames 1016
 * @brief  This function is executed in case of error occurrence.
1017
 * @retval None
1018
 */
38 mjames 1019
void Error_Handler(void)
1020
{
1021
  /* USER CODE BEGIN Error_Handler_Debug */
45 mjames 1022
  /* User can add his own implementation to report the HAL error return state */
38 mjames 1023
 
1024
  /* USER CODE END Error_Handler_Debug */
1025
}
1026
 
46 mjames 1027
#ifdef USE_FULL_ASSERT
38 mjames 1028
/**
46 mjames 1029
 * @brief  Reports the name of the source file and the source line number
1030
 *         where the assert_param error has occurred.
1031
 * @param  file: pointer to the source file name
1032
 * @param  line: assert_param error line source number
1033
 * @retval None
1034
 */
38 mjames 1035
void assert_failed(uint8_t *file, uint32_t line)
1036
{
1037
  /* USER CODE BEGIN 6 */
1038
  /* User can add his own implementation to report the file name and line number,
1039
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
1040
  /* USER CODE END 6 */
1041
}
1042
#endif /* USE_FULL_ASSERT */