Subversion Repositories DashDisplay

Rev

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