Subversion Repositories DashDisplay

Rev

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

Rev 76 Rev 77
Line 18... Line 18...
18
 */
18
 */
19
/* USER CODE END Header */
19
/* USER CODE END Header */
20
/* Includes ------------------------------------------------------------------*/
20
/* Includes ------------------------------------------------------------------*/
21
#include "main.h"
21
#include "main.h"
22
 
22
 
23
#include <stdlib.h>
-
 
24
 
-
 
25
/* Private includes ----------------------------------------------------------*/
23
/* Private includes ----------------------------------------------------------*/
26
/* USER CODE BEGIN Includes */
24
/* USER CODE BEGIN Includes */
-
 
25
#include <math.h>
27
 
26
 
28
#include "libPLX/plx.h"
27
#include "libPLX/plx.h"
29
#include "libPLX/displayinfo.h"
28
#include "libPLX/displayinfo.h"
30
#include "libPLX/commsLib.h"
29
#include "libPLX/commsLib.h"
31
#include "libSerial/serialUtils.H"
30
#include "libSerial/serialUtils.H"
Line 98... Line 97...
98
                         .observation = nullObs};
97
                         .observation = nullObs};
99
 
98
 
100
context_t contexts[MAX_DISPLAYS];
99
context_t contexts[MAX_DISPLAYS];
101
 
100
 
102
/// @brief Data storage for readings
101
/// @brief Data storage for readings
103
info_t Info[MAXRDG];
102
info_t Info[INFO_SIZE];
104
 
103
 
105
uint32_t Latch_Timer;
104
uint32_t Latch_Timer;
106
 
105
 
107
// location for GPS data
106
// location for GPS data
108
Location loc;
107
Location loc;
Line 198... Line 197...
198
 
197
 
199
/// @brief return true if this slot is unused
198
/// @brief return true if this slot is unused
200
/// @param ptr pointer to the slot to
199
/// @param ptr pointer to the slot to
201
uint8_t isUnused(int index)
200
uint8_t isUnused(int index)
202
{
201
{
203
  if (index < 0 || index > MAXRDG)
202
  if (index < 0 || index > PLX_MAX_OBS)
204
    return false;
203
    return false;
205
 
-
 
206
  return Info[index].observation.Instance == PLX_MAX_INST && Info[index].observation.Obs == PLX_MAX_OBS;
204
  return Info[index].observation.Instance == PLX_MAX_INST && Info[index].observation.Obs == PLX_MAX_OBS;
207
}
205
}
208
 
206
 
209
/// @brief Determine if an entry is currently valid
207
/// @brief Determine if an entry is currently valid
210
/// @param index the number of the array entry to display
208
/// @param index the number of the array entry to display
211
/// @return true if the entry contains data which is fresh
209
/// @return true if the entry contains data which is fresh
212
uint8_t isValid(int index)
210
uint8_t isValid(int index)
213
{
211
{
214
  if (index < 0 || index > MAXRDG)
212
  if (index < 0 || index > INFO_SIZE)
215
    return false;
213
    return false;
216
  if (isUnused(index))
214
  if (isUnused(index))
217
    return false;
215
    return false;
218
 
216
 
219
  uint32_t age = HAL_GetTick() - Info[index].lastUpdated;
217
  uint32_t age = HAL_GetTick() - Info[index].lastUpdated;
Line 226... Line 224...
226
 
224
 
227
/* USER CODE END PFP */
225
/* USER CODE END PFP */
228
 
226
 
229
/* Private user code ---------------------------------------------------------*/
227
/* Private user code ---------------------------------------------------------*/
230
/* USER CODE BEGIN 0 */
228
/* USER CODE BEGIN 0 */
-
 
229
 
231
void libPLXcallbackSendUserData(struct usart_ctl * instance)
230
unsigned mapToIndex(unsigned instance, unsigned item)
232
{
231
{
233
  (void)instance;
232
  return  instance  + item * PLX_MAX_INST_LIMIT;
234
}
233
}
235
 
234
 
-
 
235
void libPLXcallbackSendUserData(struct usart_ctl *instance)
-
 
236
{
-
 
237
  (void)instance;
-
 
238
}
236
 
239
 
237
void libPLXcallbackRecievedData(PLX_SensorInfo *info)
240
void libPLXcallbackRecievedData(PLX_SensorInfo *info)
238
{
241
{
239
  // received some data , timeout is reset
242
  // received some data , timeout is reset
240
  dataTimeout = 0;
243
  dataTimeout = 0;
Line 244... Line 247...
244
  enum PLX_Observations observation = ConvPLX(info->AddrH,
247
  enum PLX_Observations observation = ConvPLX(info->AddrH,
245
                                              info->AddrL);
248
                                              info->AddrL);
246
 
249
 
247
  char instance = info->Instance;
250
  char instance = info->Instance;
248
 
251
 
249
  int16_t data = ConvPLX(info->ReadingH,
-
 
250
                         info->ReadingL);
-
 
251
 
-
 
252
  // validate the current item, discard out of range
252
  // validate the current item, discard out of range
253
  if ((instance > PLX_MAX_INST) || (observation > PLX_MAX_OBS))
253
  if ((instance > PLX_MAX_INST_LIMIT) || (observation > PLX_MAX_OBS))
254
    return;
254
    return;
255
 
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
 
256
 
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
257
  unsigned currentSlot = mapToIndex(instance ,observation);
275
          Info[currentSlot] = nullInfo;
-
 
276
          break;
-
 
277
        }
-
 
278
    }
-
 
279
    if (k == MAXRDG)
-
 
280
      return; // abandon this iteration
-
 
281
  }
-
 
282
 
258
 
-
 
259
 
283
  // give up if we are going to fall off the end of the array
260
  int16_t data = ConvPLX(info->ReadingH,
284
  if (currentSlot >= MAXRDG)
261
                         info->ReadingL);
285
    return;
-
 
286
 
262
 
287
  Info[currentSlot].observation.Obs = observation;
263
  Info[currentSlot].observation.Obs = observation;
288
 
264
 
289
  Info[currentSlot].observation.Instance = instance;
265
  Info[currentSlot].observation.Instance = instance;
290
  Info[currentSlot].data = data;
266
  Info[currentSlot].data = data;
Line 300... Line 276...
300
  Info[currentSlot].sum += data;
276
  Info[currentSlot].sum += data;
301
  Info[currentSlot].count++;
277
  Info[currentSlot].count++;
302
  // note the last update time
278
  // note the last update time
303
  Info[currentSlot].lastUpdated = HAL_GetTick();
279
  Info[currentSlot].lastUpdated = HAL_GetTick();
304
  Info[currentSlot].updated = 1; // it has been updated
280
  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
  {
281
 
309
    if (!isValid(i))
-
 
310
      Info[i] = nullInfo;
-
 
311
  }
-
 
312
}
282
}
313
/* USER CODE END 0 */
283
/* USER CODE END 0 */
314
 
284
 
315
/**
285
/**
316
 * @brief  The application entry point.
286
 * @brief  The application entry point.
317
 * @retval int
287
 * @retval int
318
 */
288
 */
319
int main(void)
289
int main(void)
320
{
290
{
-
 
291
 
321
  /* USER CODE BEGIN 1 */
292
  /* USER CODE BEGIN 1 */
322
  __HAL_RCC_SPI1_CLK_ENABLE();
293
  __HAL_RCC_SPI1_CLK_ENABLE();
323
  __HAL_RCC_USART1_CLK_ENABLE(); // PLX main port
294
  __HAL_RCC_USART1_CLK_ENABLE(); // PLX main port
324
  __HAL_RCC_USART2_CLK_ENABLE(); // debug port
295
  __HAL_RCC_USART2_CLK_ENABLE(); // debug port
325
  __HAL_RCC_USART3_CLK_ENABLE(); // Bluetooth port
296
  __HAL_RCC_USART3_CLK_ENABLE(); // Bluetooth port
Line 431... Line 402...
431
  // used in NMEA style logging
402
  // used in NMEA style logging
432
  uint32_t nextTick = 0; ///< time to send next
403
  uint32_t nextTick = 0; ///< time to send next
433
  nextTickReload = 0;
404
  nextTickReload = 0;
434
  uint32_t offsetTicks = 0; ///< time to print as offset in mS for each loop
405
  uint32_t offsetTicks = 0; ///< time to print as offset in mS for each loop
435
 
406
 
436
 
-
 
437
  for (int i = 0; i < MAXRDG; ++i)
407
  for (int i = 0; i < INFO_SIZE; ++i)
438
  {
408
  {
439
    Info[i] = nullInfo;
409
    Info[i] = nullInfo;
440
  }
410
  }
441
 
411
 
442
  uint32_t resetCounter = 0; // record time at which both reset buttons were first pressed.
412
  uint32_t resetCounter = 0; // record time at which both reset buttons were first pressed.
Line 533... Line 503...
533
                loc.tv.tm_hour = 0;
503
                loc.tv.tm_hour = 0;
534
            }
504
            }
535
          }
505
          }
536
        }
506
        }
537
 
507
 
538
        for (int i = 0; i < MAXRDG; ++i)
508
        for (int i = 0; i < INFO_SIZE; ++i)
539
        {
509
        {
540
          if (!isValid(i))
510
          if (!isValid(i))
541
            continue;
511
            continue;
542
          // format output
512
          // format output
543
          // avoid division by zero for items with no sample data this iteration
513
          // avoid division by zero for items with no sample data this iteration
Line 613... Line 583...
613
    if (dataTimeout > 60000)
583
    if (dataTimeout > 60000)
614
    {
584
    {
615
 
585
 
616
      // do turn off screen
586
      // do turn off screen
617
    }
587
    }
618
    // wait for a bit if nothing came in.
-
 
619
    HAL_Delay(1);
-
 
620
  }
-
 
621
 
588
 
622
  // handle switch rotation
589
    // handle switch rotation
623
  for (int i = 0; i < MAX_DIALS; ++i)
590
    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)
-
 
632
    {
591
    {
633
      // skip invalid items, dont count
592
      int delta = get_dial_diff(i);
634
      if (pos < MAXRDG - 1)
593
      int pos = contexts[i].knobPos;
635
        pos++;
594
      if (pos < 0)
636
      else
595
        break; // dont process until we have read NVRAM for the first time .
637
        pos = 0;
596
      int start = pos;
638
 
-
 
639
      if (isValid(pos))
597
      // move in positive direction
640
        delta--; // count a valid item
598
      while (delta > 0)
641
 
-
 
642
      // wrap
599
      {
-
 
600
        // skip invalid items, dont count
643
      if (pos == start)
601
        if (pos < INFO_SIZE - 1)
644
        break;
602
          pos++;
645
    }
603
        else
-
 
604
          pos = 0;
646
 
605
 
647
    // move in negative direction
-
 
648
    while (delta < 0)
-
 
649
    {
-
 
650
      // skip invalid items, dont count
-
 
651
      if (pos > 0)
-
 
652
        pos--;
-
 
653
      else
-
 
654
        pos = MAXRDG - 1;
-
 
655
 
-
 
656
      if (isValid(pos))
606
        if (isValid(pos))
657
        delta++; // count a valid item
607
          delta--; // count a valid item
658
 
-
 
659
      // wrap
-
 
660
      if (pos == start)
-
 
661
        break;
-
 
662
    }
-
 
663
 
608
 
664
    contexts[i].knobPos = pos;
609
        // wrap
665
    if (pos != start)
610
        if (pos == start)
666
      contexts[i].dial_timer = DialTimeout;
611
          break;
667
  }
612
      }
668
 
613
 
-
 
614
      // move in negative direction
669
  int suppress = -1;
615
      while (delta < 0)
-
 
616
      {
670
  for (int i = 0; i < MAX_DISPLAYS; ++i)
617
        // skip invalid items, dont count
671
  { // now to display the information
618
        if (pos > 0)
-
 
619
          pos--;
-
 
620
        else
672
    suppress = DisplayCurrent(i, suppress);
621
          pos = INFO_SIZE - 1;
673
 
622
 
674
    cc_check_nvram(i);
623
        if (isValid(pos))
-
 
624
          delta++; // count a valid item
-
 
625
 
-
 
626
        // wrap
-
 
627
        if (pos == start)
-
 
628
          break;
-
 
629
      }
-
 
630
 
-
 
631
      contexts[i].knobPos = pos;
-
 
632
      if (pos != start)
-
 
633
        contexts[i].dial_timer = DialTimeout;
675
  }
634
    }
-
 
635
 
676
  /* USER CODE END WHILE */
636
    int suppress = -1;
-
 
637
    for (int i = 0; i < MAX_DISPLAYS; ++i)
-
 
638
    { // now to display the information
-
 
639
      suppress = DisplayCurrent(i, suppress);
677
 
640
 
-
 
641
      cc_check_nvram(i);
-
 
642
    }
-
 
643
    HAL_Delay(1);
-
 
644
    /* USER CODE END WHILE */
-
 
645
  }
678
  /* USER CODE BEGIN 3 */
646
  /* USER CODE BEGIN 3 */
679
 
647
 
680
  /* USER CODE END 3 */
648
  /* USER CODE END 3 */
681
}
649
}
682
 
650
 
Line 1065... Line 1033...
1065
 * @retval None
1033
 * @retval None
1066
 */
1034
 */
1067
static void MX_GPIO_Init(void)
1035
static void MX_GPIO_Init(void)
1068
{
1036
{
1069
  GPIO_InitTypeDef GPIO_InitStruct = {0};
1037
  GPIO_InitTypeDef GPIO_InitStruct = {0};
-
 
1038
  /* USER CODE BEGIN MX_GPIO_Init_1 */
-
 
1039
  /* USER CODE END MX_GPIO_Init_1 */
1070
 
1040
 
1071
  /* GPIO Ports Clock Enable */
1041
  /* GPIO Ports Clock Enable */
1072
  __HAL_RCC_GPIOH_CLK_ENABLE();
1042
  __HAL_RCC_GPIOH_CLK_ENABLE();
1073
  __HAL_RCC_GPIOA_CLK_ENABLE();
1043
  __HAL_RCC_GPIOA_CLK_ENABLE();
1074
  __HAL_RCC_GPIOC_CLK_ENABLE();
1044
  __HAL_RCC_GPIOC_CLK_ENABLE();
Line 1123... Line 1093...
1123
  GPIO_InitStruct.Pin = BT_RESET_Pin;
1093
  GPIO_InitStruct.Pin = BT_RESET_Pin;
1124
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
1094
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
1125
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1095
  GPIO_InitStruct.Pull = GPIO_NOPULL;
1126
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1096
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
1127
  HAL_GPIO_Init(BT_RESET_GPIO_Port, &GPIO_InitStruct);
1097
  HAL_GPIO_Init(BT_RESET_GPIO_Port, &GPIO_InitStruct);
-
 
1098
 
-
 
1099
  /* USER CODE BEGIN MX_GPIO_Init_2 */
-
 
1100
  /* USER CODE END MX_GPIO_Init_2 */
1128
}
1101
}
1129
 
1102
 
1130
/* USER CODE BEGIN 4 */
1103
/* USER CODE BEGIN 4 */
1131
 
1104
 
1132
/* USER CODE END 4 */
1105
/* USER CODE END 4 */