Subversion Repositories EngineBay2

Rev

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