Subversion Repositories EngineBay2

Rev

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