Subversion Repositories DashDisplay

Rev

Rev 68 | Rev 71 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 68 Rev 70
Line 63... Line 63...
63
/* USER CODE BEGIN PV */
63
/* USER CODE BEGIN PV */
64
/* Private variables ---------------------------------------------------------*/
64
/* Private variables ---------------------------------------------------------*/
65
 
65
 
66
context_t contexts[MAX_DISPLAYS];
66
context_t contexts[MAX_DISPLAYS];
67
 
67
 
68
/* timeout when the ignition is switched off */
68
///@brief  timeout when the ignition is switched off
69
#define IGNITION_OFF_TIMEOUT 30000UL
69
#define IGNITION_OFF_TIMEOUT 30000UL
70
 
70
 
71
// 500mS per logger period.
71
/// @brief 1000mS per logger period, print average per period
72
#define LOGGER_INTERVAL 500UL
72
#define LOGGER_INTERVAL 1000UL
73
 
73
 
74
const int DialTimeout = 100; // about 10 seconds after twiddle, save the dial position.
74
/// @brief  about 10 seconds after twiddle, save the dial position.
75
 
-
 
76
nvram_info_t dial_nvram[MAX_DISPLAYS];
75
const int DialTimeout = 100;
77
 
76
 
-
 
77
/// @brief Data storage for readings
78
info_t Info[MAXRDG];
78
info_t Info[MAXRDG];
79
 
79
 
-
 
80
/// @brief Define a null item
-
 
81
const info_t nullInfo = {.Max = 0,
-
 
82
                         .Min = 0xFFF,
-
 
83
                         .sum = 0,
-
 
84
                         .count = 0,
-
 
85
                         .updated = 0,
-
 
86
                         .lastUpdated = 0,
-
 
87
                         .observation = PLX_MAX_OBS,
-
 
88
                         .instance = PLX_MAX_INST};
-
 
89
 
80
/// \brief storage for incoming data
90
/// \brief storage for incoming data
81
data_t Data;
91
data_t Data;
82
 
92
 
83
int PLXItems;
-
 
84
 
-
 
85
uint32_t Latch_Timer = IGNITION_OFF_TIMEOUT;
93
uint32_t Latch_Timer = IGNITION_OFF_TIMEOUT;
86
 
94
 
87
// location for GPS data
95
// location for GPS data
88
Location loc;
96
Location loc;
89
 
97
 
Line 110... Line 118...
110
  if (contexts[dial].knobPos < 0)
118
  if (contexts[dial].knobPos < 0)
111
    return -1;
119
    return -1;
112
  return cc_display(dial, suppress);
120
  return cc_display(dial, suppress);
113
}
121
}
114
 
122
 
115
/// \note this code doesnt work so it leaves speed as 9600.
123
/// \note  HC-05 only accepts : 9600,19200,38400,57600,115200,230400,460800 baud
116
/// \brief Setup Bluetooth module
124
/// \brief Setup Bluetooth module
117
void initModule(usart_ctl *ctl, uint32_t baudRate)
125
void initModule(usart_ctl *ctl, uint32_t baudRate)
118
{
126
{
119
  char initBuf[30];
127
  char initBuf[30];
120
  // switch to command mode
128
  // switch to command mode
121
  HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin, GPIO_PIN_RESET);
129
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_RESET);
122
  HAL_Delay(500);
130
  HAL_Delay(500);
123
  int initLen = small_sprintf(initBuf, "AT+UART=%lu,1,2\n", baudRate);
-
 
124
  setBaud(ctl, 38400);
131
  setBaud(ctl, 38400);
-
 
132
  int initLen = small_sprintf(initBuf, "AT+UART=%lu,0,0\n", baudRate);
-
 
133
  const char buf[] = "AT+RESET\n";
125
  sendString(ctl, initBuf, initLen);
134
  sendString(ctl, initBuf, initLen);
-
 
135
  HAL_Delay(500);
-
 
136
  initLen = small_sprintf(initBuf, buf);
-
 
137
  sendString(ctl, initBuf, initLen);
-
 
138
 
126
  TxWaitEmpty(ctl);
139
  TxWaitEmpty(ctl);
127
  // switch back to normal comms at new baud rate
-
 
128
 
140
 
-
 
141
  // clear the button press
129
  HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin, GPIO_PIN_SET);
142
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET);
-
 
143
 
-
 
144
  // switch back to normal comms at new baud rate
130
  setBaud(ctl, baudRate);
145
  setBaud(ctl, baudRate);
131
  HAL_Delay(100);
146
  HAL_Delay(100);
132
}
147
}
133
 
148
 
134
// workspace for RMC data read from GPS module.
149
// workspace for RMC data read from GPS module.
Line 146... Line 161...
146
uint8_t btConnected()
161
uint8_t btConnected()
147
{
162
{
148
  return HAL_GPIO_ReadPin(BT_STATE_GPIO_Port, BT_STATE_Pin) == GPIO_PIN_SET;
163
  return HAL_GPIO_ReadPin(BT_STATE_GPIO_Port, BT_STATE_Pin) == GPIO_PIN_SET;
149
}
164
}
150
 
165
 
-
 
166
/// @brief return true if this slot is unused
-
 
167
/// @param ptr pointer to the slot to
-
 
168
uint8_t isUnused(int index)
-
 
169
{
-
 
170
  if (index < 0 || index > MAXRDG)
-
 
171
    return false;
-
 
172
 
-
 
173
  return Info[index].instance == PLX_MAX_INST && Info[index].observation == PLX_MAX_OBS;
-
 
174
}
-
 
175
 
-
 
176
/// @brief Determine if an entry is currently valid
-
 
177
/// @param index the number of the array entry to display
-
 
178
/// @return true if the entry contains data which is fresh
-
 
179
uint8_t isValid(int index)
-
 
180
{
-
 
181
  if (index < 0 || index > MAXRDG)
-
 
182
    return false;
-
 
183
  if (isUnused(index))
-
 
184
    return false;
-
 
185
 
-
 
186
  uint32_t age = HAL_GetTick() - Info[index].lastUpdated;
-
 
187
 
-
 
188
  if (age > 300)
-
 
189
    return false;
-
 
190
 
-
 
191
  return true;
-
 
192
}
-
 
193
 
151
/* USER CODE END PFP */
194
/* USER CODE END PFP */
152
 
195
 
153
/* Private user code ---------------------------------------------------------*/
196
/* Private user code ---------------------------------------------------------*/
154
/* USER CODE BEGIN 0 */
197
/* USER CODE BEGIN 0 */
155
 
198
 
Line 234... Line 277...
234
 
277
 
235
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
278
  HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
236
 
279
 
237
  HAL_TIM_Encoder_Start(&htim9, TIM_CHANNEL_ALL);
280
  HAL_TIM_Encoder_Start(&htim9, TIM_CHANNEL_ALL);
238
 
281
 
239
  initModule(&uc3, 9600);
282
  initModule(&uc3, 38400);
240
 
283
 
241
  // Initialise UART for 4800 baud NMEA
284
  // Initialise UART for 4800 baud NMEA
242
  setBaud(&uc2, 4800);
285
  setBaud(&uc2, 4800);
243
 
286
 
244
  // Initialuse UART4 for 4800 baud NMEA.
287
  // Initialuse UART4 for 4800 baud NMEA.
Line 267... Line 310...
267
 
310
 
268
  uint32_t nextTick = 0;
311
  uint32_t nextTick = 0;
269
  uint8_t log = 0;
312
  uint8_t log = 0;
270
  // PLX decoder protocols
313
  // PLX decoder protocols
271
  char PLXPacket = 0;
314
  char PLXPacket = 0;
-
 
315
 
-
 
316
 
272
  for (i = 0; i < MAXRDG; i++)
317
  for (i = 0; i < MAXRDG; i++)
273
  {
318
  {
274
    Info[i].Max = 0;
-
 
275
    Info[i].Min = 0xFFF;
-
 
276
    Info[i].sum = 0;
-
 
277
    Info[i].count = 0;
319
    Info[i] = nullInfo;
278
    Info[i].updated = 0;
-
 
279
    Info[i].lastUpdated = 0;
-
 
280
  }
320
  }
281
 
321
 
282
  int PLXPtr = 0;
322
  int PLXPtr = 0;
283
  int logCount = 0;
323
  int logCount = 0;
284
 
324
 
-
 
325
  uint32_t resetCounter; // record time at which both reset buttons were first pressed.
-
 
326
 
285
  /* USER CODE END 2 */
327
  /* USER CODE END 2 */
286
 
328
 
287
  /* Infinite loop */
329
  /* Infinite loop */
288
  /* USER CODE BEGIN WHILE */
330
  /* USER CODE BEGIN WHILE */
289
  while (1)
331
  while (1)
Line 307... Line 349...
307
    // Handle the bluetooth pairing / reset function by pressing both buttons.
349
    // Handle the bluetooth pairing / reset function by pressing both buttons.
308
    if ((push_pos[0] == 1) && (push_pos[1] == 1))
350
    if ((push_pos[0] == 1) && (push_pos[1] == 1))
309
    {
351
    {
310
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
352
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
311
                        GPIO_PIN_RESET);
353
                        GPIO_PIN_RESET);
-
 
354
      if (resetCounter == 0)
-
 
355
        resetCounter = HAL_GetTick();
312
    }
356
    }
313
    else
357
    else
314
    {
358
    {
315
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
359
      HAL_GPIO_WritePin(BT_BUTTON_GPIO_Port, BT_BUTTON_Pin,
316
                        GPIO_PIN_SET);
360
                        GPIO_PIN_SET);
-
 
361
 
-
 
362
      if (resetCounter != 0)
-
 
363
      {
-
 
364
        // Held down reset button for 10 seconds, clear NVRAM.
-
 
365
        if ((HAL_GetTick() - resetCounter) > 10000)
-
 
366
        {
-
 
367
          for (i = 0; i < 2; i++)
-
 
368
          {
-
 
369
            dial_pos[i] = 0;            // default to items 0 and 1
-
 
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
      }
317
    }
377
    }
318
 
378
 
319
    // poll GPS Position/time on UART4
379
    // poll GPS Position/time on UART4
320
    (void)updateLocation(&loc, &uc4);
380
    (void)updateLocation(&loc, &uc4);
321
    if (loc.valid == 'V')
381
    if (loc.valid == 'V')
Line 346... Line 406...
346
 
406
 
347
      if (log)
407
      if (log)
348
      {
408
      {
349
        log = 0;
409
        log = 0;
350
        // Send items  to BT if it is in connected state
410
        // Send items  to BT if it is in connected state
351
        for (int i = 0; i < PLXItems; ++i)
411
        for (int i = 0; i <  MAXRDG; ++i)
352
        {
412
        {
-
 
413
          if(!isValid(i))
-
 
414
            continue;
353
          char outbuff[100];
415
          char outbuff[100];
354
 
416
 
355
          int cnt = small_sprintf(outbuff,
417
          int cnt = small_sprintf(outbuff,
356
                                  "$PLLOG,%d,%d,%d,%ld",
418
                                  "$PLLOG,%d,%d,%d,%ld",
357
                                  logCount,
419
                                  logCount,
Line 407... Line 469...
407
      if (c == PLX_Stop)
469
      if (c == PLX_Stop)
408
      {
470
      {
409
        if (PLXPacket)
471
        if (PLXPacket)
410
        {
472
        {
411
          // we can now decode the selected parameter
473
          // we can now decode the selected parameter
412
          PLXItems = PLXPtr / sizeof(PLX_SensorInfo); // total
474
          int PLXNewItems = PLXPtr / sizeof(PLX_SensorInfo); // total items in last reading batch
413
          // saturate the rotary switch position
-
 
414
 
475
 
415
          // process min/max
476
          // process items
416
          for (i = 0; i < PLXItems; i++)
477
          for (i = 0; i < PLXNewItems; i++)
417
          {
478
          {
-
 
479
            // search to see if the item already has a slot in the Info[] array
-
 
480
            // match the observation and instance: if found, update entry
418
            Info[i].observation = ConvPLX(Data.Sensor[i].AddrH,
481
            enum PLX_Observations observation = ConvPLX(Data.Sensor[i].AddrH,
419
                                          Data.Sensor[i].AddrL);
482
                                                        Data.Sensor[i].AddrL);
-
 
483
 
-
 
484
            char instance = Data.Sensor[i].Instance;
-
 
485
 
-
 
486
            // validate the current item, discard out of range
420
 
487
 
421
            Info[i].instance = Data.Sensor[i].Instance;
488
            if ((instance > PLX_MAX_INST) || (observation > PLX_MAX_OBS))
422
            Info[i].data = ConvPLX(Data.Sensor[i].ReadingH,
489
              continue;
-
 
490
 
423
                                   Data.Sensor[i].ReadingL);
491
            // search for the item in the list
-
 
492
            int j;
424
            if (Info[i].data > Info[i].Max)
493
            for (j = 0; j < MAXRDG; ++j)
425
            {
494
            {
-
 
495
              if ((Info[j].observation == observation) && (Info[j].instance == instance))
426
              Info[i].Max = Info[i].data;
496
                break;
427
            }
497
            }
-
 
498
            // fallen off the end of the list of existing items without a match, so j points at next new item
-
 
499
            //
428
            if (Info[i].data < Info[i].Min)
500
            // Find an unused slot
-
 
501
 
-
 
502
            if (j == MAXRDG)
429
            {
503
            {
-
 
504
              int k;
-
 
505
              {
-
 
506
                for (k = 0; k < MAXRDG; ++k)
-
 
507
                  if (!isValid(k))
-
 
508
                  {
-
 
509
                    j = k; // found a spare slot
-
 
510
                    break;
-
 
511
                  }
-
 
512
              }
-
 
513
              if (k == MAXRDG)
-
 
514
                continue; // abandon this iteration
-
 
515
            }
-
 
516
 
-
 
517
            // give up if we are going to fall off the end of the array
-
 
518
            if (j > MAXRDG)
-
 
519
              break;
-
 
520
 
-
 
521
            Info[j].observation = observation;
-
 
522
 
-
 
523
            Info[j].instance = instance;
-
 
524
            Info[j].data = ConvPLX(Data.Sensor[j].ReadingH,
-
 
525
                                   Data.Sensor[j].ReadingL);
-
 
526
            if (Info[j].data > Info[j].Max)
-
 
527
            {
-
 
528
              Info[j].Max = Info[j].data;
-
 
529
            }
-
 
530
            if (Info[j].data < Info[j].Min)
-
 
531
            {
430
              Info[i].Min = Info[i].data;
532
              Info[j].Min = Info[j].data;
431
            }
533
            }
432
            // take an average
534
            // take an average
433
            Info[i].sum += Info[i].data;
535
            Info[j].sum += Info[j].data;
434
            Info[i].count++;
536
            Info[j].count++;
435
            // note the last update time
537
            // note the last update time
436
            Info[i].lastUpdated = HAL_GetTick();
538
            Info[j].lastUpdated = HAL_GetTick();
437
            Info[i].updated = 1; // it has been updated
539
            Info[j].updated = 1; // it has been updated
438
          }
540
          }
439
          PLXPtr = 0;
541
          PLXPtr = 0;
440
          PLXPacket = 0;
542
          PLXPacket = 0;
-
 
543
 
-
 
544
          // scan through and invalidate all old items
-
 
545
          for (int i = 0; i < MAXRDG; ++i)
-
 
546
          {
-
 
547
            if (!isValid(i))
-
 
548
              Info[i] = nullInfo;
-
 
549
          }
-
 
550
 
441
          break; // something to process 
551
          break; // something to process
442
        }
552
        }
443
      }
553
      }
444
      if (c > PLX_Stop) // illegal char, restart reading
554
      if (c > PLX_Stop) // illegal char, restart reading
445
      {
555
      {
446
        PLXPacket = 0;
556
        PLXPacket = 0;
Line 454... Line 564...
454
    }
564
    }
455
    int suppress = -1;
565
    int suppress = -1;
456
    for (i = 0; i < MAX_DISPLAYS; i++)
566
    for (i = 0; i < MAX_DISPLAYS; i++)
457
    { // now to display the information
567
    { // now to display the information
458
      suppress = DisplayCurrent(i, suppress);
568
      suppress = DisplayCurrent(i, suppress);
459
     
-
 
460
 
569
 
461
      if (dial_pos[i] < 0)
570
      if (dial_pos[i] < 0)
462
        dial_pos[i] = PLXItems - 1;
571
        dial_pos[i] = MAXRDG - 1;
463
      if (dial_pos[i] >= PLXItems)
572
      if (dial_pos[i] >= MAXRDG)
464
        dial_pos[i] = 0;
573
        dial_pos[i] = 0;
465
 
574
 
466
      int prevPos = contexts[i].knobPos;
575
      int prevPos = contexts[i].knobPos;
467
      if (contexts[i].knobPos >= 0)
576
      if (contexts[i].knobPos >= 0)
468
        contexts[i].knobPos = dial_pos[i];
577
        contexts[i].knobPos = dial_pos[i];
Line 875... Line 984...
875
  __HAL_RCC_GPIOA_CLK_ENABLE();
984
  __HAL_RCC_GPIOA_CLK_ENABLE();
876
  __HAL_RCC_GPIOC_CLK_ENABLE();
985
  __HAL_RCC_GPIOC_CLK_ENABLE();
877
  __HAL_RCC_GPIOB_CLK_ENABLE();
986
  __HAL_RCC_GPIOB_CLK_ENABLE();
878
 
987
 
879
  /*Configure GPIO pin Output Level */
988
  /*Configure GPIO pin Output Level */
880
  HAL_GPIO_WritePin(SPI_NSS1_GPIO_Port, SPI_NSS1_Pin, GPIO_PIN_SET);
989
  HAL_GPIO_WritePin(GPIOA, SPI_NSS1_Pin | BT_RESET_Pin, GPIO_PIN_SET);
881
 
990
 
882
  /*Configure GPIO pin Output Level */
991
  /*Configure GPIO pin Output Level */
883
  HAL_GPIO_WritePin(GPIOA, SPI_CD_Pin | BT_BUTTON_Pin, GPIO_PIN_RESET);
992
  HAL_GPIO_WritePin(GPIOA, SPI_CD_Pin | BT_BUTTON_Pin, GPIO_PIN_RESET);
884
 
993
 
885
  /*Configure GPIO pin Output Level */
994
  /*Configure GPIO pin Output Level */
Line 912... Line 1021...
912
  GPIO_InitStruct.Pin = IGNITION_Pin;
1021
  GPIO_InitStruct.Pin = IGNITION_Pin;
913
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
1022
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
914
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1023
  GPIO_InitStruct.Pull = GPIO_NOPULL;
915
  HAL_GPIO_Init(IGNITION_GPIO_Port, &GPIO_InitStruct);
1024
  HAL_GPIO_Init(IGNITION_GPIO_Port, &GPIO_InitStruct);
916
 
1025
 
917
  /*Configure GPIO pin : BT_BUTTON_Pin */
1026
  /*Configure GPIO pins : BT_BUTTON_Pin BT_RESET_Pin */
918
  GPIO_InitStruct.Pin = BT_BUTTON_Pin;
1027
  GPIO_InitStruct.Pin = BT_BUTTON_Pin | BT_RESET_Pin;
919
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
1028
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
920
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1029
  GPIO_InitStruct.Pull = GPIO_NOPULL;
921
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
1030
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
922
  HAL_GPIO_Init(BT_BUTTON_GPIO_Port, &GPIO_InitStruct);
1031
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
923
}
1032
}
924
 
1033
 
925
/* USER CODE BEGIN 4 */
1034
/* USER CODE BEGIN 4 */
926
 
1035
 
927
/* USER CODE END 4 */
1036
/* USER CODE END 4 */