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<24000; 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             //If touch module is not found change the string
250             if(!I2C_init())
251             {
252                  strcpy(DisplayString, "480x320 16-bit RGB 65K");
253             }
254             
255             hchar = 10;
256             vchar = vchar + 25;
257             WriteString(hchar, vchar, DisplayString, black, white);
258             
259             //SRAM size
260             hchar = 10;
261             vchar = vchar + 25;
262             WriteString(hchar, vchar, SRAMsize, black, white);
263             
264             hchar = hchar + 15;
265             
266             if((lastError & 0x4) != 0)
267             {
268                 WriteString(hchar, vchar, failStr, red, white);
269             }
270             else
271             {
272                 WriteString(hchar, vchar, SRAMStatusPass, green, white);
273             }
274 
275             hchar = hchar + 15;
276 
277             //Flash Size
278             hchar = 10;
279             vchar = vchar + 25;
280             WriteString(hchar, vchar, FlashSize, black, white);
281             
282             //Flash MID     
283             hchar = hchar + 15;
284             Binary2ASCIIHex(Flash_MID);
285             WriteChar(hchar, vchar, d_hex[1], black, white);
286             WriteChar(hchar, vchar, d_hex[0], black, white);            
287 
288             //Flash DID
289             hchar = hchar + 15;
290             Binary2ASCIIHex(Flash_DID);
291             WriteChar(hchar, vchar, d_hex[1], black, white);
292             WriteChar(hchar, vchar, d_hex[0], black, white);            
293 
294             hchar = 10;
295             vchar = vchar + 25;
296             
297             //Check what boards are present
298             WriteString(hchar, vchar, PeripheralsStr, black, white);
299             
300             hchar = hchar + 15;
301             
302             for(int i=1;i<8;i++)
303             {            
304                 Binary2ASCIIHex(PeripheralList[i]);
305                 WriteChar(hchar, vchar, d_hex[1], blue, white);
306                 WriteChar(hchar, vchar, d_hex[0], blue, white);
307                 hchar = hchar + 10;
308             }
309             
310            //USB ver
311             hchar = 10;
312             vchar = vchar + 25;
313             WriteString(hchar, vchar, USBver, black, white);
314             
315             //Oscillator
316             hchar = 10;
317             vchar = vchar + 25;
318             
319             switch(OSCCONbits.COSC)
320             {
321                 case 1:
322                     WriteString(hchar, vchar, PrimaryOsc, green, white);
323                 break;
324                 
325                 default:
326                     WriteString(hchar, vchar, OtherOsc, green, white);
327                 break;
328             }
329 
330             vchar = vchar + 25;
331             hchar = 10;
332             
333             WriteString(hchar, vchar, vbusStr, black, white);
334 
335             break;
336             
337         //Information
338         case BOARD_SCREEN:
339             //Draw Title text        
340             WriteString(170, 5, title, black, 0x04D3);
341             
342             hchar = 10;
343             vchar = 50;
344 
345             for(int i=0;i<65;i++)
346             {
347                 Binary2ASCIIHex(peripheral_info[current_board_address][i]);  
348                 WriteChar(hchar, vchar, d_hex[1], black, white);
349                 WriteChar(hchar, vchar, d_hex[0], black, white);
350 
351                 hchar = hchar + 10;
352                 
353                 if(hchar > 430)
354                 {
355                     hchar = 10;
356                     vchar = vchar + 20;
357                 }
358             }
359             NeedsRefresh = false;
360             break;
361             
362         case CONFIG_SCREEN:
363             
364             //Load Splash Image
365             /****************************/
366             Display_CASET(0, 479);
367             Display_RASET(0, 319);
368             Display_RAMWR();
369 
370             //Data
371             //RF3 = D/C 1=Data, 0=Command
372             PORTBbits.RB1 = 1;       
373 
374             for(int i=0;i<=153600; i++)
375             {
376                 PMDOUT = ConfigImage[i];
377                 while(PMMODEbits.BUSY == 1);    
378             }
379             
380             break;
381             
382         //Home
383         case HOME_SCREEN:
384             //Draw Title text        
385             WriteString(120, 5, title, black, 0x04D3);
386 
387             //Button1 - 'Info'
388             DrawButton(20, 50, 150, 50, ButtonTopColor, ButtonLowerColor, black, Button1Text); 
389 
390             //Button2 - 'Draw'
391             DrawButton(20, 125, 150, 50, ButtonTopColor, ButtonLowerColor, black, Button2Text); 
392 
393             break;
394             
395         case MOTION_SCREEN:
396             //Draw Title text        
397             WriteString(120, 5, title, black, 0x04D3);
398 
399             WriteString(10, 50, StatusStr, black, white);
400             
401             WriteString(180, 50, ControlStr, black, white);
402 
403             break;
404             
405         case DEBUG_SCREEN:
406             
407             WriteString(180, 5, HeaderString, black, 0x04D3);
408 
409             WriteString(10, 50, StatusStr, black, white);
410             
411             WriteString(180, 50, ControlStr, black, white);
412             
413             break;
414     
415         case ADC_SCREEN:
416             
417             WriteString(10, 50, StatusStr, black, white);
418             
419             break;
420         case MESSAGE_SCREEN:
421             Display_Rect(100, 200, 100, 200, blue);
422         break;
423     }   
424 }
425 
426 void DrawCircle(void)
427 {
428     int theta = 0;  // angle that will be increased each loop
429     int h = 200;      // x coordinate of circle center
430     int k = 150;      // y coordinate of circle center
431     int step = 15;  // amount to add to theta each time (degrees)
432     int x;
433     int y;
434     int r = 100;
435     
436     while(theta < 360)
437     { 
438         x = h + r*cos(theta);
439         y = k + r*sin(theta);
440         Display_Rect(x, x+5, y, y+5, blue);
441         theta = theta + 1;
442     }
443 }
444 
445 void MessageBox(char text[], uint8_t show_time)
446 {
447     //Border
448     Display_Rect(100, 300, 220, 222, blue);
449     Display_Rect(98, 100, 100, 222, blue);
450     Display_Rect(300, 302, 100, 222, blue);    
451     
452     //header
453     Display_Rect(100, 300, 100, 125, blue);
454     WriteString(105, 100, MessageBoxTitle, white, blue);
455     
456     //body
457     Display_Rect(100, 300, 125, 180, white);
458     
459     //footer
460     Display_Rect(100, 300, 180, 220, 0xe73c);
461     
462     //string
463     WriteString(104, 140, text, black, white);
464     
465     //shadow
466     Display_Rect(302, 330, 130, 240, 0x6b4c);
467     Display_Rect(130, 330, 222, 250, 0x6b4c);
468     
469     LongDelay(show_time);
470     
471     screen = old_screen;
472     
473 }
474 
475 int FPU_Enabled(void)
476 {
477     uint32_t status = _mfc0(12, 0);
478     return (status & (1u << 29)) != 0;
479 }