Subversion Repositories EngineBay2

Rev

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