Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 01:05 10 May 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MM+ Fast Loading of RLE Images from Flash to SSD1963

Author Message
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 971
Posted: 04:24am 12 Jun 2020
Copy link to clipboard 
Print this post

In this  post Peter Mather developed Cfunctions for data logging to Serial Flash memory chips.
These can be conveniently mounted on an existing footprint on the SSD1963 LCD.
Routines to write and read data were also included.

There is further discussion here about compatability if touch is used. The Cfunctions are compatible with sharing SPI with touch.


Some numbers.
An 800*480 image at 3 Bytes per pixel for RGB888 colour is 3*800*480=1152000 Bytes.
This is 4500 pages when stored on the flash chip. (256 Bytes per page). The 4500 page
Image takes about 1050ms to restore to the SSD1963. Most of this time is reading from the Flash chip via SPI.

Storing the image on flash as RGB565 requires 2 Bytes per pixel and reduces the size to 3000 pages Without a noticeable change in quality of the image.
This reduces the restore time to about 700ms.

This  posts discusses a few ideas about how to reduce the size of images so they can be quickly loaded to the LCD.


Run-Length Encoding is a lossless method of compressing files with repeated Bytes.
See wikipedia entry


The CFunction SaveImageRLE and CSUB RestoreImageRLE below implement a method of
saving images to the flash using RLE to compress the image and restoring to the SSD1963.

The method is to use MMBasic  LOAD IMAGE command to get the required image on the
SSD1963 LCD. SaveImageRLE then saves to the flash.  RestoreImageRLE then displays he saved image on the LCD.

The image is stored using the following method.
The 3 bytes used to define each RGB888 pixel are reduced to 2 bytes encoded
as RGB565 ie. RRRRRGGG GGGBBBBB
This is then stored using Run Length Encoding (RLE). Each pixel is stored as
its two byte RGB565 code, unless a run of two or more identical pixel are detected.
In this case only the first two of these identical pixel are written,
a count is then made of the number of identical pixel beyond the first two.
This count is then recorded using 1,2 or 3 bytes a detailed below.
 
If count <128 then a single Byte is used ie.0XXX XXXX B7=0 and B(6)-B(0)
contain the value.
If count < 16384 then two bytes are used. Byte 0 has  B7=1 in to indicate
an addition Byte is required. i.e.
Byte 0 is 1XXX XXXX and Byte 1 has  B7=0 is 0XXX XXXX .This leaves 14 bits
to store the counter.
For a counter of > 16383 then three bytes are used. B7=1 for  Byte 1 indicating
another byte is required. ie. 1XXX XXXX     1XXX XXXX   XXXX XXXX    
All eight bits of Byte 2 are used to store the value, giving a total of 22 bits.
 
This method of encoding is very effective when there are runs of the same pixel.
e.g. A full screen of the same colour is stored in 7 bytes.

This image from one of the above posts is the candidate used.


The attached zip file contains the above pump256.BMP It is the schematic from  above  
saved as 256 colours to increase the possibility of runs of pixels the same colour.
This 800*320  image is around 311 pages when saved to flash. It restores to the LCD in about 110ms. This refresh looks instantaneous when changing screens.

PumpPictures.zip

I used XnView as a simple Photo assistant tool. This was used to manipulate the image to 256 colours.
When you add it's shell extension, XnShell, it has a lot of common tasks in it's right-click context menu.
Google XnView

The W25Q64FVSSIG (8MB chip) return this when initialised with Peter's Cfunctions.
JEDEC ID = EF4017
F_CS = 58
Memory size is 64 Mbits
Memory size is 8 MBytes
Valid Page Nos.  0 - 32767 each 256 Bytes

So if we allow 400 pages for each image, this means we could have 32000/400 ie 80 different copies of the image save on the flash chip, each displayable in just over 1/10 of a second.

This demo program takes Geoff's Pump Controller demo and adds a schematic to the front of it. The Pump controls are accessed by touching the schematic. Once the controls are exited the appropriate image based on the power level is loaded. The code is set for and E100 board. The file pump256.bmp needs to be on the SDCard. The variable eraseandload at line 43 should be initialial set to 1 to load
the flash. After the images are stored eraseandload should be  set to 0.

eraseandload=1   '0 don't erase, 1 erase and load images

The demo only saves and restores full screens, however small areas can be selected
if desired. So use a bit like BLIT, but with data stored to flash and not memory.

 
  Quote  
'================================================================================================  
' File: RLEDemo.bas   Run Length Encoding (RLE) images between Flash and SSD1963 LCD
'================================================================================================  
' Demonstration program for the E100 Micromite+ with Flash Chip
' mounted on the spare footprint on SSD1963 LCD.
'
' It requires file pump256.BMP on the SDCARD.
' It stores 4 copies of this on the Flash chip and displays
' the first one when it starts.
' Touching the diagram anywhere will bring up the Pump Contol.
' Exit from Pump Control screen will redisplay the schematic
' that matches the current economy setting.
'
' Added on top of Geoffs Pump Controller Demo.
' Geoff Graham, October 2015
'  
'
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'================================================================================================
' Option List printout for E100 - must be entered at command line.
'================================================================================================  
'  OPTION LCDPANEL SSD1963_5, LANDSCAPE,, 6
'  OPTION TOUCH 1, 40
'  OPTION SDCARD 47
'  GUI CALIBRATE

'================================================================================================
' Option settings for program
'================================================================================================  
Option Explicit



'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'           FLASH STUFF
'  Set eraseandload=1 the first time , so images are loaded to flash.
'  After that eraseandload=0 unless you want to change the images
'  
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim INTEGER eraseandload,nextpage
eraseandload=
1   '0 dont erase, 1 erase


DIM INTEGER lastpage 'stores last page
const chipselectpin%=58 'F_CS chip select pin 53 Peter's board, 58 E100
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''


Dim ledsY  
Colour RGB (white), RGB(black)  
 
' reference numbers for the controls are defined as constants  
Const c_head = 1, c_pmp = 2, sw_pmp = 3, c_flow = 4, tb_flow = 5  
Const led_run = 6, led_alarm = 7, c_diag=8
Const frm_alarm = 20, nbr_hi = 21, nbr_lo = 22, pb_test =23  
Const c_hi = 24, c_lo = 25 ,  pb_exit =26
Const frm_pump = 30, r_econ = 31, r_norm = 32, r_hi = 33  
Const frm_log = 40, cb_enabled = 41, c_fname = 42, tb_fname = 43  
Const c_log = 44, cb_flow = 45, cb_pwr = 46, cb_warn = 47  
Const cb_alarm = 48, c_bright = 49, sb_bright = 50  
CONST gui_area1=51
 
' now draw the "Pump Control" display  
CLS  
GUI Interrupt TouchDown, TouchUp  
 
' display the heading  
Font 2,2 : GUI Caption c_head, "Pump Control", 10, 0  
Font 3 : GUI Caption c_pmp, "Pump", 20, 60, , RGB(brown)  
 
' now, define and display the controls  
' first display the switch  
Font 4  
GUI Switch sw_pmp, "ON|OFF", 20, 90, 150, 50, RGB(white),RGB(brown)  
CtrlVal(sw_pmp) = 1  
 
' the flow rate display box  
Font 3 : GUI Caption c_flow, "Flow Rate", 20, 170,, RGB(brown),0  
Font 4 : GUI Displaybox tb_flow, 20, 200, 150, 45  
CtrlVal(tb_flow) = "20.1"  
 
' the radio buttons and their frame  
Font 3 : GUI Frame frm_pump, "Power", 20, 290, 170, 163, RGB(200,20,255)  
GUI Radio r_econ, "Economy", 43, 328, 12, RGB(230, 230, 255)  
GUI Radio r_norm, "Normal", 43, 374  
GUI Radio r_hi, "High", 43, 418  
CtrlVal(r_norm) = 1     ' start with the "normal" button selected  
 
' the alarm frame with two number boxes and a push button switch  
Font 3 : GUI Frame frm_alarm, "Alarm", 220, 220, 200, 233,RGB(green)  
GUI Caption c_hi, "High:", 232, 260, "LT", RGB(yellow)  
GUI Numberbox nbr_hi, 318,MM.VPos-6,90,MM.FontHeight+12,RGB(yellow),RGB(64,64,64)  
GUI Caption c_lo, "Low:", 232, 325, LT, RGB(yellow),0  
GUI Numberbox nbr_lo, 318,MM.VPos-6,90,MM.FontHeight+12,RGB(yellow),RGB(64,64,64)  
GUI Button pb_test, "TEST", 257, 383, 130, 40,RGB(yellow), RGB(red)  
CtrlVal(nbr_lo) = 15.7 : CtrlVal(nbr_hi) = 35.5  
 
' draw the two LEDs  
Const ledsX = 255, coff = 50    ' define their position  
ledsY = 105 : GUI LED led_run, "Running", ledsX, ledsY, 15, RGB(green)  
ledsY = ledsY+49 : GUI LED led_alarm, "Alarm", ledsX, ledsY, 15, RGB(red)  
CtrlVal(led_run) = 1   ' the switch defaults to on so set the LED on  
 
' the logging frame with check boxes and a text box  
Colour RGB(cyan), 0  
GUI Frame frm_log, "Log File", 450, 20, 330, 355, RGB(green)  
GUI Checkbox cb_enabled, "Logging Enabled", 470, 50, 30, RGB(cyan)  
GUI Caption c_fname, "File Name", 470, 105  
GUI Textbox tb_fname, 470, 135, 290, 40, RGB(cyan), RGB(64,64,64)  
GUI Caption c_log, "Record:", 470, 205, , RGB(cyan), 0  
GUI Checkbox cb_flow, "Flow Rate", 500, 245, 25  
GUI Checkbox cb_alarm, "Alarms", 500, 285, 25  
GUI Checkbox cb_warn, "Warnings", 500, 325, 25  
CtrlVal(cb_enabled) = 1  
CtrlVal(tb_fname) = "LOGFILE.TXT"  
 
' define and display the spinbox for controlling the backlight  
'GUI Caption c_bright, "Backlight", 442, 415, ,RGB(200,200,255),0  
'GUI Spinbox sb_bright, MM.HPos + 8, 400, 200, 50,,,10, 10, 100  
'CtrlVal(sb_bright) = 100

GUI Button pb_exit, "Exit", 600, 400, 130, 80,RGB(BLACK), RGB(GREEN)  
GUI AREA  gui_area1,0,40,800,320

 
' All the controls have been defined and displayed. At this point  
' the program could do some real work but because this is just a  
' demo there is nothing to do.  So it just sits in a loop.

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'           FLASH STUFF
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

DIM integer showdiag=0,showcontrols=0
dim string econ$="Normal"


'================================================================================================
' Initialise the flash chip and load the images if required
'================================================================================================    
if eraseandload=1 then
 initchip(1,chipselectpin%) 'iniitialise the chip 0=no erase  1=full erase
 timer=0
 CLS RGB(GREEN)
 'load image "weather"
 
 load image "pump256"
 'LOAD IMAGE "weather-station-256fs"
 'LOAD IMAGE "weather-station-new100"
 ? timer," for 800*480 image load from SDCARD"
 
  timer=0
  nextpage=SaveImageRLE(0,0,800,320,0,chipselectpin%)
  ? timer, " mS for save page , next free page = ",nextpage
 
  ' put a Normal watermark on the image an save again
  text 470,100,"Normal",,,2,RGB(BLACK),-1
  timer=0
  nextpage=SaveImageRLE(0,0,800,320,400,chipselectpin%)
  ? timer, " mS for save page , next free page = ",nextpage
 
  ' restore image and put a Economy watermark on the image an save again
  RestoreImageRLE 0,0,800,320,0,chipselectpin%
  text 470,100,"Economy",,,2,RGB(GREEN),-1
  timer=0
  nextpage=SaveImageRLE(0,0,800,320,800,chipselectpin%)
  ? timer, " mS for save page , next free page = ",nextpage
 
   ' restore image and put a High watermark on the image an save again
  RestoreImageRLE 0,0,800,320,0,chipselectpin%
  text 470,100,"High",,,2,RGB(RED),-1
  timer=0
  nextpage=SaveImageRLE(0,0,800,320,1200,chipselectpin%)
  ? timer, " mS for save page , next free page = ",nextpage  


else
  initchip(0,chipselectpin%) 'iniitialise the chip 0=no erase  1=full erase

endif

'================================================================================================
' Initialise the screen
'================================================================================================
cls
timer=0
RestoreImageRLE 0,40,800,320,0,chipselectpin%
? timer, " for 800*480 image restore from FLASH"
GUI Caption c_diag, "Pump Schematic - Touch to set controls", 10, 0  
GUI SHOW GUI_AREA1

'================================================================================================
' Main Loop
'================================================================================================    
Do
 if showdiag=1 then
     showdiag=0
     cls
     if econ$="Normal" then RestoreImageRLE 0,40,800,320,400,chipselectpin%
     if econ$="Economy" then RestoreImageRLE 0,40,800,320,800,chipselectpin%
     if econ$="High" then RestoreImageRLE 0,40,800,320,1200,chipselectpin%
     GUI SHOW gui_area1
     'GUI SHOW c_diag
     GUI Caption c_diag, "Pump Schematic", 10, 0
     
 endif
if showcontrols=1 then
     showcontrols=0
     cls
     GUI delete c_diag
     GUI SHOW ALL
     GUI HIDE gui_area1
   
     
     
     
 endif

Loop  

'================================================================================================
' Subroutines and Functions
'================================================================================================      
 
' the interrupt routine for touch down  
' using a select case command it has a different process for each control  
Sub TouchDown  
 Select Case Touch(REF)       ' find out the control touched  
   Case cb_enabled            ' the enable check box  
     If CtrlVal(cb_enabled) Then  
       GUI ENABLE c_fname, tb_fname, c_log, cb_flow, cb_alarm, cb_warn  
     Else  
       GUI Disable c_fname, tb_fname, c_log, cb_flow, cb_alarm, cb_warn  
     EndIf  
   Case sb_bright             ' the brightness spin box  
     BackLight CtrlVal(sb_bright)  
   Case sw_pmp                ' the pump on/off switch  
     CtrlVal(led_run) = CtrlVal(sw_pmp)  
     CtrlVal(tb_flow) = Str$(CtrlVal(sw_pmp) * 20.1)  
     CtrlVal(r_norm) = 1  
   Case pb_test               ' the alarm test button  
     CtrlVal(led_alarm) = 1  
     'GUI beep 250  
   Case r_econ                ' the economy radio button  
     CtrlVal(tb_flow) = Str$(CtrlVal(sw_pmp) * 18.3)
     econ$="Economy"
   Case r_norm                ' the normal radio button  
     CtrlVal(tb_flow) = Str$(CtrlVal(sw_pmp) * 20.1)
     econ$="Normal"  
   Case r_hi                 ' the high radio button  
     CtrlVal(tb_flow) = Str$(CtrlVal(sw_pmp) * 23.7)
      econ$="High"
   CASE pb_exit
     showdiag=1
     
   CASE gui_area1
     showcontrols=1  
     
 End Select  
End Sub  
 
' interrupt routine when the touch is removed  
Sub TouchUp  
 Select Case Touch(LASTREF)    ' use the last reference  
   Case pb_test                ' was it the test button  
     CtrlVal(led_alarm) = 0    ' turn off the LED  
 End Select  
End Sub  





'  File SaveImageRLE.bas  written 11-Jun-2020  21:03:02
'
CFunction SaveImageRLE
   00000092
   'write_command_data
   27BDFFF8 AFA60010 AFA70014 3C02BF88 24030100 AC436434 27A60010 AFA60000
   308400FF 34840200 AC446430 24040200 AC446434 AC446438 AC436438 18A0000D
   8FA40000 00001821 24060200 24870004 AFA70000 80840000 34840300 AC446430
   AC466434 AC466438 24630001 1465FFF7 8FA40000 03E00008 27BD0008
   'defineregion
   2482FFFF 00463021 24A2FFFF 00471021 24090100 3C08BF88 AD096434 3C089D00
   8D090094 8D230000 8D080098 8D080000 0103502B 11400003 01004821 00604821
   01001821 3C089D00 8D0D0090 81A80015 240A0001 150A000C 24070002 00805821
   00C05021 81A3002C 28630007 14600023 00A06021 00063027 00042027 00895021
   1000001E 00C95821 15070008 24070003 00A05821 00405021 00063027 00C36021
   00041027 10000015 00431021 1507000E 00021027 00C05021 00436021 00051027
   00431021 81A3002C 28630007 1060000B 00805821 00063027 00042027 00895021
   10000006 00C95821 00495821 00052827 00A95021 00806021 00C01021 3C03BF88
   2404022A AC646430 24080200 AC686434 AC686438 24090100 AC696438 000B2202
   34840300 AC646430 AC686434 AC686438 356B0300 AC6B6430 AC686434 AC686438
   000A2202 34840300 AC646430 AC686434 AC686438 354A0300 AC6A6430 AC686434
   AC686438 AC696434 2404022B AC646430 AC686434 AC686438 AC696438 000C2202
   34840300 AC646430 AC686434 AC686438 358C0300 AC6C6430 AC686434 AC686438
   00022202 34840300 AC646430 AC686434 AC686438 34420300 AC626430 AC686434
   AC686438 03E00008 00000000
   'main
   27BDFFA0 AFBF005C AFBE0058 AFB70054 AFB60050 AFB5004C AFB40048 AFB30044
   AFB20040 AFB1003C AFB00038 8C820000 8CA30000 8CC40000 8CE50000 8FA60074
   8CD60000 8FA60070 8CC60000 AFA60018 28500000 0010100B 00408021 3C029D00
   8C420094 8C420000 0202382B 2446FFFF 00C7800A 28930000 0013200B 00809821
   00501023 0044202B 0044980B 28710000 0011180B 00608821 3C029D00 8C420098
   8C420000 0062202B 2443FFFF 0064880A 28B40000 0014280B 00A0A021 00511023
   0045182B 0043A00B 24020003 72621002 00540018 00001812 AFA30010 3C029D00
   8C42003C 0040F809 24040106 0040F021 00409021 02002021 02202821 02603021
   02803821 0411FF4B 00000000 3C02BF88 24030100 AC436434 2404022E AC446430
   24040200 AC446434 AC446438 AC436438 240300FF AC43641C AFA00020 AFA00014
   AFA00028 0000B821 0000A021 1000016D 27D10100 2484FFFF 26F70001 24050001
   16E5000C AFA40010 24070002 3C06BF88 ACC76234 3C02BF81 8C43F220 8C42F220
   ACC76238 8CC26420 304200F8 10000095 AFA20030 24020002 16E20012 24070003
   3C03BF88 AC626234 3C02BF81 8C43F220 8C42F220 24050002 3C04BF88 AC856238
   8C826420 304200FC AFA2002C 8FA60030 30C300F8 00021142 00621025 10000081
   AFA20024 16E7007F 24030002 3C02BF88 AC436234 3C02BF81 8C43F220 8C42F220
   24050002 3C04BF88 AC856238 8C826420 8FA6002C 000618C0 306300E0 7C4220C0
   8FA70028 14E0000C 00621825 8FA40024 00041200 00621025 AFA2001C 02541021
   A0440000 A0430001 26940002 24050001 10000064 AFA50028 8FA60024 00061200
   00621025 8FA7001C 14E20016 8FA60020 8FA40010 10800014 24070001 8FA50020
   24060001 14A60005 8FA20020 8FA70014 24E70001 10000053 AFA70014 14400052
   2A820100 02541021 8FA40024 A0440000 A0430001 26940002 24050001 10000049
   AFA50020 24070001 14C70033 02542021 8FA4001C 14820007 8FA70014 8FA50010
   2CA40001 8FA60014 00C43021 AFA60014 8FA70014 2CE40080 50800005 8FA50014
   02542021 A0870000 10000018 26940001 2CA44000 5080000B 02542821 02542021
   000531C2 2405FF80 00C52825 A0850000 8FA60014 30C5007F A0850001 1000000B
   26940002 8FA70014 000733C2 2404FF80 00C43025 A0A60000 00073202 00C42025
   A0A40001 A0A70002 26940003 8FA4001C 10820017 02542021 8FA50024 A0850000
   A0830001 26940002 AFA2001C AFA00020 10000014 AFA00014 8FA60024 A0860000
   A0830001 8FA7001C 14E2000D 26940002 8FA20010 1440000C 2A820100 02541021
   8FA30014 A0430000 10000006 26940001 AFA2001C AFA00020 10000002 AFA00014
   AFA2001C 2A820100 144000C5 3AE20003 8FA40018 00049A00 3C029D00 8C42001C
   02C02021 0040F809 24050005 24030006 3C02BF80 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 00000000 3C05BF80 8CA25A20 3C109D00 8E02001C 02C02021
   0040F809 24050006 8E02001C 02C02021 0040F809 24050005 24070002 3C06BF80
   ACC75A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E633C00
   AC435A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E633A00
   AC435A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 327300FF
   AC535A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C425A20 03C02021
   3C03BF80 90820000 AC625A20 8C625A10 30420080 1040FFFD 00000000 8C625A20
   24840001 5491FFF8 90820000 3C029D00 8C42001C 02C02021 0040F809 24050006
   3C139D00 3C10BF80 8E620004 0040F809 24040064 8E62001C 02C02021 0040F809
   24050005 24020005 AE025A20 8E025A10 30420080 1040FFFD 00000000 8E025A20
   AE155A20 8E025A10 30420080 1040FFFD 00000000 8E155A20 7C15AC20 8E62001C
   02C02021 0040F809 24050006 32A20001 5440FFE6 8E620004 8FA20018 24420001
   AFA20018 24020100 1282000F 24020101 16820005 24020102 92420100 A2420000
   10000015 24140001 16820009 24020103 92420100 A2420000 92420101 A2420001
   1000001A 24140002 0000A021 24020103 1682000A 24020104 92420100 A2420000
   92420101 A2420001 92420102 A2420002 1000001E 24140003 24020104 5682000C
   24020105 92420100 A2420000 92420101 A2420001 92420102 A2420002 92420103
   A2420003 10000023 24140004 24020105 5682000F 24020106 92420100 A2420000
   92420101 A2420001 92420102 A2420002 92420103 A2420003 92420104 A2420004
   24140005 10000016 24020005 24020106 16820011 2A830106 92420100 A2420000
   92420101 A2420001 92420102 A2420002 92420103 A2420003 92420104 A2420004
   92420105 A2420005 24140006 10000004 24020006 2A830106 10600008 02801021
   2404FFFF 03C21821 A0640000 24420001 28430106 1460FFFC 03C21821 3AE20003
   0002B80A 8FA30010 1460FE92 8FA40010 1A80006C 8FB30018 00138A00 3C029D00
   8C42001C 02C02021 0040F809 24050005 24030006 3C02BF80 AC435A20 3C03BF80
   8C625A10 30420080 1040FFFD 00000000 3C12BF80 8E425A20 3C109D00 8E02001C
   02C02021 0040F809 24050006 8E02001C 02C02021 0040F809 24050005 24020002
   AE425A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E233C00
   AC435A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E233A00
   AC435A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 323100FF
   AC515A20 3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C425A20 03C02021
   27C50100 3C03BF80 90820000 AC625A20 8C625A10 30420080 1040FFFD 00000000
   8C625A20 24840001 5485FFF8 90820000 3C029D00 8C42001C 02C02021 0040F809
   24050006 3C119D00 3C10BF80 8E220004 0040F809 24040064 8E22001C 02C02021
   0040F809 24050005 24020005 AE025A20 8E025A10 30420080 1040FFFD 00000000
   8E025A20 AE155A20 8E025A10 30420080 1040FFFD 00000000 8E155A20 7C15AC20
   8E22001C 02C02021 0040F809 24050006 32A20001 5440FFE6 8E220004 26730001
   AFB30018 240300FF 3C02BF88 AC43641C 3C029D00 8C420044 0040F809 03C02021
   8FA40018 00041FC3 00801021 8FBF005C 8FBE0058 8FB70054 8FB60050 8FB5004C
   8FB40048 8FB30044 8FB20040 8FB1003C 8FB00038 03E00008 27BD0060
End CFunction

 
'  File RestoreImageRLE.bas  written 11-Jun-2020  21:23:14
'
CSub RestoreImageRLE
   00000092
   'write_command_data
   27BDFFF8 AFA60010 AFA70014 3C02BF88 24030100 AC436434 27A60010 AFA60000
   308400FF 34840200 AC446430 24040200 AC446434 AC446438 AC436438 18A0000D
   8FA40000 00001821 24060200 24870004 AFA70000 80840000 34840300 AC446430
   AC466434 AC466438 24630001 1465FFF7 8FA40000 03E00008 27BD0008
   'defineregion
   2482FFFF 00463021 24A2FFFF 00471021 24090100 3C08BF88 AD096434 3C089D00
   8D090094 8D230000 8D080098 8D080000 0103502B 11400003 01004821 00604821
   01001821 3C089D00 8D0D0090 81A80015 240A0001 150A000C 24070002 00805821
   00C05021 81A3002C 28630007 14600023 00A06021 00063027 00042027 00895021
   1000001E 00C95821 15070008 24070003 00A05821 00405021 00063027 00C36021
   00041027 10000015 00431021 1507000E 00021027 00C05021 00436021 00051027
   00431021 81A3002C 28630007 1060000B 00805821 00063027 00042027 00895021
   10000006 00C95821 00495821 00052827 00A95021 00806021 00C01021 3C03BF88
   2404022A AC646430 24080200 AC686434 AC686438 24090100 AC696438 000B2202
   34840300 AC646430 AC686434 AC686438 356B0300 AC6B6430 AC686434 AC686438
   000A2202 34840300 AC646430 AC686434 AC686438 354A0300 AC6A6430 AC686434
   AC686438 AC696434 2404022B AC646430 AC686434 AC686438 AC696438 000C2202
   34840300 AC646430 AC686434 AC686438 358C0300 AC6C6430 AC686434 AC686438
   00022202 34840300 AC646430 AC686434 AC686438 34420300 AC626430 AC686434
   AC686438 03E00008 00000000
   'main
   27BDFFD0 AFBF002C AFB60028 AFB50024 AFB40020 AFB3001C AFB20018 AFB10014
   AFB00010 8FA20044 8C540000 8FA20040 8C550000 0015AA00 8C820000 8CA30000
   8CC50000 8CE70000 28440000 0004100B 00402021 3C029D00 8C420094 8C420000
   0082402B 2446FFFF 00C8200A 28A60000 0006280B 00A03021 00441023 0045282B
   0045300B 28650000 0005180B 00602821 3C029D00 8C420098 8C420000 0062402B
   2443FFFF 0068280A 28E30000 0003380B 00451023 0047182B 0043380B 70E68002
   0411FF5C 00000000 3C02BF88 24030100 AC436434 2404022C AC446430 24040200
   AC446434 AC446438 AC436438 3C029D00 8C42001C 02802021 0040F809 24050005
   3C02BF80 8C565A30 24030001 AC435A30 24030003 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 7EA33C00 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 7EB53A00 AC555A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 AC405A20 3C03BF80 8C625A10 30420080
   1040FFFD 3C02BF80 8C425A20 1200009A 00005021 00004821 00005821 00003821
   3C03BF80 3C02BF88 24060200 00C02021 2408FFFF 14E00028 00000000 AC725A20
   8C655A10 30A50080 10A0FFFD 00000000 8C675A20 30E700FF AC715A20 8C655A10
   30A50080 10A0FFFD 00000000 8C655A20 30A500FF 00079A00 02659825 30F200F8
   000588C0 323100FF 2610FFFF 364C0300 AC4C6430 AC466434 AC466438 00073940
   30E700FF 000528C2 30A5001C 00E52825 34A50300 AC456430 AC466434 AC466438
   36250300 AC456430 AC466434 AC466438 10000067 24070001 AC725A20 8C655A10
   30A50080 10A0FFFD 00000000 8C725A20 325200FF AC715A20 8C655A10 30A50080
   10A0FFFD 00000000 8C715A20 323100FF 00122A00 00B12825 001168C2 31AD001C
   00126140 318C00FF 01AC6825 325200F8 001188C0 16650040 323100FF 2610FFFF
   364C0300 AC4C6430 AC466434 AC466438 35AD0300 AC4D6430 AC466434 AC466438
   362E0300 AC4E6430 AC466434 AC466438 AC6B5A20 8C655A10 30A50080 10A0FFFD
   00000000 8C6B5A20 2D650080 14A00018 01607821 316B007F AC695A20 8C655A10
   30A50080 10A0FFFD 00000000 8C695A20 2D250080 50A00004 3129007F 000B79C0
   1000000B 01E97825 AC6A5A20 8C655A10 30A50080 10A0FFFD 00000000 8C6A5A20
   000B7BC0 00092A00 01E57825 01EA7825 11E0001F 00003821 25E5FFFF AC4C6430
   AC446434 AC446438 AC4D6430 AC446434 AC446438 AC4E6430 AC446434 AC446438
   24A5FFFF 14A8FFF5 00000000 020F8023 1000000F 00003821 2610FFFF 364C0300
   AC4C6430 AC466434 AC466438 35AD0300 AC4D6430 AC466434 AC466438 362C0300
   AC4C6430 AC466434 AC466438 00A09821 1600FF70 00000000 3C029D00 8C42001C
   02802021 0040F809 24050006 3C02BF80 AC565A30 8FBF002C 8FB60028 8FB50024
   8FB40020 8FB3001C 8FB20018 8FB10014 8FB00010 03E00008 27BD0030
End CSub


'  File PrintFlashPage.bas  written 11-Jun-2020  21:01:14
'
CSub PrintFlashPage
   00000043
   'getFPC
   27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008
   'pstring
   27BDFFE0 AFBF001C AFB00018 00808021 00002021 3C059D00 24A50048 27A60010
   0411FFEF 00000000 8FA40010 3C029D00 8C42002C 0040F809 02042021 8FBF001C
   8FB00018 03E00008 27BD0020
   'p_int
   27BDFFA0 AFBF005C AFB00058 00803821 3C109D00 AFA50010 8E020030 27A40018
   00E03021 0040F809 00073FC3 8E02002C 0040F809 27A40018 8FBF005C 8FB00058
   03E00008 27BD0060
   'p_float
   27BDFFD0 AFBF002C AFB00028 00801821 00A04821 00C04021 7C073C20 3C109D00
   AFA70010 8E020034 27A40018 00602821 01203021 0040F809 01003821 8E02002C
   0040F809 27A40018 8FBF002C 8FB00028 03E00008 27BD0030
   'main
   27BDFFC8 AFBF0034 AFB70030 AFB6002C AFB50028 AFB40024 AFB30020 AFB2001C
   AFB10018 AFB00014 8CB60000 3C119D00 262403C0 0411FFB7 00000000 3C049D00
   248403C4 0411FFB3 00000000 02C02021 2405000A 0411FFC2 00000000 262403C0
   0411FFAC 00000000 00168A00 3C029D00 8C42001C 02C02021 0040F809 24050005
   3C02BF80 8C575A30 24030001 AC435A30 24030003 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 7E233C00 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 7E313A00 AC515A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 AC405A20 3C03BF80 8C625A10 30420080
   1040FFFD 3C02BF80 8C425A20 24140010 3C11BF80 3C129D00 265203D8 3C159D00
   1000004A 26B503C0 AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20
   321000FF 02002021 24050010 0411FF84 00000000 02402021 0411FF6E 00000000
   AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20 321000FF 02002021
   24050010 0411FF76 00000000 02402021 0411FF60 00000000 02402021 0411FF5D
   00000000 AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20 321000FF
   02002021 24050010 0411FF65 00000000 02402021 0411FF4F 00000000 AE305A20
   8E225A10 30420080 1040FFFD 00000000 8E305A20 321000FF 02002021 24050010
   0411FF57 00000000 02402021 0411FF41 00000000 02402021 0411FF3E 00000000
   02402021 0411FF3B 00000000 2673FFFF 1660FFBD 02A02021 0411FF36 00000000
   2694FFFF 52800003 3C109D00 1000FFB6 24130004 260403C0 0411FF2E 00000000
   260403C0 0411FF2B 00000000 3C029D00 8C42001C 02C02021 0040F809 24050006
   3C02BF80 AC575A30 8FBF0034 8FB70030 8FB6002C 8FB50028 8FB40024 8FB30020
   8FB2001C 8FB10018 8FB00014 03E00008 27BD0038
   '.rodata
   'nl
   00000A0D
   'header
   2E200A0D 2E2E2E2E 50202E2E 20656761 00000000
   'sp
   00000020
End CSub





FUNCTION putS(index$ as string,value$ as STRING ) AS INTEGER
 Local String indw$,indr$
 LOCAL INTEGER j=lastpage-200
 indw$=index$+STRING$(255-len(index$),CHR$(255))

 putS=0
 do
   readpage(j,indr$,chipselectpin%)  
   IF indr$=indw$ THEN
      IF value$="" THEN
          rewritepage(j+100, STRING$(255,CHR$(255)),chipselectpin%)
          rewritepage(j,STRING$(255,CHR$(255)),chipselectpin%)
      ELSE
         rewritepage(j+100, value$+STRING$(255-len(value$),CHR$(255)),chipselectpin%)
      END IF
      EXIT DO
   ELSE IF indr$=STRING$(255,CHR$(255)) THEN
     rewritepage(j,indw$,chipselectpin%)
     rewritepage(j+100, value$+STRING$(255-len(value$),CHR$(255)),chipselectpin%)
     '  ? "new",index$,j
     EXIT DO
   END IF  
   j=j+1
   if j>lastpage-100 THEN
     putS=1
     EXIT DO
   END IF
 LOOP
END FUNCTION

FUNCTION getS(index$ as string) AS STRING
 Local String indv$,indr$ ,indw$
 LOCAL INTEGER j=lastpage-200 ,p
 indw$=index$+STRING$(255-len(index$),CHR$(255))
 getS=""
 do
   readpage(j,indr$,chipselectpin%)  
   IF indr$=indw$ THEN
      readpage(j+100,indv$,chipselectpin%)
      p=instr(indv$,CHR$(255))
      if p > 0 then  getS=LEFT$(indv$,p-1) ELSE getS=indv$ ENDIF  
      EXIT DO
   END IF  
   j=j+1
   if j>lastpage-100 THEN
      getS="" : EXIT DO  
   END IF
 LOOP
END FUNCTION





'****************************************  
'
'
sub initchip(eraseit as integer, cspin as integer)
 local STRING d$ length 10
 local integer i=getpagecount(d$,cspin)*256
    print "JEDEC ID = ",d$
    print "F_CS = ",cspin
    print "Memory size is ",i\131072," Mbits"
    print "Memory size is ",(i\131072)\8," MBytes"
    print "Valid Page Nos.  0 - ",(i\256)-1, " each 256 Bytes"
    lastpage=i-1
 if eraseit then
    print "erasing....."
   if not (erasechip(i,chipselectpin%)) then  
     print "erase failed"  
     end  
   endif
   
   print "Erase complete"
   
 endif
end sub



CFunction getpagecount
   00000000
   27BDFFC8 AFB30028 AFBF0034 AFB50030 AFB4002C AFB20024 AFB10020 AFB0001C
   8CB10000 3C029D00 8C420088 00111880 00621021 8C420000 24030008 10430007
   00809821 3C029D00 8C420010 02202021 24050008 0040F809 00003021 3C02BF81
   8C44F220 3C029D00 8C430088 3C020580 7C84D800 3442B053 00821026 24050014
   24040030 00A2200B 00831021 8C430000 24020065 1062006F 3C02BF81 8C45F220
   3C030580 3C029D00 8C420010 3463B053 7CA5D800 00A32826 24040005 2403000C
   0065200A 00003021 0040F809 24050008 3C02BF81 8C45F220 3C030580 3C029D00
   8C420010 3463B053 7CA5D800 00A32826 24040005 2403000C 0065200A 00003021
   0040F809 24050064 3C02BF81 8C45F220 3C030580 3C029D00 8C420010 3463B053
   7CA5D800 00A32826 2404002F 2403000B 0065200A 00003021 0040F809 24050002
   3C02BF81 8C45F220 3C030580 3C029D00 8C420010 3463B053 7CA5D800 00A32826
   2404002F 2403000B 0065200A 00003021 0040F809 24050064 3C02BF81 8C45F220
   3C030580 3C029D00 8C420010 3463B053 7CA5D800 00A32826 24040004 2403000A
   0065200A 00003021 0040F809 24050008 3C02BF81 8C45F220 3C030580 3C029D00
   8C420010 3463B053 7CA5D800 00A32826 24040004 2403000A 0065200A 00003021
   0040F809 24050064 3C02BF81 8C43F220 3C020580 3442B053 7C63D800 1462000C
   3C03BF81 8C64FA90 24050001 3C02BF81 7CA41804 AC64FA90 8C43FCA0 24040006
   7C831804 AC43FCA0 1000000B 3C029D00 8C64FA90 24050007 3C02BF81 7CA41804
   AC64FA90 8C43FC9C 24040006 7C831804 AC43FC9C 3C029D00 8C42001C 02202021
   0040F809 24050006 3C02BF80 34038060 24040C00 AC435A00 AC445A40 24040001
   AC445A30 3C03BF80 AC405A20 8C625A10 30420080 1040FFFD 3C029D00 8C42001C
   3C10BF80 02202021 24050005 8E125A20 0040F809 00000000 2402009F AE025A20
   3C03BF80 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 3C03BF80 AC405A20
   8C625A10 30420080 1040FFFD 3C02BF80 8C505A20 3C03BF80 AC405A20 8C625A10
   30420080 1040FFFD 3C02BF80 8C555A20 3C03BF80 AC525A20 8C625A10 30420080
   1040FFFD 3C129D00 8E42001C 3C03BF80 02202021 24050006 8C745A20 0040F809
   00108200 24020010 AFA20010 02158021 8E420030 00108200 02148021 26640001
   02003021 0040F809 00103FC3 3C02FF40 3442D9BF 02021021 24030006 2C420002
   10400027 A2630000 3C029D00 8C42001C 02202021 0040F809 24050005 24030006
   3C02BF80 AC435A20 3C03BF80 8C625A10 30420080 1040FFFD 3C129D00 8E42001C
   3C13BF80 02202021 24050006 8E635A20 0040F809 00000000 8E42001C 02202021
   0040F809 24050005 24020098 AE625A20 3C03BF80 8C625A10 30420080 1040FFFD
   3C029D00 8C42001C 3C03BF80 02202021 24050006 8C635A20 0040F809 00000000
   3C0200BF 24422642 24044000 12020012 00002821 3C0200BF 24422602 1202000E
   3C0200BF 24422641 1202000B 24042000 3C0200BF 24422601 12020006 2694FFF8
   24020001 0282A004 02802021 10000002 00142FC3 00002821 8FBF0034 00801021
   00A01821 8FB50030 8FB4002C 8FB30028 8FB20024 8FB10020 8FB0001C 03E00008
   27BD0038
End CFunction
'

'
CFunction erasechip
   00000000
   27BDFFD8 AFB40020 AFB00010 AFBF0024 AFB3001C AFB20018 AFB10014 8CB30000
   3C029D00 8C42001C 24030001 3C10BF80 AE035A30 0080A021 24050005 0040F809
   02602021 24020006 AE025A20 3C03BF80 8C625A10 30420080 1040FFFD 3C109D00
   8E02001C 3C11BF80 02602021 24050006 8E235A20 0040F809 00000000 8E02001C
   02602021 0040F809 24050005 240200C7 AE225A20 3C03BF80 8C625A10 30420080
   1040FFFD 3C029D00 8C42001C 02602021 24050006 3C03BF80 8C635A20 0040F809
   3C119D00 3C10BF80 8E220004 0040F809 3404C350 8E22001C 02602021 0040F809
   24050005 24020005 AE025A20 8E025A10 30420080 1040FFFD 00000000 8E025A20
   AE125A20 8E025A10 30420080 1040FFFD 00000000 8E125A20 8E22001C 02602021
   7C129420 0040F809 24050006 32420001 5440FFE6 8E220004 3C029D00 8C42001C
   02602021 0040F809 24050005 24030003 3C02BF80 AC435A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C435A20 3C03BF80 AC405A20 8C625A10 30420080
   1040FFFD 3C02BF80 8C435A20 3C03BF80 AC405A20 8C625A10 30420080 1040FFFD
   3C02BF80 8C435A20 3C03BF80 AC405A20 8C625A10 30420080 1040FFFD 00000000
   8E820004 3C03BF80 8C635A20 5C400006 3C02BF80 14400014 3C029D00 8E820000
   10400010 3C02BF80 AC525A20 3C03BF80 8C625A10 30420080 1040FFFD 3C029D00
   8C42001C 02602021 24050006 3C03BF80 8C635A20 0040F809 00000000 10000007
   00001021 3C029D00 8C42001C 02602021 0040F809 24050006 24020001 8FBF0024
   8FB40020 8FB3001C 8FB20018 8FB10014 8FB00010 03E00008 27BD0028
End CFunction
'
CSUB writepage
   00000000
   27BDFFD8 AFB3001C AFB10014 AFB00010 AFBF0024 AFB40020 AFB20018 8CD30000
   3C029D00 8C42001C 8C940000 24030001 3C10BF80 AE035A30 00A08821 02602021
   0040F809 24050005 24020006 0014A200 AE025A20 3C03BF80 8C625A10 30420080
   1040FFFD 3C109D00 8E02001C 3C12BF80 02602021 24050006 8E435A20 0040F809
   00000000 8E02001C 02602021 0040F809 24050005 24020002 AE425A20 3C03BF80
   8C625A10 30420080 1040FFFD 3C02BF80 7E843C00 8C435A20 3C03BF80 AC445A20
   8C625A10 30420080 1040FFFD 3C02BF80 7E943A00 8C435A20 3C03BF80 AC545A20
   8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 3C03BF80 AC405A20 8C625A10
   30420080 1040FFFD 3C02BF80 8C425A20 00008021 3C03BF80 24040100 02301021
   80420000 AC625A20 8C625A10 30420080 1040FFFD 00000000 26100001 8C625A20
   1604FFF7 02301021 3C029D00 8C42001C 02602021 0040F809 24050006 3C129D00
   3C11BF80 8E420004 0040F809 24040064 8E42001C 02602021 0040F809 24050005
   24020005 AE225A20 8E225A10 30420080 1040FFFD 00000000 8E225A20 AE305A20
   8E225A10 30420080 1040FFFD 00000000 8E305A20 8E42001C 02602021 0040F809
   24050006 32020001 5440FFE7 8E420004 8FBF0024 8FB40020 8FB3001C 8FB20018
   8FB10014 8FB00010 03E00008 27BD0028
End CSUB
'
CSUB readpage
   00000000
   27BDFFD8 AFB3001C AFB20018 AFB10014 AFBF0024 AFB40020 AFB00010 8CD20000
   3C029D00 8C42001C 8C940000 24030001 3C13BF80 AE635A30 00A08821 02402021
   0040F809 24050005 24020003 0014A200 AE625A20 3C03BF80 8C625A10 30420080
   1040FFFD 3C02BF80 7E843C00 8C435A20 3C03BF80 AC445A20 8C625A10 30420080
   1040FFFD 3C02BF80 7E943A00 8C435A20 3C03BF80 AC545A20 8C625A10 30420080
   1040FFFD 3C02BF80 8C435A20 3C03BF80 AC405A20 8C625A10 30420080 1040FFFD
   3C02BF80 8C425A20 00002021 3C03BF80 24050100 AC705A20 8C625A10 30420080
   1040FFFD 00000000 8C705A20 02241021 24840001 1485FFF7 A0500000 3C029D00
   8C42001C 02402021 0040F809 24050006 8FBF0024 8FB40020 8FB3001C 8FB20018
   8FB10014 8FB00010 03E00008 27BD0028
End CSUB
'
CSUB rewritepage
   00000000
   27BDFFC0 AFBF003C AFB70034 AFB5002C AFB40028 AFB30024 AFB20020 AFB1001C
   AFBE0038 3C119D00 AFB60030 AFB00018 8E22003C 00809021 24041000 8CD30000
   0040F809 00A0A021 8E430000 0040B821 8E22001C 24040001 3C11BF80 3C1500FF
   00031A00 AE245A30 24050005 02602021 36B5F000 30720FFF 0040F809 0075A824
   24020003 AE225A20 3C02BF80 8C435A10 30630080 1060FFFD 0015B402 3C02BF80
   8C435A20 3C03BF80 AC565A20 8C625A10 30420080 1040FFFD 0015F203 3C02BF80
   33DE00FF 8C435A20 3C03BF80 AC5E5A20 8C625A10 30420080 1040FFFD 3C02BF80
   32A300FF AFA30010 8FA40010 8C435A20 3C03BF80 AC445A20 8C625A10 30420080
   1040FFFD 3C02BF80 8C425A20 02E08821 26E51000 02E02021 3C03BF80 AC705A20
   8C625A10 30420080 1040FFFD 00000000 8C705A20 A0900000 24840001 1485FFF7
   26420100 0242102A 10400008 26420100 02E21021 02F29021 92830000 A2430000
   26520001 1642FFFC 26940001 3C129D00 8E42001C 02602021 0040F809 24050006
   8E42001C 02602021 0040F809 24050005 24030006 3C02BF80 AC435A20 8C435A10
   30630080 1060FFFD 3C129D00 8E42001C 3C14BF80 02602021 24050006 8E835A20
   0040F809 00000000 8E42001C 02602021 0040F809 24050005 24020020 AE825A20
   3C02BF80 8C435A10 30630080 1060FFFD 00000000 3C02BF80 8C435A20 3C03BF80
   AC565A20 8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 3C03BF80 AC5E5A20
   8C625A10 30420080 1040FFFD 8FA40010 3C02BF80 8C435A20 3C03BF80 AC445A20
   8C625A10 30420080 1040FFFD 3C029D00 8C42001C 02602021 24050006 3C03BF80
   8C635A20 0040F809 3C149D00 3C12BF80 8E820004 0040F809 24040064 8E82001C
   02602021 0040F809 24050005 24020005 AE425A20 8E425A10 30420080 1040FFFD
   00000000 8E425A20 AE505A20 8E425A10 30420080 1040FFFD 00000000 8E505A20
   8E82001C 02602021 0040F809 24050006 32020001 5440FFE7 8E820004 26BE1000
   02BE102A 1040005E 02A0B021 3C129D00 3C10BF80 24150006 8E42001C 02602021
   0040F809 24050005 AE155A20 8E025A10 30420080 1040FFFD 02602021 8E42001C
   02A02821 8E035A20 0040F809 00000000 8E42001C 02602021 0040F809 24050005
   24020002 AE025A20 8E025A10 30420080 1040FFFD 7EC23C00 8E035A20 AE025A20
   8E025A10 30420080 1040FFFD 7EC23A00 8E035A20 AE025A20 8E025A10 30420080
   1040FFFD 32C200FF 8E035A20 AE025A20 8E025A10 30420080 1040FFFD 00000000
   8E025A20 26230100 92220000 AE025A20 8E025A10 30420080 1040FFFD 00000000
   26310001 8E025A20 5623FFF8 92220000 8E42001C 02602021 0040F809 02A02821
   24140100 8E420004 0040F809 24040064 8E42001C 02602021 0040F809 24050005
   24020005 AE025A20 8E025A10 30420080 1040FFFD 00000000 8E025A20 AE145A20
   8E025A10 30420080 1040FFFD 00000000 8E145A20 8E42001C 02602021 0040F809
   02A02821 32820001 5440FFE7 8E420004 26D60100 02DE102A 5440FFA8 8E42001C
   3C029D00 8C420044 0040F809 02E02021 8FBF003C 8FBE0038 8FB70034 8FB60030
   8FB5002C 8FB40028 8FB30024 8FB20020 8FB1001C 8FB00018 03E00008 27BD0040
End CSUB



''
'sub setpagewritten(pageno as integer, cspin as integer) 'set a page as partially or completely written
'  local integer buff(31),i
'  local integer mappage=pageno\2048 'we have 2048 bits per page
'  local integer wordno=(pageno-mappage*2048)\64 'locate the word in the page
'  local integer bitno= 1<<(pageno mod 64) 'locate the bit in the word in the page
'  readpage(mappage,buff(),cspin)
'  buff(wordno) =buff(wordno) XOR bitno
'  writepage(mappage,buff(),cspin)
'end sub
''
CFunction getnextfreepage
   00000000
   27BDFEC8 AFB7012C AFBF0134 AFBE0130 AFB60128 AFB50124 AFB40120 AFB3011C
   AFB20118 AFB10114 AFB00110 8C830004 8C820000 8CB60000 000327C3 308407FF
   00821021 0044B82B 02E3B821 000212C2 0017BD40 02E2B825 24030001 3C02BF80
   AC435A30 1AE00048 0000A021 3C159D00 3C10BF80 241E0003 27B20110 24130020
   8EA2001C 02C02021 0040F809 24050005 00141A00 AE1E5A20 8E025A10 30420080
   1040FFFD 7C623C00 8E045A20 AE025A20 8E025A10 30420080 1040FFFD 7C623A00
   8E045A20 AE025A20 8E025A10 30420080 1040FFFD 00000000 306300FF 8E025A20
   AE035A20 8E025A10 30420080 1040FFFD 00000000 8E025A20 27A30010 AE115A20
   8E025A10 30420080 1040FFFD 00000000 8E115A20 7C118C20 A0710000 24630001
   1472FFF6 02C02021 8EA2001C 0040F809 24050006 8FA20010 8FA30014 00431025
   14400012 00002021 27A20018 24040001 8C430000 8C450004 00651825 1460000B
   24420008 24840001 5493FFFA 8C430000 26940001 0297102A 5440FFC2 8EA2001C
   10000002 24040100 00002021 27A30010 000410C0 00621021 8C460000 8C450004
   30C30001 14600011 00001021 24020001 00055840 240A0040 00024827 00461806
   012B4804 30480020 00453807 01231825 00E8180B 30630001 54600005 0014A140
   24420001 144AFFF5 00024827 0014A140 02842021 8FBF0134 00042180 00441021
   00021FC3 8FBE0130 8FB7012C 8FB60128 8FB50124 8FB40120 8FB3011C 8FB20118
   8FB10114 8FB00110 03E00008 27BD0138
End CFunction

Latest F4 Latest H7 FotS
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 971
Posted: 04:30am 12 Jun 2020
Copy link to clipboard 
Print this post

The  source for the CFunction and CSUB is below.


/*******************************************************************************
*
* MMBasic CFunction to save an image displayed on an SSD1963 onto flash chip
* which has been fitted to the unpopulated footprint of the SSD1963
* screen.
* acknowledgement to Peter Mather for various CFunctions for SSD1963
* and flash chips which have be used to provide many of the routines used.

* When Generating the CFunction, use MERGE CFunction mode, and name the CFunction
* SaveImageRLE
*
* Entry point is function
* long long main(long long *x, long long *y, long long *width, long long *height,
* long long *address,long long *cspin )
*
* x,y,width and height defined the area of interest. 0,0,800,480 for the full screen
* address is the page number to start writing to the flash chip.
* cspin is the chip select pin allocated for the flash chip. (F_CS) 58 on an E100
*
* The value returned is the next available page on the flash chip after the image
* is saved. You need to manage the layout of the chip manually if you are storing
* multiple images.
*
* The image is stored using the following method.
* The 3 bytes used to define each RGB888 pixel are reduced to 2 bytes encoded
* as RGB565 ie. RRRRRGGG GGGBBBBB
* This is then stored using Run Length Encoding (RLE). Each pixel is stored as
* its two byte RGB565 code, unless a run of two or more identical pixel are detected.
* In this case only the first two of these identical pixel are written,
* a count is then made of the number of identical pixel beyond the first two.
* This count is then recorded using 1,2 or 3 bytes a detailed below.
*
* If count <128 then a single Byte is used ie.0XXX XXXX B7=0 and B(6)-B(0)
* contain the value.
* If count < 16384 then two bytes are used. Byte 0 has  B7=1 in to indicate
* an addition Byte is required. i.e.
* Byte 0 is 1XXX XXXX and Byte 1 has  B7=0 is 0XXX XXXX .This leaves 14 bits
* to store the counter.
* For a counter of > 16383 then three bytes are used. B7=1 for  Byte 1 indicating
* another byte is required. ie. 1XXX XXXX     1XXX XXXX   XXXX XXXX    
* All eight bits of Byte 2 are used to store the value, giving a total of 22 bits.
*
* This method of encoding is very effective when there are runs of the same pixel.
* e.g. A full screen of the same colour is stored in 7 bytes.

*
* V1.0     2020-06-11 Gerry Allardice
*
******************************************************************************/
//#define debugging       // comment out on final version

#define Version 100     //Version 1.0
#include <stdarg.h>
#include <xc.h>   // Required for SFR defs
#include <sys/attribs.h>   // Required to use __longramfunc__
#include "../CFunctions.h"


//#define PINS64 //E64 driver Comment out for compilation for 100-pin part
#define PINS100 //E100 driver Comment out for compilation for 64-pin part

#define BITS8
//#define BITS16

#define bclrport *(volatile unsigned int *)(0xbf886134) //latch registers
#define bsetport *(volatile unsigned int *)(0xbf886138) //latch registers
#define cport *(volatile unsigned int *)(0xbf886230) //latch registers
#define cread *(volatile unsigned int *)(0xbf886220) //latch registers
#define ctrisinv *(volatile unsigned int *)(0xbf88621C) //latch registers
#define cclrport *(volatile unsigned int *)(0xbf886234) //latch registers
#define csetport *(volatile unsigned int *)(0xbf886238) //latch registers
#define eport *(volatile unsigned int *)(0xbf886430) //latch registers
#define eread *(volatile unsigned int *)(0xbf886420) //latch registers
#define etrisinv *(volatile unsigned int *)(0xbf88641C) //latch registers
#define eclrport *(volatile unsigned int *)(0xbf886434) //latch registers
#define esetport *(volatile unsigned int *)(0xbf886438) //latch registers
#define DEVID (*(volatile unsigned int *)0xBF80F220)

#define writeenable 0x06
#define pageprogram 0x02
#define writestatus1 0x01
#define readstatus1 0x05
#define readdata 0x03
#define fastread 0x0B
#define sectorerase 0x20  // 4K 16 pages
#define blockerase 0x52   // 32K 128 pages
#define block2erase 0xD8  //64K 256 pages
#define eraseall 0xC7
#define JEDEC 0x9F
#define SPIsend(a) {int j;SPIBUF=a; while((SPISTAT & 0x80)==0); j=SPIBUF;}
#define SPIread(a) {SPIBUF=a; while((SPISTAT & 0x80)==0); a=SPIBUF;}
//#define SPISTAT *(volatile unsigned int *)(0xbf805810) //SPI status register
//#define SPIBUF *(volatile unsigned int *)(0xbf805820)  //SPI output buffer

#define SPICON *(volatile unsigned int *)(0xbf805A00)               //SPI2 control register #1
#define SPICON2 *(volatile unsigned int *)(0xbf805A40)              //SPI2 control register #2
#define SPISTAT *(volatile unsigned int *)(0xbf805A10)              //SPI2 status register
#define SPISTATCLR *(volatile unsigned int *)(0xbf805A14)           //SPI1 status clear register
#define SPIBRG *(volatile unsigned int *)(0xbf805A30)               //SPI2 speed register
#define SPIBUF *(volatile unsigned int *)(0xbf805A20)               //SPI2 output buffer

//Offsets into the persistent RAM of variables
#ifdef PINS64
   #define RS_Pin_No 27
   #define WR_Pin_No 24
   #define RS_Pin 0x1000   //bit 13 mask
   #define WR_Pin 0x0800   //bit 11 mask
   #define clrport bclrport
   #define setport bsetport
   #define port eport
   #define read eread
   #define trisinv etrisinv
   #define RSLo    {clrport=RS_Pin;}
   #define RSHi    {setport=RS_Pin;}
   #define WRLo    {clrport=WR_Pin;}
   #define WRHi    {setport=WR_Pin;}
   #define RDLo    (*(volatile unsigned int *)RDclrport)=RDpin
   #define RDHi    (*(volatile unsigned int *)RDsetport)=RDpin

#endif

#ifdef PINS100
  //E100 Board
   #define F_CS 58         // flashchip CS
   #define RS_Pin_No 18    //RE8
   #define WR_Pin_No 19    //RE9
   #define RD_Pin_No 6     // Pin 6/RC1 E100//if not used tie to 3.3v  //RB15 pIN 30
   #define RS_Pin 0x0100    //b8 portE
   #define WR_Pin 0x0200    //b9 portE
   #define RD_Pin 0x0002    //b1 portc

   #define clrport bclrport
   #define setport bsetport
   #define port eport
   #define read eread  
   
   #define trisinv etrisinv
     
   #define RSLo    eclrport=RS_Pin
   #define RSHi    esetport=RS_Pin
   #define WRLo    eclrport=WR_Pin
   #define WRHi    esetport=WR_Pin
   #define RDLo    cclrport=RD_Pin
   #define RDHi    csetport=RD_Pin
  // #define RDTog   RDLo;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;RDHi;
   #define RDTog   RDLo;n=DEVID;n=DEVID;RDHi;
   #define WRTog   WRLo;WRHi;
   #define WRTog3  WRLo;WRHi;WRLo;WRHi;WRLo;WRHi;

  // #define CLKLo   bclrport=RD_Pin;
  // #define CLKHi   bsetport=RD_Pin;
  // #define WRTog   WRLo; n=DEVID; WRHi;
  // #define WRTog   WRLo; n=DEVID;n=DEVID;WRHi;


#endif

#define Both WR_Pin | RS_Pin


#define LANDSCAPE       1
#define PORTRAIT        2
#define RLANDSCAPE      3
#define RPORTRAIT       4

#ifdef debugging
//Function that gets our address offset so we dont need to pass it in.
__attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c)
    {
        *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ;
    }


void pstring(const char *s){
   volatile unsigned int libAddr ;
   getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor
   getFPCLab: { }
   unsigned char  * testData    = (unsigned char *)((void *)s + libAddr );
   MMPrintString(testData);
}

void p_int(int a,int base){
   char b[64];
   IntToStr(b,a,base);
   MMPrintString(b);
}
void p_float(float a,int m, int n, char c){
// m is the nbr of chars before the decimal point
// n is the nbr chars after the point
// ch is the leading pad char
   char b[14];
   FloatToStr(b,a, m, n ,c);
   MMPrintString(b);
}
#endif



/*******************************************************************************
*
* Write Data to a register on the Chip
*
******************************************************************************/
void write_command_data(unsigned int command, int data, ...){
  int i;
  RSLo;
  va_list ap;
  va_start(ap, data);
  port=(command & 0x00FF) | WR_Pin;  WRLo;    WRHi; // RS low
  RSHi;
  for(i = 0; i < data; i++) {
      port= (char)va_arg(ap, int) | Both;  WRLo;    WRHi; //RS high
  }
  va_end(ap);
}
/*******************************************************************************
*
* defines start/end coordinates for memory access from host to SSD1963
* also maps the start and end points to suit the orientation
*
*******************************************************************************/
void defineregion(long x, long y, long width,long height){ //SSD1963
   long x1=x,x2=x+width-1,y1=y,y2=y+height-1;
   unsigned long xstart,xend,ystart,yend,Vertical,Horizontal;

       RSLo;
       if(HRes>VRes){
       Vertical=VRes;
       Horizontal=HRes;
   }
   else {
       Vertical=HRes;
       Horizontal=VRes;
   }
    if(Option->DISPLAY_ORIENTATION!=LANDSCAPE)goto isP;
             xstart = x1;
             xend = x2;
             ystart = y1;
             yend = y2;
             if(Option->LCD_CD>6){ //reverse for 7" displays
               xstart = (Horizontal - 1) - x2;
               xend = (Horizontal - 1) - x1;
             }
             goto setreg;
    isP:        
    if(Option->DISPLAY_ORIENTATION!=PORTRAIT)goto isRL;
             xstart = y1;
             xend = y2;
             ystart = (Vertical - 1) - x2;
             yend = (Vertical - 1) - x1;
             goto setreg;
   isRL:
   if(Option->DISPLAY_ORIENTATION!=RLANDSCAPE)goto isRP;
             xstart = (Horizontal - 1) - x2;
             xend = (Horizontal - 1) - x1;
             ystart = (Vertical - 1) - y2;
             yend = (Vertical - 1) - y1;
             if(Option->LCD_CD>6){//reverse for 7" displays
               xstart = x1;
               xend = x2;
             }
             goto setreg;
    isRP:
             xstart = (Horizontal - 1) - y2;
             xend = (Horizontal - 1) - y1;
             ystart = x1;
             yend = x2;
   setreg:
   port=0x22A ;WRLo;    WRHi; // RS low
   RSHi;
   port=(xstart>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xstart) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xend>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xend) | Both;  WRLo;    WRHi; // RS HIGH
   RSLo;
   port=0x22B ;  WRLo;    WRHi; // RS low
   RSHi;
   port=(ystart>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(ystart) | Both;  WRLo;    WRHi; // RS HIGH
   port=(yend>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(yend) | Both;  WRLo;    WRHi; // RS HIGH    RSHi;
}




/*******************************************************************************
*
* Read full colour RGB888 image displayed on SSD1963 and store it as RGB565 with RLE (Run Length Encoding)
* on flash chip.
******************************************************************************/


long long main(long long *x, long long *y, long long *w, long long *h,long long *address,long long *cspin ){    
   int x1=*x,y1=*y,width=*w,height=*h;  
   int k=0,add,m,pin=*cspin;
   long pageno=*address;
   long i,j=0,z=0;
   unsigned long pixel1,pixel2,firstpixel=0,pcounter=0,rle=0;
   long n; //Used in RTog macro -don't reuse for anything else or it will take a while to find what you did!!!!!!!
   
   unsigned long fhb,fmb, flb, f565h,f565l; //32 bits
   unsigned char *p;
   char q;
 
      //Keep with screen boundaries
      if(x1 < 0) x1 = 0; if(x1 >= HRes) x1 = HRes - 1;
      if(width < 0) width = 0; if(width > (HRes-x1)) width = HRes - x1;
      if(y1 < 0) y1 = 0; if(y1 >= VRes) y1 = VRes - 1;
      if(height < 0) height = 0; if(height > (VRes-y1)) height = VRes - y1;
       
      i=width*height*3; //Number of bytes. 3 per pixel
       p=GetMemory(262); //allocate some temporary memory
       defineregion(x1,y1,width,height);
       RSLo;
       port=0x22E ;  WRLo;    WRHi; // RS low
       RSHi;
       trisinv=0xFF; //set pins to read
       //do { //read in the screen area to be save to flash
         while (i--) {
           z++;  
           if (z==1){
             RDTog  
             fhb=(read & 0xF8);
           }
           if (z==2){
             RDTog
             fmb=(read & 0xFC);
             f565h=(fhb & 0b11111000) | ((fmb>>5)& 0b00000111);
           }
           if (z==3){
              RDTog
              flb=(read & 0xF8);
              f565l=((fmb<<3)& 0b11100000) | ((flb>>3)& 0b00011111);
             
             if (firstpixel==0){ //special case for first pixel
              // x++;  
               firstpixel=1;
               pixel1=(f565h<<8)|f565l;
               p[j++]=f565h;
               p[j++]=f565l;
             }else{
               //subsequent pixels -  pixel1 is populated
               pixel2=(f565h<<8)|f565l;
               if ((pixel1==pixel2) && (i!=0)) {
                   //in run length counting
                   if (rle==1){
                     pcounter++;
                   }
                   if (rle==0){
                     rle=1;
                    //write the second pixel
                     p[j++]=f565h;
                     p[j++]=f565l;
                   }  
                   //pixel1=pixel2;
                   //w++;
                }else{
                  // y++;
                   
                    //out of run length count
                   if (rle==1){
                      rle=0;
                      if ((pixel1==pixel2) && (i==0)){pcounter++; } //add one to count if at end
                     // write the count
                      if (pcounter<128) { // 1byte
                       p[j++]=pcounter;
                      }else if(pcounter<16384){ //2 bytes
                       p[j++]=((pcounter>>7)& 0b01111111)| 0b10000000;
                       p[j++]=(pcounter  & 0b01111111) ;
                      }else{  //three bytes
                       p[j++]=((pcounter>>15)& 0b01111111)| 0b10000000;
                       p[j++]=((pcounter>>8)& 0b01111111)| 0b10000000;
                       p[j++]=(pcounter  & 0b11111111) ;  
                      }
                   
                      pcounter=0;
                      //write the new pixel if not counter as RLE
                      if (pixel1!=pixel2){
                        p[j++]=f565h;
                        p[j++]=f565l;
                      }
                      pixel1=pixel2;
                   }else{ //just a non matching pixel, no RLE in play
                          // or can be end and possible matching pixel
                      p[j++]=f565h;
                      p[j++]=f565l;  
                     // special case of matching pixel as last pixel
                      // need to write counter
                      if ((pixel1==pixel2) && (i==0)){
                         p[j++]=pcounter;  
                      }
                      pixel1=pixel2;
                   }
                 
                }
                   
                 
              } // end firstpixel else
             } //end  z=3
           
           
           //Write the page to flash if we have 256 bytes
           if (j>255){
               k=0;
               add=(pageno<<8); //convert page number to byte number
               PinSetBit(pin,LATCLR);
               SPIsend(writeenable);
               PinSetBit(pin,LATSET);
               PinSetBit(pin,LATCLR);
               SPIsend(pageprogram);
               SPIsend((add>>16) & 0xFF);
               SPIsend((add>>8) & 0xFF);
               SPIsend(add & 0xFF);
               for(m=0;m<256;m++) {
                 SPIsend(p[k]);
                 k++;
               }
               PinSetBit(pin,LATSET);
              // uSec(1000);
               do {
                uSec(100);
                PinSetBit(pin,LATCLR);
                SPIsend(readstatus1)
                SPIread(q);
                PinSetBit(pin,LATSET);
               } while(q & 1);
               pageno++;
               if (j==256){
                  j=0;  
               }
                if (j==257){
                  j=0;
                  p[j++]=p[256];
               }
                if (j==258){
                  j=0;
                  p[j++]=p[256];
                  p[j++]=p[257];
               }
                if (j==259){
                  j=0;
                  p[j++]=p[256];
                  p[j++]=p[257];
                  p[j++]=p[258];
               }
                if (j==260){
                  j=0;
                  p[j++]=p[256];
                  p[j++]=p[257];
                  p[j++]=p[258];
                  p[j++]=p[259];
               }
               if (j==261){
                  j=0;
                  p[j++]=p[256];
                  p[j++]=p[257];
                  p[j++]=p[258];
                  p[j++]=p[259];
                  p[j++]=p[260];
               }
                if (j==262){
                  j=0;
                  p[j++]=p[256];
                  p[j++]=p[257];
                  p[j++]=p[258];
                  p[j++]=p[259];
                  p[j++]=p[260];
                  p[j++]=p[261];
               }
               for(m=j;m<262;m++) {
                 p[m]=255;
                 
               }
          }
         
           if (z==3) {
               z=0 ;
           }          
         } //end while  
        //Write last part filled page to flash if required
           if (j>0){
               k=0;
               add=(pageno<<8); //convert page number to byte number
               PinSetBit(pin,LATCLR);
               SPIsend(writeenable);
               PinSetBit(pin,LATSET);
               PinSetBit(pin,LATCLR);
               SPIsend(pageprogram);
               SPIsend((add>>16) & 0xFF);
               SPIsend((add>>8) & 0xFF);
               SPIsend(add & 0xFF);
               for(m=0;m<256;m++) {
                 SPIsend(p[k]);
                 k++;
               }
               PinSetBit(pin,LATSET);
              // uSec(1000);
               do {
                uSec(100);
                PinSetBit(pin,LATCLR);
                SPIsend(readstatus1)
                SPIread(q);
                PinSetBit(pin,LATSET);
               } while(q & 1);
               pageno++;
               j=0;  
          }
       
        trisinv=0xFF; //set pins to write
        FreeMemory(p);
     
     return pageno;
}




/*******************************************************************************
*
* MMBasic CSUB RestoreImageRLE - Restores Run Length Encoded (RLE) file from
* Flash and displays on SSD1963 LCD
* acknowledgement to Peter Mather for various CFunctions for SSD1963
* and flash chips which have be used to provide many of the routines used.

* When Generating the CSUB, use MERGE CSUB mode, and name the CSUB
* RestoreImageRLE
*
* Entry point is function
* void main(long long *x, long long *y, long long *width, long long *height,
* long long *address,long long *cspin )
*
* x,y,width and height defined the area of interest. 0,0,800,480 for the full screen
* the width and height MUST match those used when storing the image, however x and y
* can be different so its restored in a different position.The  area must be with the
* screen boundaries.
* address is the page number to start reading from the flash chip.
* cspin is the chip select pin allocated for the flash chip. (F_CS) 58 on an E100
*
*
* V1.0     2020-06-11 Gerry Allardice

******************************************************************************/
//#define debugging       // comment out on final version

#define Version 100     //Version 1.0
#include <stdarg.h>
#include <xc.h>   // Required for SFR defs
#include <sys/attribs.h>   // Required to use __longramfunc__
#include "../CFunctions.h"




//#define PINS64 //E64 driver Comment out for compilation for 100-pin part
#define PINS100 //E100 driver Comment out for compilation for 64-pin part

#define BITS8
//#define BITS16

#define bclrport *(volatile unsigned int *)(0xbf886134) //latch registers
#define bsetport *(volatile unsigned int *)(0xbf886138) //latch registers
#define cport *(volatile unsigned int *)(0xbf886230) //latch registers
#define cread *(volatile unsigned int *)(0xbf886220) //latch registers
#define ctrisinv *(volatile unsigned int *)(0xbf88621C) //latch registers
#define cclrport *(volatile unsigned int *)(0xbf886234) //latch registers
#define csetport *(volatile unsigned int *)(0xbf886238) //latch registers
#define eport *(volatile unsigned int *)(0xbf886430) //latch registers
#define eread *(volatile unsigned int *)(0xbf886420) //latch registers
#define etrisinv *(volatile unsigned int *)(0xbf88641C) //latch registers
#define eclrport *(volatile unsigned int *)(0xbf886434) //latch registers
#define esetport *(volatile unsigned int *)(0xbf886438) //latch registers
#define DEVID (*(volatile unsigned int *)0xBF80F220)

#define writeenable 0x06
#define pageprogram 0x02
#define writestatus1 0x01
#define readstatus1 0x05
#define readdata 0x03
#define fastread 0x0B
#define sectorerase 0x20  // 4K 16 pages
#define blockerase 0x52   // 32K 128 pages
#define block2erase 0xD8  //64K 256 pages
#define eraseall 0xC7
#define JEDEC 0x9F
#define SPIsend(a) {int j;SPIBUF=a; while((SPISTAT & 0x80)==0); j=SPIBUF;}
#define SPIread(a) {SPIBUF=a; while((SPISTAT & 0x80)==0); a=SPIBUF;}
//#define SPISTAT *(volatile unsigned int *)(0xbf805810) //SPI status register
//#define SPIBUF *(volatile unsigned int *)(0xbf805820)  //SPI output buffer

#define SPICON *(volatile unsigned int *)(0xbf805A00)               //SPI2 control register #1
#define SPICON2 *(volatile unsigned int *)(0xbf805A40)              //SPI2 control register #2
#define SPISTAT *(volatile unsigned int *)(0xbf805A10)              //SPI2 status register
#define SPISTATCLR *(volatile unsigned int *)(0xbf805A14)           //SPI1 status clear register
#define SPIBRG *(volatile unsigned int *)(0xbf805A30)               //SPI2 speed register
#define SPIBUF *(volatile unsigned int *)(0xbf805A20)               //SPI2 output buffer
//#define SPISTAT *(volatile unsigned int *)(0xbf805A10)              //SPI2 status register
//#define SPIBUF *(volatile unsigned int *)(0xbf805A20)               //SPI2 output buffer


//Offsets into the persistent RAM of variables
#ifdef PINS64
   #define RS_Pin_No 27
   #define WR_Pin_No 24
   #define RS_Pin 0x1000   //bit 13 mask
   #define WR_Pin 0x0800   //bit 11 mask
   #define clrport bclrport
   #define setport bsetport
   #define port eport
   #define read eread
   #define trisinv etrisinv
   #define RSLo    {clrport=RS_Pin;}
   #define RSHi    {setport=RS_Pin;}
   #define WRLo    {clrport=WR_Pin;}
   #define WRHi    {setport=WR_Pin;}
   #define RDLo    (*(volatile unsigned int *)RDclrport)=RDpin
   #define RDHi    (*(volatile unsigned int *)RDsetport)=RDpin


#endif
#ifdef PINS100
  //E100 Board
   #define F_CS 58         // flashchip CS
   #define RS_Pin_No 18    //RE8
   #define WR_Pin_No 19    //RE9
   #define RD_Pin_No 6     // Pin 6/RC1 E100//if not used tie to 3.3v  //RB15 pIN 30
   #define RS_Pin 0x0100    //b8 portE
   #define WR_Pin 0x0200    //b9 portE
   #define RD_Pin 0x0002    //b1 portc

   #define clrport bclrport
   #define setport bsetport
   #define port eport
   #define read eread  
   
   #define trisinv etrisinv
 
 
   #define RSLo    eclrport=RS_Pin
   #define RSHi    esetport=RS_Pin
   #define WRLo    eclrport=WR_Pin
   #define WRHi    esetport=WR_Pin
   #define RDLo    cclrport=RD_Pin
   #define RDHi    csetport=RD_Pin
  // #define RDTog   RDLo;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;n=DEVID;RDHi;
   #define RDTog   RDLo;n=DEVID;n=DEVID;RDHi;
   #define WRTog   WRLo;WRHi;
   #define WRTog3  WRLo;WRHi;WRLo;WRHi;WRLo;WRHi;

  // #define CLKLo   bclrport=RD_Pin;
  // #define CLKHi   bsetport=RD_Pin;
  // #define WRTog   WRLo; n=DEVID; WRHi;
  // #define WRTog   WRLo; n=DEVID;n=DEVID;WRHi;


#endif

#define Both WR_Pin | RS_Pin


#define LANDSCAPE       1
#define PORTRAIT        2
#define RLANDSCAPE      3
#define RPORTRAIT       4



#ifdef debugging

//Function that gets our address offset so we dont need to pass it in.

__attribute__((noinline)) void getFPC(void *a, void *b, volatile unsigned int *c)
    {
        *c = (unsigned int) (__builtin_return_address (0) - (b -a)) ;
    }

void pstring(const char *s){
   volatile unsigned int libAddr ;
   getFPC(NULL,&&getFPCLab,&libAddr) ; // warning can be ignored, stupid editor
   getFPCLab: { }
   unsigned char  * testData    = (unsigned char *)((void *)s + libAddr );
   MMPrintString(testData);
}

void p_int(int a,int base){
   char b[64];
   IntToStr(b,a,base);
   MMPrintString(b);
}
void p_float(float a,int m, int n, char c){
// m is the nbr of chars before the decimal point
// n is the nbr chars after the point
// ch is the leading pad char
   char b[14];
   FloatToStr(b,a, m, n ,c);
   MMPrintString(b);
}
#endif


/*******************************************************************************
*
* Write Data to a register on the Chip
*
******************************************************************************/
void write_command_data(unsigned int command, int data, ...){
  int i;
  RSLo;
  va_list ap;
  va_start(ap, data);
  port=(command & 0x00FF) | WR_Pin;  WRLo;    WRHi; // RS low
  RSHi;
  for(i = 0; i < data; i++) {
      port= (char)va_arg(ap, int) | Both;  WRLo;    WRHi; //RS high
  }
  va_end(ap);
}
/*******************************************************************************
*
* defines start/end coordinates for memory access from host to SSD1963
* also maps the start and end points to suit the orientation
*
*******************************************************************************/
void defineregion(long x, long y, long width,long height){ //SSD1963
   long x1=x,x2=x+width-1,y1=y,y2=y+height-1;
   unsigned long xstart,xend,ystart,yend,Vertical,Horizontal;

       RSLo;

       if(HRes>VRes){
       Vertical=VRes;
       Horizontal=HRes;
   }
   else {
       Vertical=HRes;
       Horizontal=VRes;
   }
    if(Option->DISPLAY_ORIENTATION!=LANDSCAPE)goto isP;
             xstart = x1;
             xend = x2;
             ystart = y1;
             yend = y2;
             if(Option->LCD_CD>6){ //reverse for 7" displays
               xstart = (Horizontal - 1) - x2;
               xend = (Horizontal - 1) - x1;
             }
             goto setreg;
    isP:        
    if(Option->DISPLAY_ORIENTATION!=PORTRAIT)goto isRL;
             xstart = y1;
             xend = y2;
             ystart = (Vertical - 1) - x2;
             yend = (Vertical - 1) - x1;
             goto setreg;
   isRL:
   if(Option->DISPLAY_ORIENTATION!=RLANDSCAPE)goto isRP;
             xstart = (Horizontal - 1) - x2;
             xend = (Horizontal - 1) - x1;
             ystart = (Vertical - 1) - y2;
             yend = (Vertical - 1) - y1;
             if(Option->LCD_CD>6){//reverse for 7" displays
               xstart = x1;
               xend = x2;
             }
             goto setreg;
    isRP:
             xstart = (Horizontal - 1) - y2;
             xend = (Horizontal - 1) - y1;
             ystart = x1;
             yend = x2;
   setreg:
   port=0x22A ;WRLo;    WRHi; // RS low
 
       RSHi;
   
   port=(xstart>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xstart) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xend>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(xend) | Both;  WRLo;    WRHi; // RS HIGH
 
       RSLo;
 
   port=0x22B ;  WRLo;    WRHi; // RS low
   
       RSHi;
 
   port=(ystart>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(ystart) | Both;  WRLo;    WRHi; // RS HIGH
   port=(yend>>8 ) | Both;  WRLo;    WRHi; // RS HIGH
   port=(yend) | Both;  WRLo;    WRHi; // RS HIGH    RSHi;
}


/*******************************************************************************
*CSUB RestoreImageRLE Restore RLE RGB565 file from flash and display on SSD1963
*
* *****************************************************************************/

void main(long long *x, long long  *y, long long *w, long long *h,long long *address,long long *cspin){
   int t,m;
   int add,pin=*cspin;
   add=*address<<8; //convert page number to byte number
   int x1=*x,y1=*y,width=*w,height=*h;
   unsigned int brgsave=0;
   unsigned long i,ch,cm,cl;
   unsigned long pixel1,pixel2,firstpixel=0,rle=0;
   unsigned long pcounter=0,pcounter1=0,pcounter2=0,pcounter3=0;
   unsigned char a;
   long j,z;
 
   if(x1 < 0) x1 = 0; if(x1 >= HRes) x1 = HRes - 1;
   if(width < 0) width = 0; if(width > (HRes-x1)) width = HRes - x1;
   if(y1 < 0) y1 = 0; if(y1 >= VRes) y1 = VRes - 1;
   if(height < 0) height = 0; if(height > (VRes-y1)) height = VRes - y1;
 
   i=width*height;
   defineregion(x1,y1,width,height);
   RSLo;
   port=0x22C ;  WRLo;    WRHi; // RS low
   RSHi;
   
     PinSetBit(pin,LATCLR);
     //speed is cpuspeed/2*(BRG+1) ????
     brgsave=SPIBRG;
     SPIBRG=1;
     SPIsend(readdata);
     SPIsend((add>>16) & 0xFF);
     SPIsend((add>>8) & 0xFF);
     SPIsend(add & 0xFF);
   
       
       while (i>0) {
           if (firstpixel==0){ //special case for first pixel
               //x++;  
               firstpixel=1;
               SPIread(ch);
               ch = ch & 0xFF ;  
               SPIread(cl);
               cl = cl & 0xFF ;
               pixel1=(ch<<8)|cl;
               
               cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100);  
               ch= (ch  & 0b11111000) ;
               cl= ((cl << 3) & 0b11111000);  
         
               //write to screen
               i--;
               
               port=ch | Both;    WRLo;    WRHi;
               port=cm | Both;    WRLo;    WRHi;
               port=cl | Both;    WRLo;    WRHi;
             
             
           }else{
                //subsequent pixels  
               SPIread(ch);
               ch = ch & 0xFF ;  
               SPIread(cl);
               cl = cl & 0xFF ;
               pixel2=(ch<<8)|cl;
               cm = ((ch << 5 ) & 0b11100000) | ((cl >> 3) & 0b00011100);  
               ch= (ch  & 0b11111000) ;
               cl= ((cl << 3) & 0b11111000);  
             
               if (pixel1==pixel2) {
                     //read the RLE count and write the second pixel
                     //write repeated pixel to screen
                     i--;
                     port=ch | Both;    WRLo;    WRHi;
                     port=cm | Both;    WRLo;    WRHi;
                     port=cl | Both;    WRLo;    WRHi;
                     // now read the RLE counter
                     SPIread(pcounter1);
                     if (pcounter1<128){
                         pcounter=pcounter1;
                     }else{
                         pcounter1=(pcounter1 & 0b01111111);
                         SPIread(pcounter2);
                         if (pcounter2<128){
                            pcounter=(pcounter1<<7) | pcounter2;
                         }else{
                             pcounter2=(pcounter2 & 0b01111111);
                             SPIread(pcounter3);
                           
                            pcounter=(pcounter1<<15) | (pcounter2 <<8) | pcounter3;
                         }  
                     }
                     
                     while ( pcounter--) {
                        //write repeated pixel to screen
                       i--;  
                       port=ch | Both;    WRLo;    WRHi;
                       port=cm | Both;    WRLo;    WRHi;
                       port=cl | Both;    WRLo;    WRHi;
                     }
                     //start new pixel
                     firstpixel=0;
                 
                }else{
                   
                   //just a non matching pixel, no RLE in play
                       //write to screen
                       i--;
                       port=ch | Both;    WRLo;    WRHi;
                       port=cm | Both;    WRLo;    WRHi;
                       port=cl | Both;    WRLo;    WRHi;
                       pixel1=pixel2;
               }  
               
           }
         
       }
       PinSetBit(pin,LATSET);
       SPIBRG=brgsave;
     
}



Latest F4 Latest H7 FotS
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 971
Posted: 04:37am 12 Jun 2020
Copy link to clipboard 
Print this post

The CSUB PrintFlashPage is a useful utility to use when debugging. It prints a
page from the flash in Hex.

Usage: PrintFlashPage pageno,cspin
where cspin is the CS for the flash chip.


'  File PrintFlashPage.bas  written 12-Jun-2020  14:42:03
'
CSub PrintFlashPage
   00000043
   'getFPC
   27BDFFF8 AFBF0004 00852023 03E42021 ACC40000 8FBF0004 03E00008 27BD0008
   'pstring
   27BDFFE0 AFBF001C AFB00018 00808021 00002021 3C059D00 24A50048 27A60010
   0411FFEF 00000000 8FA40010 3C029D00 8C42002C 0040F809 02042021 8FBF001C
   8FB00018 03E00008 27BD0020
   'p_int
   27BDFFA0 AFBF005C AFB00058 00803821 3C109D00 AFA50010 8E020030 27A40018
   00E03021 0040F809 00073FC3 8E02002C 0040F809 27A40018 8FBF005C 8FB00058
   03E00008 27BD0060
   'p_float
   27BDFFD0 AFBF002C AFB00028 00801821 00A04821 00C04021 7C073C20 3C109D00
   AFA70010 8E020034 27A40018 00602821 01203021 0040F809 01003821 8E02002C
   0040F809 27A40018 8FBF002C 8FB00028 03E00008 27BD0030
   'main
   27BDFFC8 AFBF0034 AFB70030 AFB6002C AFB50028 AFB40024 AFB30020 AFB2001C
   AFB10018 AFB00014 8CB60000 8C920000 3C119D00 262403C4 0411FFB6 00000000
   3C049D00 248403C8 0411FFB2 00000000 02402021 2405000A 0411FFC1 00000000
   262403C4 0411FFAB 00000000 00129200 3C029D00 8C42001C 02C02021 0040F809
   24050005 3C02BF80 8C575A30 24030001 AC435A30 24030003 AC435A20 3C03BF80
   8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E433C00 AC435A20 3C03BF80
   8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 7E523A00 AC525A20 3C03BF80
   8C625A10 30420080 1040FFFD 3C02BF80 8C435A20 AC405A20 3C03BF80 8C625A10
   30420080 1040FFFD 3C02BF80 8C425A20 24140010 3C11BF80 3C129D00 265203DC
   3C159D00 1000004A 26B503C4 AE305A20 8E225A10 30420080 1040FFFD 00000000
   8E305A20 321000FF 02002021 24050010 0411FF83 00000000 02402021 0411FF6D
   00000000 AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20 321000FF
   02002021 24050010 0411FF75 00000000 02402021 0411FF5F 00000000 02402021
   0411FF5C 00000000 AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20
   321000FF 02002021 24050010 0411FF64 00000000 02402021 0411FF4E 00000000
   AE305A20 8E225A10 30420080 1040FFFD 00000000 8E305A20 321000FF 02002021
   24050010 0411FF56 00000000 02402021 0411FF40 00000000 02402021 0411FF3D
   00000000 02402021 0411FF3A 00000000 2673FFFF 1660FFBD 02A02021 0411FF35
   00000000 2694FFFF 52800003 3C109D00 1000FFB6 24130004 260403C4 0411FF2D
   00000000 260403C4 0411FF2A 00000000 3C029D00 8C42001C 02C02021 0040F809
   24050006 3C02BF80 AC575A30 8FBF0034 8FB70030 8FB6002C 8FB50028 8FB40024
   8FB30020 8FB2001C 8FB10018 8FB00014 03E00008 27BD0038
   '.rodata
   'nl
   00000A0D
   'header
   2E200A0D 2E2E2E2E 50202E2E 20656761 00000000
   'sp
   00000020
End CSub



e.g.


> printflashpage 0,58


....... Page 0
FF FF  FF FF   80 D0  4F EF   5D EF  5D 0   FF FF  FF FF
12 EF  5D FF   FF FF  FF 86   16 EF  5D FF   FF FF  FF 86
12 EF  5D FF   FF FF  FF 83   67 EF  5D FF   FF FF  FF 4
EF 5D  EF 5D   0 FF  FF FF   FF 86  F EF   5D EF  5D 1
FF FF  FF FF   82 34  EF 5D   EF 5D  0 FF   FF FF  FF 1
D7 5C  9C D3   7B CE  4A 49   10 A3  0 20   0 20  1 10
A3 31  E9 5B   2C 9C  D3 CE   59 EF  5D FF   FF FF  FF 83
57 EF  5D EF   5D 0  8C 51   6B 4D  31 E9   10 A3  0 20
0 20  2 29   45 52  AA 9C   D3 DE  DB FF   FF FF  FF 1
EF 5D  FF FF   FF FF  82 1F   EF 5D  FF FF   FF FF  0 DE
DB 6B  4D 10   A3 0  20 0   20 B  29 45   6B 4D  BE 38
FF FF  EF 5D   FF FF  FF FF   83 50  EF 5D   BE 38  7B CE
29 45  0 20   0 20  B 29   45 6B  4D CE   59 FF  FF FF
FF 82  1F EF   5D FF  FF CE   59 4A  49 0   20 0  20 0
10 A3  0 20   0 20  D 10   A3 31  A6 DE   DB EF  5D FF
FF FF  FF 83   4E B5  B6 31   E9 0  20 0   20 10  10 A3




Edited 2020-06-12 14:44 by disco4now
Latest F4 Latest H7 FotS
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025