Subversion Repositories DashDisplay

Rev

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