Subversion Repositories EngineBay2

Rev

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