Subversion Repositories DashDisplay

Rev

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