1 /*********************************************************************
  2     FileName:           Screens.c
  3     Dependencies:       See #includes
  4     Processor:          PIC32MZ
  5     Hardware:           MainBrain MZ
  6     Complier:           XC32 4.40
  7     Author:             Larry Knight 2023
  8 /*********************************************************************
  9  
 10     Software License Agreement:
 11  
 12     Licensed under the Apache License, Version 2.0 (the "License");
 13     you may not use this file except in compliance with the License.
 14     You may obtain a copy of the License at
 15 
 16     http://www.apache.org/licenses/LICENSE-2.0
 17 
 18     Unless required by applicable law or agreed to in writing, software
 19     distributed under the License is distributed on an "AS IS" BASIS,
 20     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 21     See the License for the specific language governing permissions and
 22     limitations under the License.
 23  
 24     Description:
 25         System Clock = 200 - 250 MHz
 26 
 27     File Description:
 28 
 29     Change History:
 30  
 31 /***********************************************************************/
 32 
 33 #include <xc.h>
 34 #include <math.h>
 35 #include "MainBrain.h"
 36 
 37 const uint16_t Bitmap_Entrypoint = 120;
 38 
 39 char FPUArray[4] = {"FPU"};
 40 char HeaderString[10] = {"MainBrain"};
 41 char DisplayString[36] = {"480x320 16-bit RGB 65K Touch"};
 42 char MessageBoxTitle[8] = {"Message"};
 43 char ProcessorArray[18] = {"PIC32MZ2048EFH100"};
 44 char SRAMsize[10] = {"8Kx8 SRAM"};
 45 char PeripheralsStr[7] = {"Boards"};
 46 char SRAMStatusPass[5] = {"Pass"};
 47 char failStr[5] = {"Fail"};
 48 char FlashSize[13] = {"512Kx8 Flash"};
 49 char USBver[8] = {"USB 2.0"};
 50 char ExitButtonText[5] = {"Exit"};
 51 char Button1Text[5] = {"Info"};
 52 char Button2Text[8] = {"Draw"};
 53 char MenuText[20] = {"Draw"};
 54 char SRAMFailText[14] = {"SRAM Fail!"};
 55 char SRAMLockedText[14] = {"SRAM Locked!"};
 56 char lastErrorText[9] = {"Errors: "};
 57 char noneStr[5] = {"none"};
 58 char vbusStr[5] = {"VBUS"};
 59 char PrimaryOsc[8] = {"Pri OSC"};
 60 char OtherOsc[6] = {"Other"};
 61 char SequenceStr[15] = {"Sequence Data:"};
 62 char M300Str[] = {"0x300:"};
 63 char M301Str[] = {"0x301:"};
 64 char M302Str[] = {"0x302:"};
 65 char M306Str[] = {"0x306:"};
 66 char M307Str[] = {"0x307:"};
 67 char M308Str[] = {"0x308:"};
 68 char StatusStr[8] = {"Status:"};
 69 char ControlStr[9] = {"Control:"};
 70 char ADCtitleStr[4] = {"ADC"};
 71 char BoardtitleStr[12] = {"Peripherals"};
 72 uint8_t LastError = 0;
 73 int ButtonTopColor = 0xef7d;
 74 int ButtonLowerColor = 0xd6ba;
 75 bool DrawScreenOpen = false;
 76 bool motionScreenActive = false;
 77 
 78 void ShowSplashScreen(uint8_t option)
 79 {
 80     int i;
 81     
 82     //Clear the Screen
 83     Display_CLRSCN(white);
 84         
 85     //Load Splash Image
 86     /****************************/
 87     Display_CASET(0, (Bitmap_width - 1));
 88     Display_RASET(Bitmap_Entrypoint, (Bitmap_Entrypoint + Bitmap_height));
 89     Display_RAMWR();
 90 
 91     //Data
 92     //RF3 = D/C 1=Data, 0=Command
 93     PORTBbits.RB1 = 1;       
 94     
 95     for(i=0;i<=23999; i++)
 96     {
 97         PMDOUT = SplashImage[i];
 98         while(PMMODEbits.BUSY == 1);    
 99     }
100     
101     //This must be here to prevent the Display /CS from remaining low
102     //after the function ends
103     PORTAbits.RA9 = 1;
104 
105     if(option == 1)
106     {
107         LongDelay(2);
108 
109         //Clear the Screen
110         Display_CLRSCN(white);
111 
112         //short delay to let operation complete
113         Delay32(0, 1000);
114     } 
115 }
116 
117 void ShowSRAM_FailScreen(void)
118 {
119 
120 }
121 
122 void ShowDrawScreen(void)
123 {
124     DrawScreenOpen = true;
125     
126     //Clear the Screen
127     Display_CLRSCN(white);
128 
129     //DrawHeader();
130     
131     //draw menu col start 
132     Display_Rect(10, 100, 40, 90, 0xd591);  
133     WriteString(25, 50, MenuText, black, 0xd591);
134     
135     
136 }
137 
138 void DrawHeader()
139 {
140     //Draw Header Bar
141     Display_Rect(0, 480, 0, 40, 0x04D3);  
142 }
143 
144 void DrawMenu(void)
145 {
146     int i;
147     
148     Display_CASET(100, 249);
149     Display_RASET(80, 229);
150     Display_RAMWR();
151 
152     //Data
153     //RF3 = D/C 1=Data, 0=Command
154     PORTBbits.RB1 = 1;       
155 
156     for(i=0;i<=22500; i++)
157     {
158         PMDOUT = DisplayMenu[i];
159         while(PMMODEbits.BUSY == 1);    
160     }
161 
162     WriteChar(192, 120, '5', black, white);
163     
164     //This must be here to prevent the Display /CS from remaining low
165     //after the function ends
166     PORTAbits.RA9 = 1;
167                     
168 }
169 
170 void DrawCanvas(uint8_t screen_, uint32_t begin_xpos, uint32_t begin_ypos, uint32_t _count)
171 {
172     uint32_t i;
173     uint32_t array_begin;
174     uint32_t array_count;
175     
176     //CONFIG_SCREEN
177     if(screen_ == CONFIG_SCREEN)    
178     {        
179         //calculate the start position in the array
180         array_begin = (((begin_ypos + 1) * 480) - (480 - (begin_xpos + 1))) - 1;
181         
182         //set the frame size to full screen
183         Display_CASET(0, 479);
184         Display_RASET(0, 319);
185         
186         //Enable display memory write
187         //Data will be written until another command is received by the display
188         Display_RAMWR();
189 
190         //Set Display Data Mode
191         //RF3 = D/C 1=Data, 0=Command
192         PORTBbits.RB1 = 1;       
193 
194         for(i=0;i<=_count; i++)
195         {
196             PMDOUT = ConfigImage[i + array_begin];
197             while(PMMODEbits.BUSY == 1);    
198         }       
199     }
200 }
201 
202 void DrawScreen(uint8_t scrn, char title[])
203 {
204     //Clear the Screen
205     Display_CLRSCN(white);
206     
207     //Draw Header Bar
208     DrawHeader();
209 
210     switch(scrn)
211     {
212         //Information
213         case INFO_SCREEN:
214             //Draw Title text        
215             WriteString(170, 5, title, black, 0x04D3);
216             
217             hchar = 10;
218             vchar = 50;
219             
220             //Display last error - 0 = no error
221             WriteString(hchar, vchar, lastErrorText, black, white);
222             
223             if(!lastError)
224             {
225                 WriteString(hchar, vchar, noneStr, green, white);
226             }
227             else
228             {
229                 Binary2ASCIIBCD(lastError);
230                 WriteChar(hchar, vchar, d1, red, white);
231                 WriteChar(hchar, vchar, d0, red, white);
232             }
233            
234             //Display device information       
235             //Processor
236             hchar = 10;
237             vchar = vchar + 25;
238             WriteString(hchar, vchar, ProcessorArray, black, white);
239             
240             
241             hchar = hchar + 20;
242             
243             if (FPU_Enabled() > 0)
244             {
245                 WriteString(hchar, vchar, FPUArray, green, white);
246             }
247 
248             //Display
249             hchar = 10;
250             vchar = vchar + 25;
251             WriteString(hchar, vchar, DisplayString, black, white);
252             
253             //SRAM size
254             hchar = 10;
255             vchar = vchar + 25;
256             WriteString(hchar, vchar, SRAMsize, black, white);
257             
258             hchar = hchar + 15;
259             
260             if((lastError & 0x4) != 0)
261             {
262                 WriteString(hchar, vchar, failStr, red, white);
263             }
264             else
265             {
266                 WriteString(hchar, vchar, SRAMStatusPass, green, white);
267             }
268 
269             hchar = hchar + 15;
270 
271             //Flash Size
272             hchar = 10;
273             vchar = vchar + 25;
274             WriteString(hchar, vchar, FlashSize, black, white);
275             
276             //Flash MID     
277             hchar = hchar + 15;
278             Binary2ASCIIHex(Flash_MID);
279             WriteChar(hchar, vchar, d_hex[1], black, white);
280             WriteChar(hchar, vchar, d_hex[0], black, white);            
281 
282             //Flash DID
283             hchar = hchar + 15;
284             Binary2ASCIIHex(Flash_DID);
285             WriteChar(hchar, vchar, d_hex[1], black, white);
286             WriteChar(hchar, vchar, d_hex[0], black, white);            
287 
288             hchar = 10;
289             vchar = vchar + 25;
290             
291             //Check what boards are present
292             WriteString(hchar, vchar, PeripheralsStr, black, white);
293             
294             hchar = hchar + 15;
295             
296             for(int i=1;i<8;i++)
297             {            
298                 Binary2ASCIIHex(PeripheralList[i]);
299                 WriteChar(hchar, vchar, d_hex[1], blue, white);
300                 WriteChar(hchar, vchar, d_hex[0], blue, white);
301                 hchar = hchar + 10;
302             }
303             
304            //USB ver
305             hchar = 10;
306             vchar = vchar + 25;
307             WriteString(hchar, vchar, USBver, black, white);
308             
309             //Oscillator
310             hchar = 10;
311             vchar = vchar + 25;
312             
313             switch(OSCCONbits.COSC)
314             {
315                 case 1:
316                     WriteString(hchar, vchar, PrimaryOsc, green, white);
317                 break;
318                 
319                 default:
320                     WriteString(hchar, vchar, OtherOsc, green, white);
321                 break;
322             }
323 
324             vchar = vchar + 25;
325             hchar = 10;
326             
327             WriteString(hchar, vchar, vbusStr, black, white);
328 
329             break;
330             
331         //Information
332         case BOARD_SCREEN:
333             //Draw Title text        
334             WriteString(170, 5, title, black, 0x04D3);
335             
336             hchar = 10;
337             vchar = 50;
338 
339             for(int i=0;i<65;i++)
340             {
341                 Binary2ASCIIHex(peripheral_info[current_board_address][i]);  
342                 WriteChar(hchar, vchar, d_hex[1], black, white);
343                 WriteChar(hchar, vchar, d_hex[0], black, white);
344 
345                 hchar = hchar + 10;
346                 
347                 if(hchar > 430)
348                 {
349                     hchar = 10;
350                     vchar = vchar + 20;
351                 }
352             }
353             NeedsRefresh = false;
354             break;
355             
356         case CONFIG_SCREEN:
357             
358             //Load Splash Image
359             /****************************/
360             Display_CASET(0, 479);
361             Display_RASET(0, 319);
362             Display_RAMWR();
363 
364             //Data
365             //RF3 = D/C 1=Data, 0=Command
366             PORTBbits.RB1 = 1;       
367 
368             for(int i=0;i<=153600; i++)
369             {
370                 PMDOUT = ConfigImage[i];
371                 while(PMMODEbits.BUSY == 1);    
372             }
373             
374             break;
375             
376         //Home
377         case HOME_SCREEN:
378             //Draw Title text        
379             WriteString(120, 5, title, black, 0x04D3);
380 
381             //Button1 - 'Info'
382             DrawButton(20, 50, 150, 50, ButtonTopColor, ButtonLowerColor, black, Button1Text); 
383 
384             //Button2 - 'Draw'
385             DrawButton(20, 125, 150, 50, ButtonTopColor, ButtonLowerColor, black, Button2Text); 
386 
387             break;
388             
389         case MOTION_SCREEN:
390             //Draw Title text        
391             WriteString(120, 5, title, black, 0x04D3);
392 
393             WriteString(10, 50, StatusStr, black, white);
394             
395             WriteString(180, 50, ControlStr, black, white);
396 
397             break;
398             
399         case DEBUG_SCREEN:
400             
401             WriteString(180, 5, HeaderString, black, 0x04D3);
402 
403             WriteString(10, 50, StatusStr, black, white);
404             
405             WriteString(180, 50, ControlStr, black, white);
406             
407             break;
408     
409         case ADC_SCREEN:
410             
411             WriteString(10, 50, StatusStr, black, white);
412             
413             break;
414         case MESSAGE_SCREEN:
415             Display_Rect(100, 200, 100, 200, blue);
416         break;
417     }   
418 }
419 
420 void DrawCircle(void)
421 {
422     int theta = 0;  // angle that will be increased each loop
423     int h = 200;      // x coordinate of circle center
424     int k = 150;      // y coordinate of circle center
425     int step = 15;  // amount to add to theta each time (degrees)
426     int x;
427     int y;
428     int r = 100;
429     
430     while(theta < 360)
431     { 
432         x = h + r*cos(theta);
433         y = k + r*sin(theta);
434         Display_Rect(x, x+5, y, y+5, blue);
435         theta = theta + 1;
436     }
437 }
438 
439 void MessageBox(char text[], uint8_t show_time)
440 {
441     //Border
442     Display_Rect(100, 300, 220, 222, blue);
443     Display_Rect(98, 100, 100, 222, blue);
444     Display_Rect(300, 302, 100, 222, blue);    
445     
446     //header
447     Display_Rect(100, 300, 100, 125, blue);
448     WriteString(105, 100, MessageBoxTitle, white, blue);
449     
450     //body
451     Display_Rect(100, 300, 125, 180, white);
452     
453     //footer
454     Display_Rect(100, 300, 180, 220, 0xe73c);
455     
456     //string
457     WriteString(104, 140, text, black, white);
458     
459     //shadow
460     Display_Rect(302, 330, 130, 240, 0x6b4c);
461     Display_Rect(130, 330, 222, 250, 0x6b4c);
462     
463     LongDelay(show_time);
464     
465     screen = old_screen;
466     
467 }
468 
469 int FPU_Enabled(void)
470 {
471     uint32_t status = _mfc0(12, 0);
472     return (status & (1u << 29)) != 0;
473 }