Subversion Repositories DashDisplay

Rev

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