Subversion Repositories DashDisplay

Rev

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

Rev 75 Rev 76
Line 25... Line 25...
25
/* Private includes ----------------------------------------------------------*/
25
/* Private includes ----------------------------------------------------------*/
26
/* USER CODE BEGIN Includes */
26
/* USER CODE BEGIN Includes */
27
 
27
 
28
#include "libPLX/plx.h"
28
#include "libPLX/plx.h"
29
#include "libPLX/displayinfo.h"
29
#include "libPLX/displayinfo.h"
-
 
30
#include "libPLX/commsLib.h"
30
#include "libSerial/serialUtils.H"
31
#include "libSerial/serialUtils.H"
31
 
32
 
32
#include "libSmallPrintf/small_printf.h"
33
#include "libSmallPrintf/small_printf.h"
33
#include "libNMEA/nmea.h"
34
#include "libNMEA/nmea.h"
34
#include "switches.h"
35
#include "switches.h"
Line 99... Line 100...
99
context_t contexts[MAX_DISPLAYS];
100
context_t contexts[MAX_DISPLAYS];
100
 
101
 
101
/// @brief Data storage for readings
102
/// @brief Data storage for readings
102
info_t Info[MAXRDG];
103
info_t Info[MAXRDG];
103
 
104
 
104
/// \brief storage for incoming data
-
 
105
data_t Data;
-
 
106
 
-
 
107
uint32_t Latch_Timer;
105
uint32_t Latch_Timer;
108
 
106
 
109
// location for GPS data
107
// location for GPS data
110
Location loc;
108
Location loc;
111
 
109
 
112
/// @brief Time when the logged data will be sent
110
/// @brief Time when the logged data will be sent
113
uint32_t nextTickReload;
111
uint32_t nextTickReload;
114
 
112
 
-
 
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
 
115
/* USER CODE END PV */
129
/* USER CODE END PV */
116
 
130
 
117
/* Private function prototypes -----------------------------------------------*/
131
/* Private function prototypes -----------------------------------------------*/
118
void SystemClock_Config(void);
132
void SystemClock_Config(void);
119
static void MX_GPIO_Init(void);
133
static void MX_GPIO_Init(void);
Line 135... Line 149...
135
  return cc_display(dial, suppress);
149
  return cc_display(dial, suppress);
136
}
150
}
137
 
151
 
138
/// \note  HC-05 only accepts : 9600,19200,38400,57600,115200,230400,460800 baud
152
/// \note  HC-05 only accepts : 9600,19200,38400,57600,115200,230400,460800 baud
139
/// \brief Setup Bluetooth module
153
/// \brief Setup Bluetooth module
140
void initModule(usart_ctl *ctl, uint32_t baudRate)
154
void initModule(struct usart_ctl *ctl, uint32_t baudRate)
141
{
155
{
142
  char initBuf[60];
156
  char initBuf[60];
143
  // switch to command mode
157
  // switch to command mode
144
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET);
158
  HAL_GPIO_WritePin(BT_RESET_GPIO_Port, BT_RESET_Pin, GPIO_PIN_SET);
145
  HAL_Delay(500);
159
  HAL_Delay(500);
Line 212... Line 226...
212
 
226
 
213
/* USER CODE END PFP */
227
/* USER CODE END PFP */
214
 
228
 
215
/* Private user code ---------------------------------------------------------*/
229
/* Private user code ---------------------------------------------------------*/
216
/* USER CODE BEGIN 0 */
230
/* USER CODE BEGIN 0 */
-
 
231
void libPLXcallbackSendUserData(struct usart_ctl * instance)
-
 
232
{
-
 
233
  (void)instance;
-
 
234
}
-
 
235
 
-
 
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
  }
217
 
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
}
218
/* USER CODE END 0 */
313
/* USER CODE END 0 */
219
 
314
 
220
/**
315
/**
221
 * @brief  The application entry point.
316
 * @brief  The application entry point.
222
 * @retval int
317
 * @retval int
Line 282... Line 377...
282
  /* turn on UART4 IRQ */
377
  /* turn on UART4 IRQ */
283
  HAL_NVIC_SetPriority(UART4_IRQn, 4, 0);
378
  HAL_NVIC_SetPriority(UART4_IRQn, 4, 0);
284
  HAL_NVIC_EnableIRQ(UART4_IRQn);
379
  HAL_NVIC_EnableIRQ(UART4_IRQn);
285
 
380
 
286
  /* setup the USART control blocks */
381
  /* setup the USART control blocks */
287
  init_usart_ctl(&uc1, &huart1);
382
  init_usart_ctl(&uc1, &huart1, uc1_tx_buffer,
-
 
383
                 uc1_rx_buffer,
-
 
384
                 TX_USART_BUFF_SIZ,
-
 
385
                 TX_USART_BUFF_SIZ);
288
  init_usart_ctl(&uc2, &huart2);
386
  init_usart_ctl(&uc2, &huart2, uc2_tx_buffer,
-
 
387
                 uc2_rx_buffer,
-
 
388
                 TX_USART_BUFF_SIZ,
-
 
389
                 TX_USART_BUFF_SIZ);
289
  init_usart_ctl(&uc3, &huart3);
390
  init_usart_ctl(&uc3, &huart3, uc3_tx_buffer,
-
 
391
                 uc3_rx_buffer,
-
 
392
                 TX_USART_BUFF_SIZ,
-
 
393
                 TX_USART_BUFF_SIZ);
290
  init_usart_ctl(&uc4, &huart4);
394
  init_usart_ctl(&uc4, &huart4, uc4_tx_buffer,
-
 
395
                 uc4_rx_buffer,
-
 
396
                 TX_USART_BUFF_SIZ,
-
 
397
                 TX_USART_BUFF_SIZ);
291
 
398
 
292
  EnableSerialRxInterrupt(&uc1);
399
  EnableSerialRxInterrupt(&uc1);
293
  EnableSerialRxInterrupt(&uc2);
400
  EnableSerialRxInterrupt(&uc2);
294
  EnableSerialRxInterrupt(&uc3);
401
  EnableSerialRxInterrupt(&uc3);
295
  EnableSerialRxInterrupt(&uc4);
402
  EnableSerialRxInterrupt(&uc4);
Line 319... Line 426...
319
 
426
 
320
  /// @brief Time when the logged data will be sent
427
  /// @brief Time when the logged data will be sent
321
 
428
 
322
  setRmcCallback(&rmc_callback);
429
  setRmcCallback(&rmc_callback);
323
 
430
 
324
  // data timeout
-
 
325
  uint32_t timeout = 0; //
-
 
326
 
-
 
327
  // used in NMEA style logging
431
  // used in NMEA style logging
328
  uint32_t nextTick = 0; ///< time to send next
432
  uint32_t nextTick = 0; ///< time to send next
329
  nextTickReload = 0;
433
  nextTickReload = 0;
330
  uint32_t offsetTicks = 0; ///< time to print as offset in mS for each loop
434
  uint32_t offsetTicks = 0; ///< time to print as offset in mS for each loop
331
 
435
 
332
  // PLX decoder protocols
-
 
333
  char PLXPacket = 0;
-
 
334
  int PLXPtr = 0;
-
 
335
 
436
 
336
  for (int i = 0; i < MAXRDG; ++i)
437
  for (int i = 0; i < MAXRDG; ++i)
337
  {
438
  {
338
    Info[i] = nullInfo;
439
    Info[i] = nullInfo;
339
  }
440
  }
340
 
441
 
341
  uint32_t resetCounter = 0; // record time at which both reset buttons were first pressed.
442
  uint32_t resetCounter = 0; // record time at which both reset buttons were first pressed.
342
 
443
 
-
 
444
  resetPLX();
343
  /* USER CODE END 2 */
445
  /* USER CODE END 2 */
344
 
446
 
345
  /* Infinite loop */
447
  /* Infinite loop */
346
  /* USER CODE BEGIN WHILE */
448
  /* USER CODE BEGIN WHILE */
347
  while (1)
449
  while (1)
Line 446... Line 548...
446
 
548
 
447
          double cur_rdg = ConveriMFDRaw2Data((enum PLX_Observations)Observation, DisplayInfo[Observation].Units,
549
          double cur_rdg = ConveriMFDRaw2Data((enum PLX_Observations)Observation, DisplayInfo[Observation].Units,
448
                                              average);
550
                                              average);
449
          int cnt;
551
          int cnt;
450
          int intPart;
552
          int intPart;
-
 
553
          // depending on digits after the decimal point,
-
 
554
          // choose how to format data
451
          switch (DisplayInfo[Observation].DP)
555
          switch (DisplayInfo[Observation].DP)
452
          {
556
          {
453
          default:
557
          default:
454
          case 0:
558
          case 0:
455
            cnt = small_sprintf(outbuff,
559
            cnt = small_sprintf(outbuff,
Line 492... Line 596...
492
          sendString(&uc3, outbuff, cnt);
596
          sendString(&uc3, outbuff, cnt);
493
        }
597
        }
494
      }
598
      }
495
    }
599
    }
496
 
600
 
497
    // determine if we are getting any data from the interface
-
 
498
    uint16_t cc = SerialCharsReceived(&uc1);
-
 
499
    int chr;
-
 
500
    if (cc == 0)
601
    // poll data into libPLX
501
    {
-
 
502
      timeout++;
602
    libPLXpollData(&uc1);
503
      if (btConnected() && (timeout % 1000 == 0))
-
 
504
      {
-
 
505
        const char msg[] = "Timeout\r\n";
-
 
506
        sendString(&uc3, msg, sizeof(msg));
-
 
507
      }
-
 
508
 
603
 
509
      if (timeout > 60000)
604
    // determine if we are getting any data from the interface
510
      {
-
 
511
 
605
 
512
        // do turn off screen
606
    dataTimeout++;
-
 
607
    if (btConnected() && (dataTimeout % 1000 == 0))
513
      }
608
    {
514
      // wait for a bit if nothing came in.
609
      const char msg[] = "Timeout\r\n";
515
      HAL_Delay(1);
610
      sendString(&uc3, msg, sizeof(msg));
516
    }
611
    }
517
 
612
 
518
    /// process the observation list
-
 
519
    for (chr = 0; chr < cc; chr++)
613
    if (dataTimeout > 60000)
520
    {
614
    {
521
      char c = GetCharSerial(&uc1);
-
 
522
 
615
 
523
      if (c == PLX_Start) // at any time if the start byte appears, reset the pointers
-
 
524
      {
-
 
525
        PLXPtr = 0; // reset the pointer
-
 
526
        PLXPacket = 1;
-
 
527
        timeout = 0; // Reset the timer
-
 
528
        continue;
-
 
529
      }
-
 
530
      if (c == PLX_Stop)
-
 
531
      {
-
 
532
        if (PLXPacket)
-
 
533
        {
-
 
534
          // we can now decode the selected parameter
-
 
535
          int PLXNewItems = PLXPtr / sizeof(PLX_SensorInfo); // total items in last reading batch
-
 
536
 
-
 
537
          // process items
-
 
538
          for (int dataItem = 0; dataItem < PLXNewItems; ++dataItem)
-
 
539
          {
-
 
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
-
 
542
            enum PLX_Observations observation = ConvPLX(Data.Sensor[dataItem].AddrH,
-
 
543
                                                        Data.Sensor[dataItem].AddrL);
-
 
544
 
-
 
545
            char instance = Data.Sensor[dataItem].Instance;
-
 
546
 
-
 
547
            int16_t data = ConvPLX(Data.Sensor[dataItem].ReadingH,
-
 
548
                                   Data.Sensor[dataItem].ReadingL);
-
 
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
-
 
555
            int currentSlot;
-
 
556
            for (currentSlot = 0; currentSlot < MAXRDG; ++currentSlot)
-
 
557
            {
-
 
558
              if ((Info[currentSlot].observation.Obs == observation) && (Info[currentSlot].observation.Instance == instance))
-
 
559
                break;
-
 
560
            }
-
 
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
 
-
 
565
            if (currentSlot == MAXRDG)
-
 
566
            {
-
 
567
              int k;
-
 
568
              {
-
 
569
                for (k = 0; k < MAXRDG; ++k)
-
 
570
                  if (!isValid(k))
-
 
571
                  {
-
 
572
                    currentSlot = k; // found a spare slot
-
 
573
                    break;
616
      // do turn off screen
574
                  }
-
 
575
              }
-
 
576
              if (k == MAXRDG)
-
 
577
                continue; // abandon this iteration
-
 
578
            }
-
 
579
 
-
 
580
            // give up if we are going to fall off the end of the array
-
 
581
            if (currentSlot >= MAXRDG)
-
 
582
              break;
-
 
583
 
-
 
584
            Info[currentSlot].observation.Obs = observation;
-
 
585
 
-
 
586
            Info[currentSlot].observation.Instance = instance;
-
 
587
            Info[currentSlot].data = data;
-
 
588
            if (data > Info[currentSlot].Max)
-
 
589
            {
-
 
590
              Info[currentSlot].Max = data;
-
 
591
            }
-
 
592
            if (data < Info[currentSlot].Min)
-
 
593
            {
-
 
594
              Info[currentSlot].Min = data;
-
 
595
            }
-
 
596
            // take an average
-
 
597
            Info[currentSlot].sum += data;
-
 
598
            Info[currentSlot].count++;
-
 
599
            // note the last update time
-
 
600
            Info[currentSlot].lastUpdated = HAL_GetTick();
-
 
601
            Info[currentSlot].updated = 1; // it has been updated
-
 
602
          }
-
 
603
          PLXPtr = 0;
-
 
604
          PLXPacket = 0;
-
 
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
-
 
614
        }
-
 
615
      }
-
 
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
    }
617
    }
-
 
618
    // wait for a bit if nothing came in.
-
 
619
    HAL_Delay(1);
-
 
620
  }
627
 
621
 
628
    // handle switch rotation
622
  // handle switch rotation
629
    for (int i = 0; i < MAX_DIALS; ++i)
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)
630
    {
632
    {
631
      int delta = get_dial_diff(i);
-
 
632
      int pos = contexts[i].knobPos;
-
 
633
      if (pos < 0)
-
 
634
        break; // dont process until we have read NVRAM for the first time .
-
 
635
      int start = pos;
-
 
636
      // move in positive direction
-
 
637
      while (delta > 0)
-
 
638
      {
-
 
639
        // skip invalid items, dont count
633
      // skip invalid items, dont count
640
        if (pos < MAXRDG - 1)
634
      if (pos < MAXRDG - 1)
641
          pos++;
635
        pos++;
642
        else
636
      else
643
          pos = 0;
637
        pos = 0;
644
 
638
 
645
        if (isValid(pos))
639
      if (isValid(pos))
646
          delta--; // count a valid item
640
        delta--; // count a valid item
647
 
-
 
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
-
 
657
        if (pos > 0)
-
 
658
          pos--;
-
 
659
        else
-
 
660
          pos = MAXRDG - 1;
-
 
661
 
-
 
662
        if (isValid(pos))
-
 
663
          delta++; // count a valid item
-
 
664
 
641
 
665
        // wrap
642
      // wrap
666
        if (pos == start)
643
      if (pos == start)
667
          break;
644
        break;
668
      }
645
    }
669
 
646
 
-
 
647
    // move in negative direction
-
 
648
    while (delta < 0)
-
 
649
    {
670
      contexts[i].knobPos = pos;
650
      // skip invalid items, dont count
671
      if (pos != start)
651
      if (pos > 0)
-
 
652
        pos--;
-
 
653
      else
-
 
654
        pos = MAXRDG - 1;
-
 
655
 
-
 
656
      if (isValid(pos))
672
        contexts[i].dial_timer = DialTimeout;
657
        delta++; // count a valid item
-
 
658
 
-
 
659
      // wrap
-
 
660
      if (pos == start)
-
 
661
        break;
673
    }
662
    }
674
 
663
 
675
    int suppress = -1;
664
    contexts[i].knobPos = pos;
676
    for (int i = 0; i < MAX_DISPLAYS; ++i)
-
 
677
    { // now to display the information
665
    if (pos != start)
678
      suppress = DisplayCurrent(i, suppress);
666
      contexts[i].dial_timer = DialTimeout;
-
 
667
  }
679
 
668
 
680
      cc_check_nvram(i);
669
  int suppress = -1;
-
 
670
  for (int i = 0; i < MAX_DISPLAYS; ++i)
-
 
671
  { // now to display the information
-
 
672
    suppress = DisplayCurrent(i, suppress);
681
    }
673
 
682
    /* USER CODE END WHILE */
674
    cc_check_nvram(i);
683
  }
675
  }
-
 
676
  /* USER CODE END WHILE */
-
 
677
 
684
  /* USER CODE BEGIN 3 */
678
  /* USER CODE BEGIN 3 */
685
 
679
 
686
  /* USER CODE END 3 */
680
  /* USER CODE END 3 */
687
}
681
}
688
 
682