Subversion Repositories DashDisplay

Rev

Details | Last modification | View Log | RSS feed

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