Subversion Repositories DashDisplay

Rev

Rev 57 | Rev 62 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * display.cpp
  3.  *
  4.  *  Created on: 30 Nov 2020
  5.  *      Author: mike
  6.  */
  7.  
  8. #include "main.h"
  9. #include "display.h"
  10. #include "switches.h"
  11. #include "nvram.h"
  12. #include <cstring>
  13. #include "libOLED/stm32_halDisplay.H"
  14. #include "libOLED/fontclass.H"
  15. #include "libOLED/displayDial.H"
  16. #include "libPlx/displayInfo.H"
  17. #include "libOLED/ap_math.h"
  18.  
  19. #include "splash.H"
  20.  
  21. namespace
  22. {
  23.         int const WIDTH = 128;
  24.         int const HEIGHT = 64;
  25.         int const DISPLAY_RAMWIDTH = 132;
  26. }
  27.  
  28. uint8_t displayBuffer[2][dataSize(WIDTH, HEIGHT)];
  29.  
  30. stm32_halDisplay_t displays[MAX_DISPLAYS] =
  31.         {stm32_halDisplay_t(WIDTH, HEIGHT, DISPLAY_RAMWIDTH, displayBuffer[0],
  32.                                                 &hspi1,
  33.                                                 SPI_CD_GPIO_Port,
  34.                                                 SPI_CD_Pin,
  35.                                                 SPI_RESET_GPIO_Port,
  36.                                                 SPI_RESET_Pin,
  37.                                                 SPI_NSS1_GPIO_Port,
  38.                                                 SPI_NSS1_Pin),
  39.          stm32_halDisplay_t(WIDTH, HEIGHT,
  40.                                                 DISPLAY_RAMWIDTH,
  41.                                                 displayBuffer[1],
  42.                                                 &hspi1,
  43.                                                 SPI_CD_GPIO_Port,
  44.                                                 SPI_CD_Pin,
  45.                                                 SPI_RESET_GPIO_Port,
  46.                                                 SPI_RESET_Pin,
  47.                                                 SPI_NSS2_GPIO_Port,
  48.                                                 SPI_NSS2_Pin)};
  49.  
  50. displayDial_t dials[MAX_DISPLAYS] =
  51.         {displayDial_t(displays[0], 64, 60, 60, 90), displayDial_t(displays[1], 64,
  52.                                                                                                                            60, 60, 90)};
  53. #if defined __cplusplus
  54. extern "C"
  55. {
  56. #endif
  57.         static void
  58.         showMinMax(display_t &display, uint8_t dp_pos, int16_t int_min,
  59.                            uint16_t int_max)
  60.         {
  61.                 display.fontSigDigits(small_font, 0, 0, 0, dp_pos, int_min, WHITE);
  62.                 display.gotoxy(0, 8);
  63.  
  64.                 display.printString(small_font, "Min", 3, WHITE);
  65.  
  66.                 display.fontSigDigits(small_font, 120, 0, 1, dp_pos, int_max, WHITE);
  67.                 display.gotoxy(110, 8);
  68.                 display.printString(small_font, "Max", 3, WHITE);
  69.         }
  70.  
  71.         void
  72.         cc_init()
  73.         {
  74.                 for (auto i = 0; i < MAX_DISPLAYS; i++)
  75.                 {
  76.                         display_t &display = displays[i];
  77.                         if (i == 0)
  78.                                 display.reset();
  79.                         display.init();
  80.                         display.clearDisplay(BLACK);
  81.                         displaySplash(display);
  82.                         display.gotoxy(8, 32);
  83.                         display.printString(large_font, i == 0 ? "1" : "2", 1, BLACK);
  84.                         display.display();
  85.                 }
  86.  
  87.                 HAL_Delay(1000);
  88.  
  89.                 for (auto i = 0; i < MAX_DISPLAYS; i++)
  90.                 {
  91.                         display_t &display = displays[i];
  92.                         display.clearDisplay(BLACK);
  93.                         display.setPixelMode(WHITE);
  94.                         display.display();
  95.                         context_t &context = contexts[i];
  96.                         context.dial_timer = 200; // enough time to see at least one frame of PLX before NVRAM check
  97.                         context.dial1 = -1;
  98.                         context.OldObservation = -1;
  99.                         context.OldObservationIndex = -1;
  100.                 }
  101.         }
  102.  
  103.         // Check to see if there is an observation/instance in the dynamic data array
  104.         // that matches the current observation/instance in the NVRAM
  105.  
  106.         void
  107.         cc_check_nvram(int dialIndex)
  108.         {
  109.                 if (dialIndex < 0 && dialIndex > MAX_DISPLAYS)
  110.                         return;
  111.                 context_t &context = contexts[dialIndex];
  112.  
  113.                 // check for timer timeout on consistent timer
  114.  
  115.                 if (context.dial_timer)
  116.                 {
  117.                         context.dial_timer--;
  118.                         if (context.dial_timer == 0)
  119.                         {
  120.                                 context.dial_timer = DialTimeout;
  121.                                 int i;
  122.                                 if (context.knobPos < 0)
  123.                                 {
  124.                                         for (i = 0; i < PLXItems; i++)
  125.                                                 if (Info[i].observation == dial_nvram[dialIndex].data.observation && Info[i].instance == dial_nvram[dialIndex].data.instance)
  126.                                                 {
  127.                                                         context.knobPos = i;
  128.                                                         return;
  129.                                                 }
  130.                                 }
  131.                                 if (context.knobPos == -1)
  132.                                         context.knobPos = dialIndex; // timed out , not in NVRAM, use a default
  133.  
  134.                                 // is this a change since the last timeout ?
  135.                                 if (Info[context.knobPos].observation != dial_nvram[dialIndex].data.observation || Info[context.knobPos].instance != dial_nvram[dialIndex].data.instance)
  136.                                 {
  137.  
  138.                                         // store the observation and instance in the NVRAM, not dial position.
  139.                                         nvram_info_t curr_val;
  140.                                         curr_val.data.observation = Info[context.knobPos].observation;
  141.                                         curr_val.data.instance = Info[context.knobPos].instance;
  142.                                         uint32_t addr = (uint32_t)(&dial_nvram[dialIndex]);
  143.                                         WriteUint32NVRAM(addr, curr_val.u32);
  144.                                 }
  145.                         }
  146.                 }
  147.         }
  148.  
  149.         int
  150.         cc_display(int dialIndex, int suppressIndex)
  151.  
  152.         {
  153.                 if (dialIndex < 0 && dialIndex > MAX_DISPLAYS)
  154.                         return -1;
  155.                 context_t &context = contexts[dialIndex];
  156.                 displayDial_t &dial = dials[dialIndex];
  157.                 stm32_halDisplay_t &display = displays[dialIndex];
  158.                 int itemIndex = context.knobPos;
  159.                 char buff[10];
  160.                 int i;
  161.  
  162.                 // check for item suppression
  163.                 if (itemIndex == suppressIndex)
  164.                 {
  165.                         context.dial1 = -1;
  166.                         context.OldObservation = -1;
  167.                         context.OldObservationIndex = -1;
  168.  
  169.                         display.clearDisplay();
  170.                         display.display();
  171.                         return -1; // we suppressed this display
  172.                 }
  173.  
  174.                 // clear startup display off the screen
  175.                 if (context.OldObservation == -1)
  176.                         display.clearDisplay(BLACK);
  177.  
  178.                 int DataVal = Info[itemIndex].data; // data reading
  179.                 int Observation = Info[itemIndex].observation;
  180.                 int ObservationIndex = Info[itemIndex].instance;
  181.                 // now to convert the readings and format strings
  182.                 // find out limits
  183.                 char *msg;
  184.                 int len;
  185.  
  186.                 // if the user presses the dial then reset min/max to current value
  187.                 if (push_pos[dialIndex] == 1)
  188.                 {
  189.                         Info[itemIndex].Max = DataVal;
  190.                         Info[itemIndex].Min = DataVal; // 12 bit max value
  191.                 }
  192.  
  193.                 if (Observation < PLX_MAX_OBS)
  194.                 {
  195.                         if (Observation != context.OldObservation || ObservationIndex != context.OldObservationIndex)
  196.                         {
  197.  
  198.                                 display.clearDisplay();
  199.                                 dial.draw_scale(DisplayInfo[Observation].Low,
  200.                                                                 DisplayInfo[Observation].High, 12, 1,
  201.                                                                 DisplayInfo[Observation].TickScale);
  202.  
  203.                                 dial.draw_limits();
  204.  
  205.                                 msg = DisplayInfo[Observation].name;
  206.                                 len = 7;
  207.                                 int len1 = ObservationIndex > 0 ? len - 1 : len;
  208.                                 for (i = 0; i < len1 && msg[i]; i++)
  209.                                 {
  210.                                         buff[i] = msg[i];
  211.                                 }
  212.                                 if (ObservationIndex > 0 && i < len)
  213.                                 {
  214.                                         buff[i++] = ObservationIndex + '1';
  215.                                 }
  216.  
  217.                                 display.gotoxy(64 - i * 4, 48);
  218.                                 display.printString(large_font, buff, i, WHITE);
  219.  
  220.                                 context.OldObservation = Observation;
  221.                                 context.OldObservationIndex = ObservationIndex;
  222.                                 context.dial1 = -1; // do not display old needl, cleared screen
  223.                                 display.display();
  224.                         }
  225.                 }
  226.  
  227.                 double max_rdg;
  228.                 double min_rdg;
  229.                 double cur_rdg;
  230.                 int int_rdg;
  231.                 int int_max;
  232.                 int int_min;
  233.  
  234.                 max_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units,
  235.                                                                          Info[itemIndex].Max);
  236.                 min_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units,
  237.                                                                          Info[itemIndex].Min);
  238.                 cur_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units,
  239.                                                                          Info[itemIndex].data);
  240.  
  241.                 int dp_pos; // where to print the decimal place
  242.                 float scale = 1.0;
  243.                 switch (DisplayInfo[Observation].DP)
  244.                 {
  245.                 default:
  246.                 case 0:
  247.                         scale = 1.0;
  248.                         dp_pos = display_t::NO_DECIMAL;
  249.                         break;
  250.                 case 1:
  251.                         scale = 10.0;
  252.                         dp_pos = 1;
  253.                         break;
  254.                 case 2:
  255.                         scale = 100.0;
  256.                         dp_pos = 2;
  257.                         break;
  258.                 }
  259.                 int_rdg = (int)(cur_rdg * scale);
  260.                 int_max = (int)(max_rdg * scale);
  261.                 int_min = (int)(min_rdg * scale);
  262.  
  263.                 cur_rdg -= DisplayInfo[Observation].Low;
  264.                 cur_rdg = ap_math::SINE_STEPS * cur_rdg / (DisplayInfo[Observation].High - DisplayInfo[Observation].Low);
  265.  
  266.                 context.dial0 = (int)cur_rdg;
  267.  
  268.                 display.gotoxy(32, 28);
  269.                 display.fontDigits(large_font, 4, dp_pos, int_rdg, WHITE);
  270.  
  271.                 display.printString(small_font, DisplayInfo[Observation].suffix,
  272.                                                         strlen(DisplayInfo[Observation].suffix));
  273.                 display.printString(small_font, "    ",
  274.                                                         3 - strlen(DisplayInfo[Observation].suffix));
  275.                 // print value overlaid by needle
  276.  
  277.                 /* old needle un-draw */
  278.                 if (context.dial1 >= 0)
  279.                 {
  280.                         dial.draw_needle(context.dial1);
  281.                 }
  282.                 dial.draw_needle(context.dial0);
  283.                 context.dial1 = context.dial0;
  284.                 showMinMax(display, dp_pos, int_min, int_max);
  285.  
  286.                 display.display();
  287.  
  288.                 return itemIndex;
  289.         }
  290. }
  291.