Subversion Repositories DashDisplay

Rev

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

Rev Author Line No. Line
50 mjames 1
/* USER CODE BEGIN Header */
2 mjames 2
/**
52 mjames 3
 ******************************************************************************
4
 * @file           : main.c
5
 * @brief          : Main program body
6
 ******************************************************************************
7
 * @attention
8
 *
9
 * <h2><center>&copy; Copyright (c) 2020 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
 */
50 mjames 19
/* USER CODE END Header */
2 mjames 20
/* Includes ------------------------------------------------------------------*/
50 mjames 21
#include "main.h"
2 mjames 22
 
50 mjames 23
/* Private includes ----------------------------------------------------------*/
2 mjames 24
/* USER CODE BEGIN Includes */
50 mjames 25
 
26
#include "libPLX/plx.h"
27
#include "libSerial/serial.H"
28
#include "libSmallPrintf/small_printf.h"
58 mjames 29
#include "libNMEA/nmea.h"
4 mjames 30
#include "switches.h"
65 mjames 31
#include <string.h>
2 mjames 32
 
33
/* USER CODE END Includes */
34
 
50 mjames 35
/* Private typedef -----------------------------------------------------------*/
36
/* USER CODE BEGIN PTD */
37
 
38
/* USER CODE END PTD */
39
 
40
/* Private define ------------------------------------------------------------*/
41
/* USER CODE BEGIN PD */
42
/* USER CODE END PD */
43
 
44
/* Private macro -------------------------------------------------------------*/
45
/* USER CODE BEGIN PM */
46
 
47
/* USER CODE END PM */
48
 
2 mjames 49
/* Private variables ---------------------------------------------------------*/
65 mjames 50
I2C_HandleTypeDef hi2c1;
51
 
62 mjames 52
SPI_HandleTypeDef hspi1;
2 mjames 53
 
50 mjames 54
TIM_HandleTypeDef htim2;
44 mjames 55
TIM_HandleTypeDef htim3;
56
TIM_HandleTypeDef htim9;
57
 
60 mjames 58
UART_HandleTypeDef huart4;
3 mjames 59
UART_HandleTypeDef huart1;
2 mjames 60
UART_HandleTypeDef huart2;
23 mjames 61
UART_HandleTypeDef huart3;
2 mjames 62
 
63
/* USER CODE BEGIN PV */
64
/* Private variables ---------------------------------------------------------*/
65
 
50 mjames 66
context_t contexts[MAX_DISPLAYS];
67
 
70 mjames 68
///@brief  timeout when the ignition is switched off
24 mjames 69
#define IGNITION_OFF_TIMEOUT 30000UL
70
 
70 mjames 71
/// @brief 1000mS per logger period, print average per period
72
#define LOGGER_INTERVAL 1000UL
14 mjames 73
 
70 mjames 74
/// @brief  about 10 seconds after twiddle, save the dial position.
75
const int DialTimeout = 100;
18 mjames 76
 
70 mjames 77
/// @brief Data storage for readings
56 mjames 78
info_t Info[MAXRDG];
79
 
70 mjames 80
/// @brief Define a null item
81
const info_t nullInfo = {.Max = 0,
82
                         .Min = 0xFFF,
83
                         .sum = 0,
84
                         .count = 0,
85
                         .updated = 0,
86
                         .lastUpdated = 0,
87
                         .observation = PLX_MAX_OBS,
88
                         .instance = PLX_MAX_INST};
89
 
56 mjames 90
/// \brief storage for incoming data
50 mjames 91
data_t Data;
56 mjames 92
 
27 mjames 93
uint32_t Latch_Timer = IGNITION_OFF_TIMEOUT;
24 mjames 94
 
58 mjames 95
// location for GPS data
96
Location loc;
97
 
2 mjames 98
/* USER CODE END PV */
99
 
100
/* Private function prototypes -----------------------------------------------*/
58 mjames 101
void SystemClock_Config(void);
102
static void MX_GPIO_Init(void);
103
static void MX_SPI1_Init(void);
104
static void MX_USART1_UART_Init(void);
105
static void MX_USART2_UART_Init(void);
106
static void MX_USART3_UART_Init(void);
107
static void MX_TIM3_Init(void);
108
static void MX_TIM9_Init(void);
109
static void MX_TIM2_Init(void);
60 mjames 110
static void MX_UART4_Init(void);
65 mjames 111
static void MX_I2C1_Init(void);
2 mjames 112
/* USER CODE BEGIN PFP */
113
 
7 mjames 114
// the dial is the switch number we are using.
115
// suppress is the ItemIndex we wish to suppress on this display
60 mjames 116
int DisplayCurrent(int dial, int suppress)
7 mjames 117
{
57 mjames 118
  if (contexts[dial].knobPos < 0)
50 mjames 119
    return -1;
60 mjames 120
  return cc_display(dial, suppress);
50 mjames 121
}
30 mjames 122
 
70 mjames 123
/// \note  HC-05 only accepts : 9600,19200,38400,57600,115200,230400,460800 baud
56 mjames 124
/// \brief Setup Bluetooth module
60 mjames 125
void initModule(usart_ctl *ctl, uint32_t baudRate)
53 mjames 126
{
127
  char initBuf[30];
128
  // switch to command mode
70 mjames 129
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_RESET);
60 mjames 130
  HAL_Delay(500);
131
  setBaud(ctl, 38400);
70 mjames 132
  int initLen = small_sprintf(initBuf, "AT+UART=%lu,0,0\n", baudRate);
133
  const char buf[] = "AT+RESET\n";
60 mjames 134
  sendString(ctl, initBuf, initLen);
70 mjames 135
  HAL_Delay(500);
136
  initLen = small_sprintf(initBuf, buf);
137
  sendString(ctl, initBuf, initLen);
138
 
60 mjames 139
  TxWaitEmpty(ctl);
70 mjames 140
 
141
  // clear the button press
142
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET);
143
 
53 mjames 144
  // switch back to normal comms at new baud rate
60 mjames 145
  setBaud(ctl, baudRate);
146
  HAL_Delay(100);
147
}
53 mjames 148
 
60 mjames 149
// workspace for RMC data read from GPS module.
150
uint8_t rmc_buff[80];
62 mjames 151
volatile uint16_t rmc_length;
60 mjames 152
 
153
uint8_t rmc_callback(uint8_t *data, uint16_t length)
154
{
62 mjames 155
  rmc_length = length < sizeof(rmc_buff) ? length : sizeof(rmc_buff);
60 mjames 156
  memcpy(rmc_buff, data, length);
62 mjames 157
  return 0;
53 mjames 158
}
159
 
63 mjames 160
// check if bluetooth connected
161
uint8_t btConnected()
162
{
65 mjames 163
  return HAL_GPIO_ReadPin(BT_STATE_GPIO_Port, BT_STATE_Pin) == GPIO_PIN_SET;
63 mjames 164
}
165
 
70 mjames 166
/// @brief return true if this slot is unused
167
/// @param ptr pointer to the slot to
168
uint8_t isUnused(int index)
169
{
170
  if (index < 0 || index > MAXRDG)
171
    return false;
172
 
173
  return Info[index].instance == PLX_MAX_INST && Info[index].observation == PLX_MAX_OBS;
174
}
175
 
176
/// @brief Determine if an entry is currently valid
177
/// @param index the number of the array entry to display
178
/// @return true if the entry contains data which is fresh
179
uint8_t isValid(int index)
180
{
181
  if (index < 0 || index > MAXRDG)
182
    return false;
183
  if (isUnused(index))
184
    return false;
185
 
186
  uint32_t age = HAL_GetTick() - Info[index].lastUpdated;
187
 
188
  if (age > 300)
189
    return false;
190
 
191
  return true;
192
}
193
 
50 mjames 194
/* USER CODE END PFP */
14 mjames 195
 
50 mjames 196
/* Private user code ---------------------------------------------------------*/
197
/* USER CODE BEGIN 0 */
14 mjames 198
 
7 mjames 199
/* USER CODE END 0 */
2 mjames 200
 
50 mjames 201
/**
62 mjames 202
 * @brief  The application entry point.
203
 * @retval int
204
 */
58 mjames 205
int main(void)
7 mjames 206
{
16 mjames 207
  /* USER CODE BEGIN 1 */
60 mjames 208
  __HAL_RCC_SPI1_CLK_ENABLE();
209
  __HAL_RCC_USART1_CLK_ENABLE(); // PLX main port
210
  __HAL_RCC_USART2_CLK_ENABLE(); // debug port
211
  __HAL_RCC_USART3_CLK_ENABLE(); // Bluetooth port
61 mjames 212
  __HAL_RCC_UART4_CLK_ENABLE();  // NMEA0183 port
2 mjames 213
 
50 mjames 214
  __HAL_RCC_TIM3_CLK_ENABLE();
2 mjames 215
 
50 mjames 216
  __HAL_RCC_TIM9_CLK_ENABLE();
23 mjames 217
 
16 mjames 218
  /* USER CODE END 1 */
2 mjames 219
 
50 mjames 220
  /* MCU Configuration--------------------------------------------------------*/
6 mjames 221
 
16 mjames 222
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
58 mjames 223
  HAL_Init();
2 mjames 224
 
50 mjames 225
  /* USER CODE BEGIN Init */
226
 
227
  /* USER CODE END Init */
228
 
16 mjames 229
  /* Configure the system clock */
58 mjames 230
  SystemClock_Config();
2 mjames 231
 
50 mjames 232
  /* USER CODE BEGIN SysInit */
59 mjames 233
  // Switch handler called on sysTick interrupt.
60 mjames 234
  InitSwitches();
50 mjames 235
 
236
  /* USER CODE END SysInit */
237
 
16 mjames 238
  /* Initialize all configured peripherals */
58 mjames 239
  MX_GPIO_Init();
240
  MX_SPI1_Init();
241
  MX_USART1_UART_Init();
242
  MX_USART2_UART_Init();
243
  MX_USART3_UART_Init();
244
  MX_TIM3_Init();
245
  MX_TIM9_Init();
246
  MX_TIM2_Init();
60 mjames 247
  MX_UART4_Init();
65 mjames 248
  MX_I2C1_Init();
16 mjames 249
  /* USER CODE BEGIN 2 */
2 mjames 250
 
50 mjames 251
  /* Turn on USART1 IRQ */
60 mjames 252
  HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
253
  HAL_NVIC_EnableIRQ(USART1_IRQn);
4 mjames 254
 
50 mjames 255
  /* Turn on USART2 IRQ  */
60 mjames 256
  HAL_NVIC_SetPriority(USART2_IRQn, 4, 0);
257
  HAL_NVIC_EnableIRQ(USART2_IRQn);
2 mjames 258
 
50 mjames 259
  /* turn on USART3 IRQ */
60 mjames 260
  HAL_NVIC_SetPriority(USART3_IRQn, 4, 0);
261
  HAL_NVIC_EnableIRQ(USART3_IRQn);
4 mjames 262
 
60 mjames 263
  /* turn on UART4 IRQ */
264
  HAL_NVIC_SetPriority(UART4_IRQn, 4, 0);
265
  HAL_NVIC_EnableIRQ(UART4_IRQn);
266
 
50 mjames 267
  /* setup the USART control blocks */
60 mjames 268
  init_usart_ctl(&uc1, &huart1);
269
  init_usart_ctl(&uc2, &huart2);
270
  init_usart_ctl(&uc3, &huart3);
271
  init_usart_ctl(&uc4, &huart4);
23 mjames 272
 
60 mjames 273
  EnableSerialRxInterrupt(&uc1);
274
  EnableSerialRxInterrupt(&uc2);
275
  EnableSerialRxInterrupt(&uc3);
276
  EnableSerialRxInterrupt(&uc4);
23 mjames 277
 
60 mjames 278
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
23 mjames 279
 
60 mjames 280
  HAL_TIM_Encoder_Start(&htim9, TIM_CHANNEL_ALL);
44 mjames 281
 
70 mjames 282
  initModule(&uc3, 38400);
2 mjames 283
 
58 mjames 284
  // Initialise UART for 4800 baud NMEA
60 mjames 285
  setBaud(&uc2, 4800);
58 mjames 286
 
60 mjames 287
  // Initialuse UART4 for 4800 baud NMEA.
288
  setBaud(&uc4, 4800);
23 mjames 289
 
60 mjames 290
  cc_init();
291
 
50 mjames 292
  int i;
293
  for (i = 0; i < 2; i++)
60 mjames 294
  {
65 mjames 295
    contexts[i].knobPos = -1;   // set the knob position
60 mjames 296
  }
7 mjames 297
 
50 mjames 298
  /* reset the display timeout, latch on power from accessories */
299
  Latch_Timer = IGNITION_OFF_TIMEOUT;
60 mjames 300
  HAL_GPIO_WritePin(POWER_LATCH_GPIO_Port, POWER_LATCH_Pin, GPIO_PIN_RESET);
16 mjames 301
 
60 mjames 302
  setRmcCallback(&rmc_callback);
303
 
66 mjames 304
  // data timeout
305
  uint32_t timeout = 0; //
306
 
307
  uint32_t nextTick = 0;
308
  uint8_t log = 0;
309
  // PLX decoder protocols
310
  char PLXPacket = 0;
70 mjames 311
 
66 mjames 312
  for (i = 0; i < MAXRDG; i++)
313
  {
70 mjames 314
    Info[i] = nullInfo;
66 mjames 315
  }
316
 
317
  int PLXPtr = 0;
318
  int logCount = 0;
319
 
71 mjames 320
  uint32_t resetCounter = 0 ; // record time at which both reset buttons were first pressed.
70 mjames 321
 
16 mjames 322
  /* USER CODE END 2 */
7 mjames 323
 
16 mjames 324
  /* Infinite loop */
325
  /* USER CODE BEGIN WHILE */
52 mjames 326
  while (1)
60 mjames 327
  {
328
 
329
    /* while ignition is on, keep resetting power latch timer */
330
    if (HAL_GPIO_ReadPin(IGNITION_GPIO_Port, IGNITION_Pin) == GPIO_PIN_RESET)
52 mjames 331
    {
60 mjames 332
      Latch_Timer = HAL_GetTick() + IGNITION_OFF_TIMEOUT;
333
    }
334
    else
335
    {
336
      /* if the ignition has been off for a while, then turn off power */
337
      if (HAL_GetTick() > Latch_Timer)
338
      {
339
        HAL_GPIO_WritePin(POWER_LATCH_GPIO_Port, POWER_LATCH_Pin,
340
                          GPIO_PIN_RESET);
341
      }
342
    }
7 mjames 343
 
66 mjames 344
    // Handle the bluetooth pairing / reset function by pressing both buttons.
345
    if ((push_pos[0] == 1) && (push_pos[1] == 1))
60 mjames 346
    {
66 mjames 347
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
348
                        GPIO_PIN_RESET);
70 mjames 349
      if (resetCounter == 0)
350
        resetCounter = HAL_GetTick();
60 mjames 351
    }
66 mjames 352
    else
353
    {
354
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
355
                        GPIO_PIN_SET);
70 mjames 356
 
357
      if (resetCounter != 0)
358
      {
359
        // Held down reset button for 10 seconds, clear NVRAM.
360
        if ((HAL_GetTick() - resetCounter) > 10000)
361
        {
362
          for (i = 0; i < 2; i++)
363
          {
364
            contexts[i].knobPos = -1;   // set the knob position
365
            contexts[i].dial_timer = 1; // timeout immediately when decremented
366
          }
367
          erase_nvram();
368
        }
369
        resetCounter = 0;
370
      }
66 mjames 371
    }
58 mjames 372
 
66 mjames 373
    // poll GPS Position/time on UART4
374
    (void)updateLocation(&loc, &uc4);
375
    if (loc.valid == 'V')
376
      memset(loc.time, '-', 6);
60 mjames 377
 
66 mjames 378
    // if permitted, log data from RMC packet
379
    if (btConnected())
60 mjames 380
    {
66 mjames 381
      // Any RMC data, send it, reset the logger timeout
382
      if (rmc_length)
62 mjames 383
      {
66 mjames 384
        sendString(&uc3, (const char *)rmc_buff, rmc_length);
62 mjames 385
        rmc_length = 0;
386
        nextTick = HAL_GetTick() + LOGGER_INTERVAL;
66 mjames 387
        log = 1;      // send out associated data over Bluetooth because triggered by recieving RMC
388
        logCount = 0; // first sample set this second numbered 0
62 mjames 389
      }
65 mjames 390
 
66 mjames 391
      // Timeout for data logging regularly
392
      if (HAL_GetTick() > nextTick)
62 mjames 393
      {
394
        nextTick = HAL_GetTick() + LOGGER_INTERVAL;
66 mjames 395
        logCount++;
396
        if (logCount > (1000 / LOGGER_INTERVAL))
397
          logCount = 0;
62 mjames 398
        log = 1;
399
      }
400
 
66 mjames 401
      if (log)
60 mjames 402
      {
66 mjames 403
        log = 0;
404
        // Send items  to BT if it is in connected state
71 mjames 405
        for (int i = 0; i < MAXRDG; ++i)
66 mjames 406
        {
71 mjames 407
          if (!isValid(i))
408
            continue;
66 mjames 409
          char outbuff[100];
410
 
411
          int cnt = small_sprintf(outbuff,
412
                                  "$PLLOG,%d,%d,%d,%ld",
413
                                  logCount,
414
                                  Info[i].observation,
415
                                  Info[i].instance,
416
                                  Info[i].count == 0 ? 0 : Info[i].sum / Info[i].count);
417
 
418
          // NMEA style checksum
419
          int ck;
420
          int sum = 0;
421
          for (ck = 1; ck < cnt; ck++)
422
            sum += outbuff[ck];
423
          cnt += small_sprintf(outbuff + cnt, "*%02X\n",
424
                               sum & 0xFF);
425
          sendString(&uc3, outbuff, cnt);
426
        }
60 mjames 427
      }
66 mjames 428
    }
429
 
430
    // determine if we are getting any data from the interface
431
    uint16_t cc = SerialCharsReceived(&uc1);
432
    int chr;
433
    if (cc == 0)
434
    {
435
      timeout++;
436
      if (btConnected() && (timeout % 1000 == 0))
60 mjames 437
      {
66 mjames 438
        const char msg[] = "Timeout\r\n";
439
        sendString(&uc3, msg, sizeof(msg));
60 mjames 440
      }
27 mjames 441
 
66 mjames 442
      if (timeout > 60000)
60 mjames 443
      {
27 mjames 444
 
66 mjames 445
        // do turn off screen
60 mjames 446
      }
66 mjames 447
      // wait for a bit if nothing came in.
448
      HAL_Delay(10);
449
    }
62 mjames 450
 
66 mjames 451
    /// process the observation list
452
    for (chr = 0; chr < cc; chr++)
453
    {
68 mjames 454
      char c = GetCharSerial(&uc1);
66 mjames 455
 
456
      if (c == PLX_Start) // at any time if the start byte appears, reset the pointers
60 mjames 457
      {
66 mjames 458
        PLXPtr = 0; // reset the pointer
459
        PLXPacket = 1;
460
        timeout = 0; // Reset the timer
67 mjames 461
        continue;
66 mjames 462
      }
67 mjames 463
      if (c == PLX_Stop)
66 mjames 464
      {
465
        if (PLXPacket)
466
        {
467
          // we can now decode the selected parameter
70 mjames 468
          int PLXNewItems = PLXPtr / sizeof(PLX_SensorInfo); // total items in last reading batch
24 mjames 469
 
70 mjames 470
          // process items
471
          for (i = 0; i < PLXNewItems; i++)
60 mjames 472
          {
70 mjames 473
            // search to see if the item already has a slot in the Info[] array
474
            // match the observation and instance: if found, update entry
475
            enum PLX_Observations observation = ConvPLX(Data.Sensor[i].AddrH,
476
                                                        Data.Sensor[i].AddrL);
7 mjames 477
 
70 mjames 478
            char instance = Data.Sensor[i].Instance;
479
 
480
            // validate the current item, discard out of range
481
 
482
            if ((instance > PLX_MAX_INST) || (observation > PLX_MAX_OBS))
483
              continue;
484
 
485
            // search for the item in the list
486
            int j;
487
            for (j = 0; j < MAXRDG; ++j)
60 mjames 488
            {
70 mjames 489
              if ((Info[j].observation == observation) && (Info[j].instance == instance))
490
                break;
60 mjames 491
            }
70 mjames 492
            // fallen off the end of the list of existing items without a match, so j points at next new item
493
            //
494
            // Find an unused slot
495
 
496
            if (j == MAXRDG)
66 mjames 497
            {
70 mjames 498
              int k;
499
              {
500
                for (k = 0; k < MAXRDG; ++k)
501
                  if (!isValid(k))
502
                  {
503
                    j = k; // found a spare slot
504
                    break;
505
                  }
506
              }
507
              if (k == MAXRDG)
508
                continue; // abandon this iteration
66 mjames 509
            }
70 mjames 510
 
511
            // give up if we are going to fall off the end of the array
512
            if (j > MAXRDG)
513
              break;
514
 
515
            Info[j].observation = observation;
516
 
517
            Info[j].instance = instance;
518
            Info[j].data = ConvPLX(Data.Sensor[j].ReadingH,
519
                                   Data.Sensor[j].ReadingL);
520
            if (Info[j].data > Info[j].Max)
521
            {
522
              Info[j].Max = Info[j].data;
523
            }
524
            if (Info[j].data < Info[j].Min)
525
            {
526
              Info[j].Min = Info[j].data;
527
            }
66 mjames 528
            // take an average
70 mjames 529
            Info[j].sum += Info[j].data;
530
            Info[j].count++;
66 mjames 531
            // note the last update time
70 mjames 532
            Info[j].lastUpdated = HAL_GetTick();
533
            Info[j].updated = 1; // it has been updated
60 mjames 534
          }
535
          PLXPtr = 0;
536
          PLXPacket = 0;
70 mjames 537
 
538
          // scan through and invalidate all old items
539
          for (int i = 0; i < MAXRDG; ++i)
540
          {
541
            if (!isValid(i))
542
              Info[i] = nullInfo;
543
          }
544
 
545
          break; // something to process
60 mjames 546
        }
547
      }
67 mjames 548
      if (c > PLX_Stop) // illegal char, restart reading
549
      {
550
        PLXPacket = 0;
551
        PLXPtr = 0;
552
        continue;
553
      }
554
      if (PLXPacket && PLXPtr < sizeof(Data.Bytes))
555
      {
556
        Data.Bytes[PLXPtr++] = c;
557
      }
558
    }
71 mjames 559
 
560
    // handle switch rotation
561
    for (i = 0; i < MAX_DIALS; ++i)
562
    {
563
      int delta = get_dial_diff(i);
564
      int pos = contexts[i].knobPos;
565
      if(pos < 0)
566
        break; // dont process until we have read NVRAM for the first time . 
567
      int start = pos;
568
      // move in positive direction
569
      while (delta > 0)
570
      {
571
        // skip invalid items, dont count
572
        if(pos<MAXRDG-1)
573
          pos++;
574
        else
575
          pos=0;
576
 
577
        if (isValid(pos))
578
          delta--; // count a valid item 
579
 
580
        // wrap
581
        if (pos == start)
582
          break;
583
      }
584
 
585
      // move in negative direction
586
      while (delta < 0)
587
 
588
      {
589
        // skip invalid items, dont count
590
        if(pos>0)
591
          pos--;
592
        else
593
          pos=MAXRDG-1;
594
 
595
        if (isValid(pos))
596
          delta++; // count a valid item 
597
 
598
        // wrap
599
        if (pos == start)
600
          break;
601
      }
602
 
603
      contexts[i].knobPos = pos;
604
      if (pos != start)
605
        contexts[i].dial_timer = DialTimeout;
606
    }
607
 
67 mjames 608
    int suppress = -1;
609
    for (i = 0; i < MAX_DISPLAYS; i++)
610
    { // now to display the information
611
      suppress = DisplayCurrent(i, suppress);
23 mjames 612
 
67 mjames 613
      cc_check_nvram(i);
60 mjames 614
    }
66 mjames 615
  }
71 mjames 616
}
617
/* USER CODE END WHILE */
52 mjames 618
 
71 mjames 619
/* USER CODE BEGIN 3 */
66 mjames 620
 
71 mjames 621
/* USER CODE END 3 */
67 mjames 622
 
50 mjames 623
/**
62 mjames 624
 * @brief System Clock Configuration
625
 * @retval None
626
 */
58 mjames 627
void SystemClock_Config(void)
5 mjames 628
{
58 mjames 629
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
630
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
2 mjames 631
 
50 mjames 632
  /** Configure the main internal regulator output voltage
62 mjames 633
   */
29 mjames 634
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
61 mjames 635
 
50 mjames 636
  /** Initializes the RCC Oscillators according to the specified parameters
62 mjames 637
   * in the RCC_OscInitTypeDef structure.
638
   */
44 mjames 639
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
59 mjames 640
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
16 mjames 641
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
44 mjames 642
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
643
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
29 mjames 644
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV3;
58 mjames 645
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
646
  {
647
    Error_Handler();
648
  }
61 mjames 649
 
50 mjames 650
  /** Initializes the CPU, AHB and APB buses clocks
62 mjames 651
   */
652
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
16 mjames 653
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
654
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
29 mjames 655
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
16 mjames 656
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
50 mjames 657
 
58 mjames 658
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
659
  {
660
    Error_Handler();
661
  }
2 mjames 662
}
663
 
50 mjames 664
/**
65 mjames 665
 * @brief I2C1 Initialization Function
666
 * @param None
667
 * @retval None
668
 */
669
static void MX_I2C1_Init(void)
670
{
671
 
672
  /* USER CODE BEGIN I2C1_Init 0 */
673
 
674
  /* USER CODE END I2C1_Init 0 */
675
 
676
  /* USER CODE BEGIN I2C1_Init 1 */
677
 
678
  /* USER CODE END I2C1_Init 1 */
679
  hi2c1.Instance = I2C1;
680
  hi2c1.Init.ClockSpeed = 100000;
681
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
682
  hi2c1.Init.OwnAddress1 = 0;
683
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
684
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
685
  hi2c1.Init.OwnAddress2 = 0;
686
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
687
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
688
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
689
  {
690
    Error_Handler();
691
  }
692
  /* USER CODE BEGIN I2C1_Init 2 */
693
 
694
  /* USER CODE END I2C1_Init 2 */
695
}
696
 
697
/**
62 mjames 698
 * @brief SPI1 Initialization Function
699
 * @param None
700
 * @retval None
701
 */
58 mjames 702
static void MX_SPI1_Init(void)
5 mjames 703
{
2 mjames 704
 
50 mjames 705
  /* USER CODE BEGIN SPI1_Init 0 */
706
 
707
  /* USER CODE END SPI1_Init 0 */
708
 
709
  /* USER CODE BEGIN SPI1_Init 1 */
710
 
711
  /* USER CODE END SPI1_Init 1 */
712
  /* SPI1 parameter configuration*/
16 mjames 713
  hspi1.Instance = SPI1;
714
  hspi1.Init.Mode = SPI_MODE_MASTER;
715
  hspi1.Init.Direction = SPI_DIRECTION_1LINE;
716
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
717
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
718
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
719
  hspi1.Init.NSS = SPI_NSS_SOFT;
50 mjames 720
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
16 mjames 721
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
722
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
723
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
724
  hspi1.Init.CRCPolynomial = 10;
58 mjames 725
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
726
  {
727
    Error_Handler();
728
  }
50 mjames 729
  /* USER CODE BEGIN SPI1_Init 2 */
2 mjames 730
 
50 mjames 731
  /* USER CODE END SPI1_Init 2 */
2 mjames 732
}
733
 
50 mjames 734
/**
62 mjames 735
 * @brief TIM2 Initialization Function
736
 * @param None
737
 * @retval None
738
 */
58 mjames 739
static void MX_TIM2_Init(void)
50 mjames 740
{
741
 
742
  /* USER CODE BEGIN TIM2_Init 0 */
743
 
744
  /* USER CODE END TIM2_Init 0 */
745
 
58 mjames 746
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
747
  TIM_MasterConfigTypeDef sMasterConfig = {0};
50 mjames 748
 
749
  /* USER CODE BEGIN TIM2_Init 1 */
750
 
751
  /* USER CODE END TIM2_Init 1 */
752
  htim2.Instance = TIM2;
753
  htim2.Init.Prescaler = 0;
754
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
755
  htim2.Init.Period = 65535;
756
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
757
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
58 mjames 758
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
759
  {
760
    Error_Handler();
761
  }
50 mjames 762
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
58 mjames 763
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
764
  {
765
    Error_Handler();
766
  }
50 mjames 767
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
768
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
58 mjames 769
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
770
  {
771
    Error_Handler();
772
  }
50 mjames 773
  /* USER CODE BEGIN TIM2_Init 2 */
774
 
775
  /* USER CODE END TIM2_Init 2 */
776
}
777
 
778
/**
62 mjames 779
 * @brief TIM3 Initialization Function
780
 * @param None
781
 * @retval None
782
 */
58 mjames 783
static void MX_TIM3_Init(void)
44 mjames 784
{
785
 
50 mjames 786
  /* USER CODE BEGIN TIM3_Init 0 */
44 mjames 787
 
50 mjames 788
  /* USER CODE END TIM3_Init 0 */
789
 
58 mjames 790
  TIM_Encoder_InitTypeDef sConfig = {0};
791
  TIM_MasterConfigTypeDef sMasterConfig = {0};
50 mjames 792
 
793
  /* USER CODE BEGIN TIM3_Init 1 */
794
 
795
  /* USER CODE END TIM3_Init 1 */
44 mjames 796
  htim3.Instance = TIM3;
797
  htim3.Init.Prescaler = 0;
798
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
50 mjames 799
  htim3.Init.Period = 65535;
800
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
801
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
44 mjames 802
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
50 mjames 803
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
44 mjames 804
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
805
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
806
  sConfig.IC1Filter = 15;
50 mjames 807
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
44 mjames 808
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
809
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
810
  sConfig.IC2Filter = 15;
58 mjames 811
  if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)
812
  {
813
    Error_Handler();
814
  }
44 mjames 815
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
816
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
58 mjames 817
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
818
  {
819
    Error_Handler();
820
  }
50 mjames 821
  /* USER CODE BEGIN TIM3_Init 2 */
44 mjames 822
 
50 mjames 823
  /* USER CODE END TIM3_Init 2 */
44 mjames 824
}
825
 
50 mjames 826
/**
62 mjames 827
 * @brief TIM9 Initialization Function
828
 * @param None
829
 * @retval None
830
 */
58 mjames 831
static void MX_TIM9_Init(void)
44 mjames 832
{
833
 
50 mjames 834
  /* USER CODE BEGIN TIM9_Init 0 */
44 mjames 835
 
50 mjames 836
  /* USER CODE END TIM9_Init 0 */
837
 
58 mjames 838
  TIM_Encoder_InitTypeDef sConfig = {0};
839
  TIM_MasterConfigTypeDef sMasterConfig = {0};
50 mjames 840
 
841
  /* USER CODE BEGIN TIM9_Init 1 */
842
 
843
  /* USER CODE END TIM9_Init 1 */
44 mjames 844
  htim9.Instance = TIM9;
845
  htim9.Init.Prescaler = 0;
846
  htim9.Init.CounterMode = TIM_COUNTERMODE_UP;
50 mjames 847
  htim9.Init.Period = 65535;
848
  htim9.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
849
  htim9.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
44 mjames 850
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
50 mjames 851
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
44 mjames 852
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
853
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
854
  sConfig.IC1Filter = 15;
50 mjames 855
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
44 mjames 856
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
857
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
50 mjames 858
  sConfig.IC2Filter = 0;
58 mjames 859
  if (HAL_TIM_Encoder_Init(&htim9, &sConfig) != HAL_OK)
860
  {
861
    Error_Handler();
862
  }
44 mjames 863
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
864
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
58 mjames 865
  if (HAL_TIMEx_MasterConfigSynchronization(&htim9, &sMasterConfig) != HAL_OK)
866
  {
867
    Error_Handler();
868
  }
50 mjames 869
  /* USER CODE BEGIN TIM9_Init 2 */
44 mjames 870
 
50 mjames 871
  /* USER CODE END TIM9_Init 2 */
60 mjames 872
}
50 mjames 873
 
60 mjames 874
/**
62 mjames 875
 * @brief UART4 Initialization Function
876
 * @param None
877
 * @retval None
878
 */
60 mjames 879
static void MX_UART4_Init(void)
880
{
881
 
882
  /* USER CODE BEGIN UART4_Init 0 */
883
 
884
  /* USER CODE END UART4_Init 0 */
885
 
886
  /* USER CODE BEGIN UART4_Init 1 */
887
 
888
  /* USER CODE END UART4_Init 1 */
889
  huart4.Instance = UART4;
890
  huart4.Init.BaudRate = 4800;
891
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
892
  huart4.Init.StopBits = UART_STOPBITS_1;
893
  huart4.Init.Parity = UART_PARITY_NONE;
894
  huart4.Init.Mode = UART_MODE_TX_RX;
895
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
896
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
897
  if (HAL_UART_Init(&huart4) != HAL_OK)
898
  {
899
    Error_Handler();
900
  }
901
  /* USER CODE BEGIN UART4_Init 2 */
902
 
903
  /* USER CODE END UART4_Init 2 */
44 mjames 904
}
905
 
50 mjames 906
/**
62 mjames 907
 * @brief USART1 Initialization Function
908
 * @param None
909
 * @retval None
910
 */
58 mjames 911
static void MX_USART1_UART_Init(void)
5 mjames 912
{
3 mjames 913
 
50 mjames 914
  /* USER CODE BEGIN USART1_Init 0 */
915
 
916
  /* USER CODE END USART1_Init 0 */
917
 
918
  /* USER CODE BEGIN USART1_Init 1 */
919
 
920
  /* USER CODE END USART1_Init 1 */
16 mjames 921
  huart1.Instance = USART1;
922
  huart1.Init.BaudRate = 19200;
923
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
44 mjames 924
  huart1.Init.StopBits = UART_STOPBITS_1;
16 mjames 925
  huart1.Init.Parity = UART_PARITY_NONE;
926
  huart1.Init.Mode = UART_MODE_TX_RX;
927
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
928
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
58 mjames 929
  if (HAL_UART_Init(&huart1) != HAL_OK)
930
  {
931
    Error_Handler();
932
  }
50 mjames 933
  /* USER CODE BEGIN USART1_Init 2 */
3 mjames 934
 
50 mjames 935
  /* USER CODE END USART1_Init 2 */
3 mjames 936
}
937
 
50 mjames 938
/**
62 mjames 939
 * @brief USART2 Initialization Function
940
 * @param None
941
 * @retval None
942
 */
58 mjames 943
static void MX_USART2_UART_Init(void)
5 mjames 944
{
2 mjames 945
 
50 mjames 946
  /* USER CODE BEGIN USART2_Init 0 */
947
 
948
  /* USER CODE END USART2_Init 0 */
949
 
950
  /* USER CODE BEGIN USART2_Init 1 */
951
 
952
  /* USER CODE END USART2_Init 1 */
16 mjames 953
  huart2.Instance = USART2;
954
  huart2.Init.BaudRate = 115200;
955
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
956
  huart2.Init.StopBits = UART_STOPBITS_1;
957
  huart2.Init.Parity = UART_PARITY_NONE;
958
  huart2.Init.Mode = UART_MODE_TX_RX;
959
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
960
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
58 mjames 961
  if (HAL_UART_Init(&huart2) != HAL_OK)
962
  {
963
    Error_Handler();
964
  }
50 mjames 965
  /* USER CODE BEGIN USART2_Init 2 */
2 mjames 966
 
50 mjames 967
  /* USER CODE END USART2_Init 2 */
2 mjames 968
}
969
 
50 mjames 970
/**
62 mjames 971
 * @brief USART3 Initialization Function
972
 * @param None
973
 * @retval None
974
 */
58 mjames 975
static void MX_USART3_UART_Init(void)
23 mjames 976
{
977
 
50 mjames 978
  /* USER CODE BEGIN USART3_Init 0 */
979
 
980
  /* USER CODE END USART3_Init 0 */
981
 
982
  /* USER CODE BEGIN USART3_Init 1 */
983
 
984
  /* USER CODE END USART3_Init 1 */
23 mjames 985
  huart3.Instance = USART3;
58 mjames 986
  huart3.Init.BaudRate = 19200;
23 mjames 987
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
50 mjames 988
  huart3.Init.StopBits = UART_STOPBITS_1;
44 mjames 989
  huart3.Init.Parity = UART_PARITY_NONE;
23 mjames 990
  huart3.Init.Mode = UART_MODE_TX_RX;
991
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
992
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
58 mjames 993
  if (HAL_UART_Init(&huart3) != HAL_OK)
994
  {
995
    Error_Handler();
996
  }
50 mjames 997
  /* USER CODE BEGIN USART3_Init 2 */
23 mjames 998
 
50 mjames 999
  /* USER CODE END USART3_Init 2 */
23 mjames 1000
}
1001
 
50 mjames 1002
/**
62 mjames 1003
 * @brief GPIO Initialization Function
1004
 * @param None
1005
 * @retval None
1006
 */
58 mjames 1007
static void MX_GPIO_Init(void)
5 mjames 1008
{
58 mjames 1009
  GPIO_InitTypeDef GPIO_InitStruct = {0};
2 mjames 1010
 
16 mjames 1011
  /* GPIO Ports Clock Enable */
29 mjames 1012
  __HAL_RCC_GPIOH_CLK_ENABLE();
1013
  __HAL_RCC_GPIOA_CLK_ENABLE();
1014
  __HAL_RCC_GPIOC_CLK_ENABLE();
1015
  __HAL_RCC_GPIOB_CLK_ENABLE();
2 mjames 1016
 
16 mjames 1017
  /*Configure GPIO pin Output Level */
70 mjames 1018
  HAL_GPIO_WritePin(GPIOA, SPI_NSS1_Pin | BT_RESET_Pin, GPIO_PIN_SET);
2 mjames 1019
 
16 mjames 1020
  /*Configure GPIO pin Output Level */
62 mjames 1021
  HAL_GPIO_WritePin(GPIOA, SPI_CD_Pin | BT_BUTTON_Pin, GPIO_PIN_RESET);
2 mjames 1022
 
50 mjames 1023
  /*Configure GPIO pin Output Level */
62 mjames 1024
  HAL_GPIO_WritePin(GPIOC, SPI_RESET_Pin | POWER_LATCH_Pin | USB_PWR_Pin, GPIO_PIN_RESET);
50 mjames 1025
 
1026
  /*Configure GPIO pin Output Level */
58 mjames 1027
  HAL_GPIO_WritePin(SPI_NSS2_GPIO_Port, SPI_NSS2_Pin, GPIO_PIN_SET);
50 mjames 1028
 
1029
  /*Configure GPIO pins : SPI_NSS1_Pin SPI_CD_Pin */
62 mjames 1030
  GPIO_InitStruct.Pin = SPI_NSS1_Pin | SPI_CD_Pin;
16 mjames 1031
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
29 mjames 1032
  GPIO_InitStruct.Pull = GPIO_NOPULL;
16 mjames 1033
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
58 mjames 1034
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
2 mjames 1035
 
24 mjames 1036
  /*Configure GPIO pins : SPI_RESET_Pin SPI_NSS2_Pin POWER_LATCH_Pin USB_PWR_Pin */
62 mjames 1037
  GPIO_InitStruct.Pin = SPI_RESET_Pin | SPI_NSS2_Pin | POWER_LATCH_Pin | USB_PWR_Pin;
16 mjames 1038
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
29 mjames 1039
  GPIO_InitStruct.Pull = GPIO_NOPULL;
16 mjames 1040
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
58 mjames 1041
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
2 mjames 1042
 
61 mjames 1043
  /*Configure GPIO pins : BT_STATE_Pin SW1_PUSH_Pin SW2_PUSH_Pin */
62 mjames 1044
  GPIO_InitStruct.Pin = BT_STATE_Pin | SW1_PUSH_Pin | SW2_PUSH_Pin;
16 mjames 1045
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
32 mjames 1046
  GPIO_InitStruct.Pull = GPIO_PULLUP;
58 mjames 1047
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
5 mjames 1048
 
32 mjames 1049
  /*Configure GPIO pin : IGNITION_Pin */
1050
  GPIO_InitStruct.Pin = IGNITION_Pin;
1051
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
1052
  GPIO_InitStruct.Pull = GPIO_NOPULL;
58 mjames 1053
  HAL_GPIO_Init(IGNITION_GPIO_Port, &GPIO_InitStruct);
32 mjames 1054
 
70 mjames 1055
  /*Configure GPIO pins : BT_BUTTON_Pin BT_RESET_Pin */
1056
  GPIO_InitStruct.Pin = BT_BUTTON_Pin | BT_RESET_Pin;
37 mjames 1057
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
1058
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1059
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
70 mjames 1060
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
2 mjames 1061
}
1062
 
1063
/* USER CODE BEGIN 4 */
1064
 
1065
/* USER CODE END 4 */
1066
 
5 mjames 1067
/**
62 mjames 1068
 * @brief  This function is executed in case of error occurrence.
1069
 * @retval None
1070
 */
58 mjames 1071
void Error_Handler(void)
5 mjames 1072
{
50 mjames 1073
  /* USER CODE BEGIN Error_Handler_Debug */
1074
  /* User can add his own implementation to report the HAL error return state */
1075
 
1076
  /* USER CODE END Error_Handler_Debug */
30 mjames 1077
}
5 mjames 1078
 
62 mjames 1079
#ifdef USE_FULL_ASSERT
2 mjames 1080
/**
62 mjames 1081
 * @brief  Reports the name of the source file and the source line number
1082
 *         where the assert_param error has occurred.
1083
 * @param  file: pointer to the source file name
1084
 * @param  line: assert_param error line source number
1085
 * @retval None
1086
 */
50 mjames 1087
void assert_failed(uint8_t *file, uint32_t line)
29 mjames 1088
{
1089
  /* USER CODE BEGIN 6 */
50 mjames 1090
  /* User can add his own implementation to report the file name and line number,
1091
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
29 mjames 1092
  /* USER CODE END 6 */
1093
}
50 mjames 1094
#endif /* USE_FULL_ASSERT */