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 */ |