![]() |
Forum Index : Microcontroller and PC projects : V4.7 : MX170 SDCard FAT32 Driver
Page 1 of 3 ![]() ![]() |
|||||
Author | Message | ||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
Hi I have created a driver which enables the PIC32MX170 28/44pin Micromite to Read/Write files from/to a FAT32 formatted SDCard. One of the primary uses for this FAT32 driver is to enable MMBasic programs to perform logging operations and then for a PC/Tablet/MAC to be able to read the logfile and process it using common tools such as Excel/Libre Calc/OpenOffice Calc, ie the files produced are 100% FAT32 compliant. NB there is nothing limiting the use of the driver to just logging applications, but most embedded systems need logging capability hence the chosen example MMBasic program. Once installed, the Driver's memory footprint is > memory
Flash: 23K (39%) Program (441 lines) 7K (12%) 1 CFunction 29K (49%) Free RAM: 2K ( 3%) 11 Variables 0K ( 0%) General 51K (97%) Free > Only 7K !! The hardware required is 1) PIC32MX170 28/44 pin Micromite loaded with MmBasic 4.7 B23 or later 'PIC32MX170 28 Pin wiring
'Pin 2 Chip Select can be any digital output pin 'Pin 3 MOSI 'Pin 14 MISO 'Pin 25 SCLK 2) SPI SDCard adapter, eg Catalex http://www.dx.com/p/spi-microsd-card-adapter-v0-9b-for-arduino-works-with-official-arduino-board-246784#.Vcj0F_mrTRY or http://www.ebay.co.uk/itm/Micro-SD-Storage-Board-Mciro-SD-TF-Card-Memory-Shield-Module-SPI-For-Arduino-New-/251820477428 ?hash=item3aa1ab8bf4 The software 2015-08-10_185905_SDCardDriverExample.zip and you will also need the blank logfile.csv 2015-08-10_185941_logfile.zip The logfile.csv is 10 MBytes but when empty compresses down to 11KBytes. How to use 1) Unzip logfile.zip and copy logfile.csv to the root of your uSD card, and insert it into your SPI uSD card adaprer. 2) Unzip SDCardDriverExample and load into your Micromite 3) Run the program several times 4) The program should display something similar to > Run
Test Harness for CFunction FAT32 FileSystem driver (c) Peter Carnegie 2015 Ver 1.5 Simulates use of SDCard for Logging data CFunction Driver Version= 1.5 Initialise the Driver Initialise the disk Mount the disk Open File /logfile.csv Get Length of file /logfile.csv File /logfile.csv is 10485760 bytes in size Get Number of logging records already in file Number of Existing Log Records : 0 Write Updated Number of Records to disk Flush data to secure it Create Header entry if it doesn't exist Write a simulated Temperature entry to the Log file Write New Log record out :"10-08-2015","19:01:16","20.32" Flush log record to secure it Read and display our logging file Num Records = 5 Header = Log File Started at 10-08-2015 19:01:03 Record 1 = "10-08-2015","19:01:04","20.86" Record 2 = "10-08-2015","19:01:09","20.58" Record 3 = "10-08-2015","19:01:11","20.71" Record 4 = "10-08-2015","19:01:14","20.29" Record 5 = "10-08-2015","19:01:16","20.32" Close File Close Driver > The records are in Comma Separated Value format. 5)Now take the uSDCard and insert it into your PC's card reader and open logfile.csv in your spreadsheet, eg Excel. You should find that logfile.csv will load straight in without any problems. (6)Reinsert the SDCard back into the Micromite setup and run the program a few times to generate some more simulated logging records, proving that the program is truly appending persistent records to the SDCard. This driver has been created with minimal memory impact in mind, targeted at Embedded Systems, so it it doesn't support operations like DIR, DEL, CREATE File and so on. I will release a driver which does provide the full range of support expected from a file system driver in due course. I have provided thin MMBasic wrapper functions around the calls to the CFunction driver, and of course if memory is really, really tight, then user code can of course directly call the CFunction entry point. Some of the limitations of this driver are 1) File size is limited to 4GBytes 2) Files cannot be created or extended, so you MUST create a large blank, ie zero-filled, file into which all subsequent write operations will take place 3) The seek command must seek on 512 byte boundaries, so with a 4GByte file that limits the maximum number of logging records to 8,388,600 before a second 4GByte file needs to be used. 4) The driver is designed for 40/48MHz operation - I will release a version which can deal with different CPU speeds in due course. 5) The driver is limited to FAT32, ie FAT12/16 are NOT supported 6) Filenames MUST be in 8.3 format This driver is hot off the keyboard so please treat it as a Beta. I couldn't have written the FAT32 driver without publications by ChaN. I hope someone finds this driver useful - all feedback most gratefully received. Peter OPTION EXPLICIT
OPTION DEFAULT NONE CPU 48 CONST VER!=1.6 'Using Catalex micro SDCard breakout board 'PIC32MX170 28 Pin wiring 'Pin 2 Chip Select can be any digital output pin 'Pin 3 MOSI 'Pin 14 MISO 'Pin 25 SCLK PRINT "Test Harness for CFunction FAT32 FileSystem driver (c) Peter Carnegie 2015 Ver";Ver! PRINT "Simulates use of SDCard for Logging data" 'Useful loop variable DIM I%=0 'We're using pin 2 for Chip Select CONST CSPin%=2 'Used for holding filename 'Use dd if=/dev/zero of=logfile.csv bs=1M count=10 to make a blank logfile DIM FileName$="/logfile.csv" 'Used for byte I/O buffer DIM Buffer$=STRING$(255," ") 'Offset in file of where to start Reading/Writing From/To DIM Offset%=0 'Captures number of Bytes READ/WRITTEN DIM ByteCount%=0 'Used to capture the return values from functions DIM Result%=-1 'Used for calculating Number of Log Records DIM NumRecords% 'Appended to each line in the file CONST CRLF$=CHR$(13)+CHR$(10) 'Quote Character for CSV format CONST Quot$=CHR$(34) PRINT "CFunction Driver Version=";File.Ver() PRINT "Initialise the Driver" Result%=File.Driver.Init(CSPin%) PError "Failed to Initialise DRIVER. Please Power Cycle system",Result%,1 PRINT "Initialise the disk" Result%=File.Disk.Init() PError "Failed to Initialise Disk. Please re-insert media and try again",Result%,1 PRINT "Mount the disk" Result%=File.Mount.Disk() PError "Failed to Mount Disk. Please re-insert media and try again",Result%,1 PRINT "Open File ";FileName$ Result%=File.Open(FileName$) PError "Failed to Open file "+FileName$,Result%,1 PRINT "Get Length of file ";FileName$ Result%=File.Length(ByteCount%) PError "Failed to get length of "+FileName$,Result%,1 PRINT "File ";FileName$;" is ";ByteCount%;" bytes in size" PRINT "Get Number of logging records already in file" Buffer$=STRING$(128," ") Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Read the first 128 bytes Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read file",Result%,0 'Get number of existing log records IF INSTR(Buffer$,".0")>0 THEN NumRecords%=VAL(MID$(Buffer$,1,INSTR(Buffer$,".0")-1)) ELSE NumRecords%=0 ENDIF PRINT "Number of Existing Log Records :";I% 'Update the number of records we've written out to disk 'Increment the number of records because we're going to 'append a new one NumRecords%=NumRecords%+1 Buffer$=STR$(NumRecords%)+ ".0" +CRLF$ 'Now write it back out to disk Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 PRINT "Write Updated Number of Records to disk" ByteCount%=0 Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 PRINT "Flush data to secure it" Result%=File.Flush() PError "Flush to disk failed",Result%,0 PRINT "Create Header entry if it doesn't exist" Offset%=512 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Read the Header block Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read file",Result%,0 'Header exists ? IF INSTR(1,Buffer$,"Log File")<1 THEN PRINT "Creating File Header" Offset%=512 PRINT "Seek to ";Offset% Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 Buffer$="Log File Started at "+DATE$+" "+TIME$+CRLF$ Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 Result%=File.Flush() PError "Flush to disk failed",Result%,0 ENDIF PRINT "Write a simulated Temperature entry to the Log file" Offset%=1024+(NumRecords% * 512) Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Simulate temperature logging Buffer$=Quot$+DATE$+Quot$+","+Quot$+TIME$+Quot$+","+Quot$+STR$(20 + RND(1),2,2)+Quot$+CRLF$ PRINT "Write New Log record out :";Buffer$; Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 PRINT "Flush log record to secure it" Result%=File.Flush() PError "Failed to Flush data to disk. Error Code:",Result%,0 PRINT "Read and display our logging file" Buffer$=STRING$(128," ") Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Get Number of Log records Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 'Allow for 10 million records NumRecords%=VAL(MID$(Buffer$,1,INSTR(Buffer$,".0")-1)) PRINT "Num Records = ";STR$(NumRecords%) 'Get Header Offset%=512 Result%=File.Seek(Offset%) Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 PRINT "Header = ";Buffer$; 'Seek to start of logging records Offset%=1024 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Display each Log Record FOR I%=1 TO NumRecords% Offset%=1024 + I%*512 Result%=File.Seek(Offset%) Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 PRINT "Record";STR$(I%,7);" = ";Buffer$; NEXT I% PRINT "Close File" Result%=File.Close() PError "Failed to Close File",Result%,0 PRINT "Close Driver" Result%=File.Driver.Close() PError "Failed to Close Driver",Result%,0 IF Result%<>0 THEN PRINT "Please issue CPU Restart command at MMBasic command prompt" ENDIF END '************************************************* ' ' Print Error Message if Code% is NON-Zero ' END if Hard% is NON-Zero ' ' SUB PError(Msg$,Code%,Hard%) IF Code%=0 THEN EXIT SUB PRINT "Error : ";Msg$;". Error Code:";Code% AND &Hff IF Hard%<>0 THEN END END SUB '*********************************************** ' ' CUNCTION FAT Filesystem Driver ' ' (c) Copyright Peter Carnegie 2015 ' ' File.Driver.Init Initialise the Driver ' File.Driver.Close Close the Driver and release all resources ' File.Disk.Init Initialise the Disk Sub-System ' File.Disk.Mount Mount the disk into the filesystem ' File.Open Open File ' File.Close Close File ' File.Read Read from File ' File.Write Write to File ' File.Flush Flush bytes to disk ' File.Seek Move READ/WRITE pointer to position ' File.Ver Return Driver Version ' File.Length Returns length of File in Bytes ' ' The CFunction can of course be called directly from user code ' These MMBasic wrapper functions just make things neater and tidier ! ' ' '*********************************************** '*********************************************** ' ' Initialise the FAT FileSystem Device Driver ' ' CSPinNum% is the pin number used for CS (Chip Select) ' ' Returns the address of the persistent driver memory ' ' FUNCTION File.Driver.Init(CSPinNum%) AS INTEGER 'Get address of the CFunction Driver itself LOCAL AddrOfSDCard%=PEEK(CFUNADDR Driver.SDCard) LOCAL Addr% LOCAL Result%=Driver.SDCard(0,AddrOfSDCard%,CSPinNum%,Addr%) File.Driver.Init=Result% END FUNCTION '*********************************************** ' ' Initialise the Disk ' ' Returns 0 if Successful ' ' FUNCTION File.Disk.Init() AS INTEGER LOCAL Result%=Driver.SDCard(1) File.Disk.Init=Result% END FUNCTION '*********************************************** ' ' Mount the disk ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Mount.Disk() AS INTEGER LOCAL Result%=Driver.SDCard(2) File.Mount.Disk=Result% END FUNCTION '*********************************************** ' ' Open File ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Open(Path$) AS INTEGER LOCAL Result%=Driver.SDCard(3,Path$) File.Open=Result% END FUNCTION '*********************************************** ' ' Read File - Sequential ' ' Returns 0 if succesful else non-zero ' On Entry ' ' On Exit ' Buffer$ will contain the bytes read in from disk ' NumBytes% will contain the number of bytes actually read ' If NumBytes%=0 then End Of File has been reached ' ' Use File.Seek to position the write pointer ' FUNCTION File.Read(Buffer$, NumBytes%) AS INTEGER LOCAL Result%=Driver.SDCard(4,Buffer$,NumBytes%) File.Read=Result% END FUNCTION '*********************************************** ' ' Write File - Sequential ' ' Returns 0 if succesful else non-zero ' On Entry ' Buffer$ contains the bytes to be written ' ' On Exit ' NumBytes% will contain the number of bytes actually written ' ' Use File.Seek to position the write pointer ' FUNCTION File.Write(Buffer$,NumBytes%) AS INTEGER NumBytes%=-1 LOCAL Result%=Driver.SDCard(5,Buffer$,NumBytes%) File.Write=Result% END FUNCTION '*********************************************** ' ' Flush Data to disk ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Flush() AS INTEGER LOCAL Buffer$="" LOCAL Offset%=0 LOCAL BytesWritten%=-1 LOCAL Result%=Driver.SDCard(5,Buffer$,BytesWritten%) File.Flush=Result% END FUNCTION '*********************************************** ' ' Close File ' ' Returns 0 if succesful else non-zero ' Flushes any unwritten bytes to the physical disk ' ' FUNCTION File.Close() AS INTEGER LOCAL Result%=Driver.SDCard(6) File.Close=Result% END FUNCTION '*********************************************** ' ' Drive Close ' ' Returns 0 if succesful else non-zero ' Unconfigures SPI ' Unconfigures CS pin ' FREEs up persistent RAM ' ' FUNCTION File.Driver.Close() AS INTEGER LOCAL Result%=0 Result%=Driver.SDCard(7) File.Driver.Close=Result% END FUNCTION '*********************************************** ' ' File Seek ' ' Returns 0 if succesful else non-zero ' Moves Reading/Writing offset to Position% ' ' FUNCTION File.Seek(Position%) AS INTEGER LOCAL Result%=Driver.SDCard(8,Position%) File.Seek=Result% END FUNCTION '*********************************************** ' ' Driver Version ' ' Returns Driver Version as a FLOAT, eg 1.5 ' ' FUNCTION File.Ver() AS FLOAT LOCAL Result%=Driver.SDCard(9) File.Ver=Result% / 100 END FUNCTION '*********************************************** ' ' Length of File ' ' Returns Length of File in Length% ' Returns 0 if OK, non-zero otherwise ' ' FUNCTION File.Length(Length%) AS INTEGER LOCAL Result%=Driver.SDCard(10,Length%) File.Length=Result% END FUNCTION '****************************************************************************** 'Created : 2015-08-10 15:20:23 UTC 'Author : Peter Carnegie 'Generator : CFuncGen Ver 2.1.5.0 ' CFUNCTION Driver.SDCard 00000686 10c00006 00801021 00862021 a0450000 24420001 5444fffe a0450000 03e00008 00000000 2407ffff 24c6ffff 10c70008 00001021 80830000 80a20000 00621023 14400003 24840001 1000fff7 24a50001 03e00008 00000000 27bdffe0 afbf001c 3c029d00 8c42008c 8c420000 2c830002 1460001e 8c42005c 8c430014 0083182b 1060001c 24030003 8c450000 14a3001e 000429c2 8c420018 3086007f 27a40010 00a22821 00063080 24070004 04110563 00000000 14400010 24030001 93a30013 00031e00 93a20012 00021400 00621825 93a20010 00621825 93a20011 00021200 00621825 10000004 7c63d800 10000002 24030001 24030001 00601021 8fbf001c 03e00008 27bd0020 1000ffff 00000000 3c029d00 8c42008c 8c420000 8c43005c 2484fffe 8c650014 24a5fffe 0085282b 10a00005 00001021 8c650008 8c620020 70851802 00621021 03e00008 00000000 90830015 00031a00 90820014 00621825 00031c00 9082001b 00021200 9084001a 00441025 03e00008 00621025 27bdffe8 afbf0014 afb00010 00808021 3c029d00 8c42008c 8c420000 8c43005c ac800000 8c840008 24050001 1085000c 24020001 8c650014 0085282b 10a00009 8fbf0014 50800001 8c64001c ae04000c 0411FFD0 00000000 ae020010 00001021 8fbf0014 8fb00010 03e00008 27bd0018 27bdffe0 afbf001c afb20018 afb10014 afb00010 00808021 3c029d00 8c42008c 8c420000 8c52005c 8c910000 26310001 3231ffff 12200027 24020003 8c830010 50600025 8fbf001c 3222000f 54400020 ae110000 24630001 ac830010 8c84000c 14800007 00111902 8e430010 0223182b 14600016 24020003 10000017 8fbf001c 8e420008 2442ffff 00621024 54400010 ae110000 0411FF75 00000000 00402021 2c430002 1460000b 24020001 8e430014 0083182b 10600007 24020003 ae04000c 0411FF98 00000000 ae020010 ae110000 00001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb20018 afb10014 afb00010 00808821 00a09021 0411FFA1 00000000 14400020 00408021 8e260000 30c6000f 02402021 8e250010 00063140 24070020 041104C7 00000000 0002802b 16000016 02001021 92420000 50400012 24100003 9242000b 30420008 14400008 02202021 02402021 8e250004 2406000b 0411FF32 00000000 10400007 02202021 0411FFA0 00000000 1040ffe4 00408021 10000002 02001021 02001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb20018 afb10014 afb00010 00a08021 3c029d00 8c42008c 8c520000 8c910004 02202021 24050020 2406000b 0411FF0B 00000000 8e090000 00002021 00001821 24080008 240a002f 2407002e 240b0008 01231021 80450000 30a200ff 24630001 2c460021 14c0001e 306300ff 504a001d 01231821 10470003 0088302b 14c00008 00000000 550b0017 01231821 54470015 01231821 01602021 1000ffed 2408000b 04a10005 2445ff9f 8e450044 00a21021 9042ff80 2445ff9f 30a500ff 2ca5001a 10a00003 02242821 2442ffe0 304200ff a0a20000 24840001 1000ffdd 308400ff 01231821 ae030000 2c420021 a222000b 00001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb10018 afb00014 00808021 afa60028 80c20000 24030020 14430006 00a08821 24c60001 afa60028 80c20000 5043fffd 24c60001 2403002f 54430004 ae000008 24c60001 afa60028 ae000008 8fa20028 90420000 2c420020 10400006 02002021 0411FF18 00000000 10000019 a2200000 02002021 27a50028 0411FF9A 00000000 14400013 02002021 02202821 0411FF64 00000000 1440000f 8fbf001c 8e030004 9063000b 5460000c 8fb10018 9222000b 30420010 10400005 02202021 0411FEF6 00000000 1000ffea ae020008 24020003 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffe0 afbf001c afb10018 afb00014 00808021 00a08821 240601fe 24070002 0411041F 00000000 14400018 24030003 92040001 00042200 92020000 00822025 7c042620 2402aa55 14820010 24030002 02002021 02202821 24060052 24070002 0411040F 00000000 14400008 24030001 92030001 00031a00 92020000 00621825 7c031e20 38634146 0003182b 00601021 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffb8 afbf0044 afb20040 afb1003c afb00038 00808821 3c029d00 8c42008c 8c500000 ae00005c 04110363 00000000 30420001 1440006a 24030002 27a40010 00002821 0411FFC5 00000000 24030001 1443001a 00009021 27a40010 00002821 240601be 24070010 041103E4 00000000 1440005b 24030001 93a20014 10400058 24030006 93b2001b 00129600 93a2001a 00021400 02429025 93a20018 02429025 93a20019 00021200 02429025 27a40010 02402821 0411FFA9 00000000 24040003 10440047 24030001 14400045 24030006 27a40010 02402821 2406000d 24070024 041103C6 00000000 1440003d 24030001 93a2001a 00021200 93a30019 00431025 1440000c 93a30013 93a3002a 00031e00 93a20029 00021400 00621025 93a30027 00431025 93a30028 00031a00 00431025 93a30013 70431002 93a60012 00063200 93a30011 00c33025 02469021 ae320018 93a50010 ae250008 93a30015 00031a00 93a40014 00641825 ae230010 93a40017 00042200 93a70016 00872025 1480000b 00031902 93a70026 00073e00 93a40025 00042400 00e42025 93a70023 00872025 93a70024 00073a00 00872025 00862023 00822023 00832023 0085001b 00a001f4 00002812 24a50002 ae250014 3404fff7 00a4282b 10a00009 24040003 24030006 00601021 8fbf0044 8fb20040 8fb1003c 8fb00038 03e00008 27bd0048 ae240000 93a50032 00052e00 93a40031 00042400 00a42025 93a5002f 00852025 93a50030 00052a00 00852025 ae24001c 02439021 02421021 ae220020 ae200004 ae11005c 1000ffe7 00001821 27bdffa0 afbf005c afb10058 afb00054 00803021 3c029d00 8c42008c 8c420000 8c51005c ae200004 27a20024 afa20014 27a40010 27a50030 0411FEFB 00000000 1440001b 00408021 93a20030 10400017 93a2003b 30420010 54400015 24100003 27a40030 0411FE18 00000000 ae22002c 93a3004f 00031e00 93a2004e 00021400 00621025 93a3004c 00431025 93a3004d 00031a00 00431025 ae220028 ae200024 24020001 10000002 ae220004 24100003 02001021 8fbf005c 8fb10058 8fb00054 03e00008 27bd0060 27bdffd0 afbf002c afb60028 afb50024 afb40020 afb3001c afb20018 afb10014 afb00010 0080a821 00c09821 3c029d00 8c42008c 8c420000 8c50005c acc00000 12000049 24020005 8e030004 30630001 10600045 24020004 8e120028 8e020024 02429023 0245102b 00a2900a 1240003e 00001021 0080a021 24160200 8e020024 304301ff 5460001e 8e060024 8e110008 2631ffff 00021a42 02238824 323100ff 5620000e 8e040030 54400003 8e040030 10000003 8e02002c 0411FD93 00000000 2c430002 50600004 ae020030 ae000004 10000025 24020001 8e040030 0411FDB8 00000000 14400004 00518821 ae000004 1000001d 24020001 ae110034 8e060024 30c601ff 02c61023 0052882b 0251100a 00408821 00002021 0295200b 8e050034 00403821 041102F1 00000000 50400004 8e020024 ae000004 1000000b 24020001 00511021 ae020024 02519023 8e620000 00511021 12400003 ae620000 1000ffc7 0291a021 00001021 8fbf002c 8fb60028 8fb50024 8fb40020 8fb3001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0030 27bdffd0 afbf002c afb60028 afb50024 afb40020 afb3001c afb20018 afb10014 afb00010 00a09021 00c09821 0080a021 3c029d00 8c42008c 8c420000 8c50005c acc00000 12000077 24020005 8e030004 30640001 10800073 24020004 14a00011 30630040 5060000a 8e030004 00002021 00002821 04110307 00000000 50400004 8e030004 ae000004 10000066 24020001 2402ffbf 00621024 ae020004 10000061 00001021 54600006 8e030028 8e030024 2402fe00 00621024 ae020024 8e030028 8e020024 00621023 0052182b 10600004 24150200 10400053 00409021 24150200 2416ffbf 8e020024 304301ff 54600028 8e110024 8e110008 2631ffff 00021a42 02238824 323100ff 5620000e 8e040030 54400003 8e040030 10000003 8e02002c 0411FD15 00000000 2c430002 50600004 ae020030 ae000004 1000003a 24020001 8e040030 0411FD3A 00000000 14400004 00512821 ae000004 10000032 24020001 ae050034 00002021 041102CA 00000000 50400004 8e020004 ae000004 10000029 24020001 34420040 ae020004 8e110024 323101ff 02b18823 0232102b 0242880a 02802021 02202821 041102BA 00000000 50400004 8e020024 ae000004 10000019 24020001 00511021 ae020024 8e620000 00511021 ae620000 8e020024 304201ff 5440000d 02519023 00002021 00002821 041102A8 00000000 50400004 8e020004 ae000004 10000007 24020001 00561024 ae020004 02519023 1640ffb2 0291a021 00001021 8fbf002c 8fb60028 8fb50024 8fb40020 8fb3001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0030 27bdffe0 afbf001c afb00018 3c029d00 8c42008c 8c500000 00002021 00002821 27a60010 0411FF63 00000000 ae00005c 8fbf001c 8fb00018 03e00008 27bd0020 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 3c029d00 8c42008c 8c420000 8c50005c 1200004d 24020005 8e030004 30630001 10600049 24020004 8e020028 0044902b 0092100a 00409021 8e030024 ae000024 12400041 00001021 8e110008 10600012 00118a40 2463ffff 2642ffff 0051001b 022001f4 00001012 0071001b 022001f4 00002012 0044102b 54400008 8e04002c 00111023 00431824 ae030024 02439023 10000003 8e040030 8e04002c ae040030 0232102b 10400017 00119823 02519023 0411FC88 00000000 00402021 2c420002 54400006 ae000004 8e020014 0082102b 54400004 ae040030 ae000004 1000001a 24020001 8e020024 00511021 ae020024 02531021 00511821 0223182b 5460ffec 00409021 8e020024 00529021 ae120024 0411FC9E 00000000 54400004 8e040008 ae000004 10000008 24020001 2484ffff 8e030024 00031a42 00831824 00431021 ae020034 00001021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 00052840 0085001b 00a001f4 00001012 03e00008 2442ffff 27bdffe0 afbf001c afb10018 afb00014 3c029d00 8c43008c 8c710000 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040003 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030003 24050014 00a4180b 00602021 24050008 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 2404000e 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 2403000e 24050029 00a4180b 00602021 24050002 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040019 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030019 2405000e 00a4180b 00602021 24050008 0040f809 00003021 3c02bf81 ac40f230 3c05aa99 24a56655 ac45f230 3c045566 348499aa ac44f230 3c03bf81 8c66f200 7c066b44 ac66f200 3c06bf81 8cc7fa84 24100001 7e071804 acc7fa84 3c06bf81 8cc7fb04 24080003 7d071804 acc7fb04 ac40f230 ac45f230 ac44f230 8c62f200 7e026b44 ac62f200 34038120 3c02bf80 ac435800 3c029d00 8c420000 8c440000 3c050003 34a5d090 0411FF8D 00000000 3c03bf80 ac625830 ae300038 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffe8 afbf0014 afb00010 3c029d00 8c43008c 8c700000 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040003 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030003 24050014 00a4180b 00602021 00002821 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 2404000e 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 2403000e 24050029 00a4180b 00602021 00002821 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040019 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030019 2405000e 00a4180b 00602021 00002821 0040f809 00003021 3c02bf81 ac40f230 3c05aa99 24a56655 ac45f230 3c045566 348499aa ac44f230 3c03bf81 8c66f200 7c066b44 ac66f200 3c06bf81 8cc7fb04 7c071804 acc7fb04 ac40f230 ac45f230 ac44f230 8c62f200 24040001 7c826b44 ac62f200 ae000038 8fbf0014 8fb00010 03e00008 27bd0018 27bdffe8 afbf0014 3c029d00 8c420004 0040f809 24040064 8fbf0014 03e00008 27bd0018 308400ff 3c02bf80 ac445820 3c03bf80 8c625810 30420001 1040fffd 3c02bf80 8c425820 03e00008 00000000 240300ff 3c02bf80 ac435820 3c03bf80 8c625810 30420001 1040fffd 3c02bf80 8c425820 03e00008 304200ff 27bdffe0 afbf001c afb20018 afb10014 afb00010 309100ff 3c029d00 8c42008c 8c500000 7c111420 04410009 00a09021 24040077 00002821 0411FFF1 00000000 2c430002 1060002f 8fbf001c 3231007f 8e020054 8e030050 ac430000 0411FFDD 00000000 8e020058 8e030050 ac430000 0411FFD8 00000000 02202021 0411FFCA 00000000 00122602 0411FFC7 00000000 7e443c00 0411FFC4 00000000 7e443a00 0411FFC1 00000000 324400ff 0411FFBE 00000000 24020040 12220006 24040095 3a310048 24020001 24030087 00402021 0071200a 0411FFB4 00000000 2410000a 0411FFBC 00000000 7c021c20 04610004 2610ffff 321000ff 1600fff9 00000000 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffd0 afbf002c afb40028 afb30024 afb20020 afb1001c afb00018 3c029d00 8c42008c 8c510000 0411FEB7 00000000 8e220054 8e230050 ac430000 2410000a 0411FF9E 00000000 2610ffff 321000ff 1600fffb 24040040 00002821 0411FFA2 00000000 24030001 1443005a 00009021 24040048 240501aa 0411FF9B 00000000 24030001 14430033 240400e9 27b40010 27b30014 02808021 0411FF88 00000000 a2020000 26100001 1613fffb 93a30012 24020001 14620047 00009021 93a30013 240200aa 54620044 a2320048 10000007 24102710 0411FF65 00000000 16000004 240400e9 10000039 00009021 240400e9 3c054000 0411FF7C 00000000 5440fff5 2610ffff 12000033 00009021 2404007a 00002821 0411FF74 00000000 5440002e a2320048 0411FF65 00000000 a2820000 26940001 1674fffb 2402000c 93b20010 32520040 24030004 0072100a 10000021 00409021 00002821 0411FF63 00000000 2c420002 24030002 24120001 0062900b 240300e9 24130041 0062980b 10000005 24102710 0411FF39 00000000 52000011 00009021 02602021 00002821 0411FF52 00000000 5440fff7 2610ffff 52000009 00009021 24040050 24050200 0411FF4A 00000000 10000003 0002900b 10000002 a2320048 a2320048 8e220054 8e230050 ac430000 0411FF35 00000000 3c029d00 8c420000 8c440000 3c050098 34a59680 0411FE3B 00000000 3c03bf80 ac605800 3c04bf80 ac825830 34028120 ac625800 2e420001 8fbf002c 8fb40028 8fb30024 8fb20020 8fb1001c 8fb00018 03e00008 27bd0030 27bdffd0 afbf002c afb50028 afb40024 afb30020 afb2001c afb10018 afb00014 00809021 00c09821 00e0a821 3c029d00 8c42008c 8c540000 92830048 30630008 00051240 24040051 0043280a 0411FF15 00000000 14400029 24100001 34109c40 241100ff 0411FF04 00000000 14510005 2610ffff 1600fffb 00000000 1000001f 24100001 240300fe 1443001c 24100001 00138823 26310202 12600006 02358823 0411FEF5 00000000 2673ffff 1660fffc 00000000 12400009 02558021 0411FEEE 00000000 a2420000 26520001 1650fffb 00000000 10000004 00000000 26b5ffff 56a0ffff 26b5ffff 0411FEE3 00000000 2631ffff 1620fffc 00008021 8e820054 8e830050 ac430000 0411FEDB 00000000 02001021 8fbf002c 8fb50028 8fb40024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0030 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 00808021 3c029d00 8c42008c 10800012 8c510000 10a0004a 00009821 8e220040 10400047 00859021 92040000 26100001 0411FEB2 00000000 8e220040 2442ffff 1212003e ae220040 5440fff8 92040000 1000003b 00009821 50a00014 8e300040 92230048 30630008 00051240 24040058 0043280a 0411FEB7 00000000 14400030 24130001 240400ff 0411FE9C 00000000 240400fe 0411FE99 00000000 24020200 ae220040 10000026 00009821 26100002 12000008 2610ffff 2412ffff 00002021 0411FE8E 00000000 2610ffff 1612fffc 00002021 0411FE94 00000000 3042001f 24030005 1443000e 24130001 10000005 24101388 0411FE78 00000000 10000002 2610ffff 241200ff 0411FE87 00000000 10520003 2e130001 1600fff6 24130001 8e220054 8e230050 ac430000 0411FE7E 00000000 10000003 02601021 00009821 02601021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 00809021 00a09821 3c119d00 8e22003c 0040f809 24040060 00408021 8e22008c ac500000 00001821 00001021 24040018 00031880 02031821 ac600000 24420001 1444fffb 00401821 3c029d00 8c42008c 8c510000 24020060 ae22003c 3c029d00 24421a18 3c039d00 24631dc8 0062202b 10800004 00621023 00529021 10000003 ae320044 00529021 ae320044 ae33004c 3c129d00 8e420028 0040f809 02602021 24030001 00431004 ae220050 8e420024 02602021 0040f809 24050006 ae220054 8e420024 02602021 0040f809 24050005 ae220058 8e420010 02602021 24050008 0040f809 00003021 8e220054 8e230050 ac430000 02001021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 27bdffd0 afbf002c afb40028 afb30024 afb20020 afb1001c afb00018 00a09021 00c0a021 8c820000 8c830004 00432025 14800010 00e09821 3c029d00 8c42008c 8c420000 2410ffff 14400098 2411ffff 8ca40000 8cc50000 0411FF9E 00000000 ae620000 ae600004 00008021 1000008f 00008821 24040001 1444000d 24040002 1460000b 2410ffff 3c029d00 8c42008c 8c420000 10400085 2411ffff 0411FE50 00000000 00408021 10000080 00008821 1444000a 24040003 14600008 00008821 3c029d00 8c42008c 8c440000 0411FAD6 00000000 10000075 305000ff 14440014 24040004 14600012 00000000 82420000 26440001 00821021 a0400001 82430001 24020020 14620005 24030020 24840001 80820000 5043fffe 24840001 0411FB54 00000000 305000ff 10000060 00008821 1444000e 24040005 1460000c 27a60010 26440001 92450000 0411FB7B 00000000 8fa30010 a2430000 ae830000 ae800004 305000ff 10000051 00008821 14440012 24040006 14600010 27a60010 26440001 92450000 0411FBD0 00000000 304200ff 50400004 8fa20010 00408021 10000043 00008821 ae820000 ae800004 00008021 1000003e 00008821 14440007 24040007 14600005 00008821 0411FC52 00000000 10000036 305000ff 54440016 24040008 54600014 24040008 3c109d00 8e02008c 8c520000 0411FD32 00000000 8e020010 8e44004c 00002821 0040f809 00003021 8e03008c 8e020044 0040f809 8c640000 8e02008c ac400000 00008021 1000001f 00008821 14440008 24040009 14600006 00008821 8e440000 0411FC42 00000000 10000016 305000ff 14440004 2404000a 1060000f 24100096 2404000a 1444000e 2410ffff 5460000d 2411ffff 3c029d00 8c42008c 8c420000 8c420028 ae420000 ae400004 00008021 10000004 00008821 10000002 00008821 2411ffff 02001021 02201821 8fbf002c 8fb40028 8fb30024 8fb20020 8fb1001c 8fb00018 03e00008 27bd0030 41909a80 808f418e 49454545 8f8e4949 4f929290 55554f99 9b9a9959 9f9e9d9c 554f4941 a7a6a5a5 abaaa9a8 afae21ac b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc END CFUNCTION 'MIPS32 M4K ' '****************************************************************************** The only Konstant is Change |
||||
CircuitGizmos![]() Guru ![]() Joined: 08/09/2011 Location: United StatesPosts: 1427 |
I think that this is a GREAT idea! Micromites and Maximites! - Beginning Maximite |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
@CG Thanks. Hopefully you can independently verify the driver with your hardware, it should just work on a 44 pin 'MX170 although I don't one to test with ! Peter The only Konstant is Change |
||||
Grogster![]() Admin Group ![]() Joined: 31/12/2012 Location: New ZealandPosts: 9610 |
Clever boy! ![]() ![]() ![]() ![]() Well done. I am sure this will be of great use to those who don't want to tackle the MM+. Amazing you got all those filesystem features into 7K! Marvelous. ![]() Smoke makes things work. When the smoke gets out, it stops! |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
Hi G, thanks, it was quite intense coding/testing to say the least ! I'm working on a way to load CFunctions directly into Flash so that the 3:1 wastage should be got rid of. That way, the 7K CFunction driver will be just that, 7K, and not another 15K of duplicated/wasted flash. Personally, I think that the 28 pin 'MX170 is great VFM from all kinds of angles and it has legs on it still despite the siren attractions of it's younger but beefier younger sibling ![]() Also, if we can really crack loadable drivers for MMBasic comprehensively, then of course the MM+ will benefit from being able to have its range of devices supported increased by 3rd party contributors. Take care Peter The only Konstant is Change |
||||
viscomjim Guru ![]() Joined: 08/01/2014 Location: United StatesPosts: 925 |
Peter, you, my friend, are a BAD ASS!!!!!!!! This is great stuff. I can't wait till all this stuff is put together and out of beta so I can blow my arduino loving friends, library loving minds. Keep up the GREAT work!!!! I want to make a commercial like windows vs macs. "Hi, I'm an arduino, and I'm a uMite..." |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
@Jim, Thank You ![]() @Grogster, PS, I reckon that if I built the FAT32 driver directly into the MMBasic Interpreter, that it would only cost about 5K in Flash ! G'Morning down under, and G'Nite up here ! (sorry to have to bring it up, but what a great Ashes' series ![]() Peter The only Konstant is Change |
||||
jman![]() Guru ![]() Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Peter this really great well done. Regards Jman |
||||
Frank N. Furter Guru ![]() Joined: 28/05/2012 Location: GermanyPosts: 949 |
Thats really amazing! ![]() Is there a way to load different bitmaps with this driver to a TFT??? - that would be great!!! THANKS! Frank |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Hi Peter, As others are saying - this is really good stuff ![]() Let me know what you need to help test ![]() Will gladly put it in the post for you to have by the end of this week . . . WW |
||||
kiiid Guru ![]() Joined: 11/05/2013 Location: United KingdomPosts: 671 |
Excellent! This brings life to my good old Microkite modules, because they integrate both MX170 and a uSD card slot :) http://rittle.org -------------- |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10317 |
I thought you had been quiet recently ![]() Brilliant bit of coding ![]() What speed are you running SPI? Do you up the SPI speed once the card is initialised? Please could you confirm the relationship between "write" and "flush". Can I write multiple records and then flush just once? In this case I assume the records end up in the same block if they fit? I assume "write" is: pf_write(buff, btw, &bw); //Initiate write operation or write next data. and "flush" is: pf_write(0, 0, &bw); //Finalize the write operation. If read/write pointer is not on the sector boundary, left bytes in the sector will be filled with zero. One suggestion for simplification for the user, but please ignore if not sensible, why not combine: ' File.Driver.Init Initialise the Driver ' File.Disk.Init Initialise the Disk Sub-System ' File.Disk.Mount Mount the disk into the filesystem into a single call with a return that specifies which if any bit fails: 0= success 1= fail to initialise driver 2= fail to initialise disk sub-system 4= fail to mount file system |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
@jman Thank you. @FF Yes there is indeed, it involves using File.Read to read the bitmap into RAM, then using the DrawBitmap API call to write the bitmap from RAM to the display. The RAM will have been allocated using the MALLOC API call. I don't think you can do this entirely in MMBasic but you will need to write a small CFunction to make the call into the DrawBitmap API call. The algorithm is MALLOC(size of bitmap) File.Read Bitmap into RAM BitMapdraw RAM to display If I get some time I'll create an example to demonstrate, but I'm more interested and focused on getting CFunction binaries loaded directly into Flash. @WW - Phil Thank you for such a generous offer, if I had a 44 pin MX170 module then I could test all my various bits of code across all the platforms because then I would have a complete set of 28/44/64/100 pin PIC32MX'X70's here. If you're quite sure then I would love to have one of your MX '170 44 pin modules please. @MatherP Yes indeed, one can do as many File.Writes as required and the Driver will automatically flush the bytes to the disk every 512 bytes worth but there is a chance that if there was a power failure then bytes might not have made it to the physical disk and hence would be lost. Because I was demonstrating a logging capability I wanted to make sure that the chance of losing a record was minimised hence why I flush to disk after every write. What I think I'll do, is add some functionality to the driver enabling the file to be opened for Writing specifying "with automatic flush after every write" - that should tidy up the user code a bit - flushing after every write does slow down the throughput, but is much more certain, and for an embedded system I would have thought certainty was important, hence a worthwhile alteration Your idea re combining those three calls is sensible especially in the context of an embedded system where users are not inserting/swapping SDCards as they would on a desktop/laptop system. Re SPI, I start at 250KHz, then once the SDCard has been successfully mounted switch to 10MHz - which reminds me, I must make the change to the CFunction to only go as fast as "CurrentCpuSpeed >> 2" to allow for CPU 5,10 etc. Thanks everybody for the generous feedback, it really makes it all the more worthwhile to know that people appreciate one's work. Peter The only Konstant is Change |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10317 |
Peter This only works in black and white (or other pair of colours) because BitMapdraw only uses 1 bit per pixel. It needs a more complex CFunction that defines the region and then writes the data to the display itself to deal with 16 or 24-bit colour - basically a complete loadable driver. Also, the data needs to be in a predefined binary form that the CFunction understands (RGB565, RGB888 etc.). Writing out a ".BMP" adds another level of complexity This is something I would like Geoff to change so DefineRegion is separately callable from DrawRectangle and BitMapDraw and/or add a new routine for outputting a full colour bitmap. Also, the CFunction will have to be able to write part of the image at a time as there isn't enough RAM to buffer the whole image |
||||
WhiteWizzard Guru ![]() Joined: 05/04/2013 Location: United KingdomPosts: 2944 |
Consider it done! ![]() I will build one tonight (Tuesday) and ship tomorrow for delivery Thursday/Friday. Are you're ok with soldering in the headers? If so then I will send the parcel as a large letter; but if not then let me know and I will solder them for you. Always glad to help you (and others) with the brilliant innovations being made with the MicroMite . . . ![]() WW |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
good point PeterM - only mono bitmaps for now then ! The only Konstant is Change |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
Hi Phil Thank you very much indeed. I can still solder headers ![]() BTW, I find that the double sided headers are really useful because I can plug stuff into a breadboard and also attach a dupont socket cable to the top side - I've run out for now but have 10 sticks on order from China due hopefully soon - although sometimes that "slow Boat from (to) China" does seem to be very slow indeed. Once again, very many thanks Phil, you're a star. Peter The only Konstant is Change |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10317 |
Peter I can confirm this works on the 44-pin Just one thing in your example above and what I see Why does the top line say "Number of Existing Log Records : 0 " when there are already lines in the file? |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10317 |
Peter Another thing.... If you enable an LCDPANEL "OPTION LCDPANEL ILI9341,L,23,24,25" then you get the error: "Error: Pin 20 is reserved on startup" when running your program, pin 20 is MOSI on the 44-pin, I assume the error would be on pin 3 on a 28-pin. Geoff gets round this in the normal SPI OPEN command by testing as below: if(ExtCurrentConfig[SPI_OUT_PIN] != EXT_BOOT_RESERVED) { ExtCfg(SPI_OUT_PIN, EXT_DIG_OUT, 0); ExtCfg(SPI_OUT_PIN, EXT_COM_RESERVED, 0); ExtCfg(SPI_INP_PIN, EXT_DIG_IN, 0); ExtCfg(SPI_INP_PIN, EXT_COM_RESERVED, 0); ExtCfg(SPI_CLK_PIN, EXT_DIG_OUT, 0); ExtCfg(SPI_CLK_PIN, EXT_COM_RESERVED, 0); SPI_PPS_OPEN; } SpiChnOpen(SPI_CHANNEL1, SPIMode, SPISpeed); SPIOpen = true; i.e. if the LCDPANEL is enabled then the pins don't need setting up, just open the SPI channel In order to be compatible with LCD panels and touch you need to execute this code as part of File.Driver.Init and then execute " SpiChnOpen(SPI_CHANNEL1, SPIMode, SPISpeed);" as part of every Basic callable function. You also need to execute SpiChnClose(SPI_CHANNEL1); at the end of every function and the complete close, as below, as part of File.Driver.Close if(SPIOpen && ExtCurrentConfig[SPI_OUT_PIN] != EXT_BOOT_RESERVED) {// don't close if it is not open or if it is being used by the LCD
SpiChnClose(SPI_CHANNEL1); SPI_PPS_CLOSE; ExtCfg(SPI_OUT_PIN, EXT_NOT_CONFIG, 0); ExtCfg(SPI_INP_PIN, EXT_NOT_CONFIG, 0); // reset to not in use ExtCfg(SPI_CLK_PIN, EXT_NOT_CONFIG, 0); } SPIOpen = false; // show that we are not using it This then meets Geoff's approach for displays and touch which is that all other SPI usage must open the port before use, and close it again after each usage. Note that it is important in the File.Driver.Close not to de-allocate the pins without the test or this will kill subsequent touch and display functions Rather than include the SPI open/close in the Cfunction it may be better to include them in the Basic wrapper for each SD function as this is "safe", just change the speed as required in the Cfunction. I found this problem while working on the display of pictures from SD. I've got a very quick solution for this but need the above problem fixed before I can progress. Finally, a request: please could you implement reading/writing complete 512 byte sectors into an array such as BUFFER%(64), or BUFFER!(128) Result%=File.BlockRead(Buffer%()) Result%=File.BlockWrite(Buffer!()) This then allows a Basic program to do all sorts of things that Petit FAT doesn't support. Thanks Peter |
||||
G8JCF![]() Guru ![]() Joined: 15/05/2014 Location: United KingdomPosts: 676 |
'Cos there is bug in the MMBasic program I released ! You've got sharp eyes, thank you ! The MMBasic line is currently PRINT "Number of Existing Log Records :";I% and it should read PRINT "Number of Existing Log Records :";NumRecords%
V1.61 attached2015-08-12_002449_SDCardDriverExampleV1.61.zip and also below Thanks again PeterM, very well spotted Peter OPTION EXPLICIT
OPTION DEFAULT NONE CPU 48 CONST VER!=1.61 'Using Catalex micro SDCard breakout board 'PIC32MX170 28 Pin wiring 'Pin 2 Chip Select can be any digital output pin 'Pin 3 MOSI 'Pin 14 MISO 'Pin 25 SCLK PRINT "Test Harness for CFunction FAT32 FileSystem driver (c) Peter Carnegie 2015 Ver";Ver! PRINT "Simulates use of SDCard for Logging data" 'Set Non-Zero to TRACE program CONST TRACE = 0 'Number of bytes to show in hex dumps CONST Length%=&H100 'Useful loop variable DIM I%=0 'Holds the address returned by Driver.Init DIM AddrOfRam%=0 'We're using pin 2 for Chip Select CONST CSPin%=2 'Used for holding filename 'Use dd if=/dev/zero of=logfile.csv bs=1M count=10 to make a blank logfile DIM FileName$="/logfile.csv" 'Used for byte I/O buffer DIM Buffer$=STRING$(255," ") 'Offset in file of where to start Reading/Writing From/To DIM Offset%=0 'Captures number of Bytes READ/WRITTEN DIM ByteCount%=0 'Used to capture the return values from functions DIM Result%=-1 'Used for calculating Number of Log Records DIM NumRecords% 'Appended to each line in the file CONST CRLF$=CHR$(13)+CHR$(10) 'Quote Character for CSV format CONST Quot$=CHR$(34) PRINT "CFunction Driver Version=";File.Ver() PRINT "Initialise the Driver" 'AddrOfRam%=File.Driver.Init(CSPin%) Result%=File.Driver.Init(CSPin%, AddrOfRam%) PError "Failed to Initialise DRIVER. Please Power Cycle system",Result%,1 PRINT "Initialise the disk" Result%=File.Disk.Init() PError "Failed to Initialise Disk. Please re-insert media and try again",Result%,1 PRINT "Mount the disk" Result%=File.Mount.Disk() PError "Failed to Mount Disk. Please re-insert media and try again",Result%,1 PRINT "Open File ";FileName$ Result%=File.Open(FileName$) PError "Failed to Open file "+FileName$,Result%,1 PRINT "Get Length of file ";FileName$ Result%=File.Length(ByteCount%) PError "Failed to get length of "+FileName$,Result%,1 PRINT "File ";FileName$;" is ";ByteCount%;" bytes in size" PRINT "Get Number of logging records already in file" Buffer$=STRING$(128," ") Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Read the first 128 bytes Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read file",Result%,0 'Get number of existing log records IF INSTR(Buffer$,".0")>0 THEN NumRecords%=VAL(MID$(Buffer$,1,INSTR(Buffer$,".0")-1)) ELSE NumRecords%=0 ENDIF PRINT "Number of Existing Log Records :";NumRecords% 'Update the number of records we've written out to disk 'Increment the number of records because we're going to 'append a new one NumRecords%=NumRecords%+1 Buffer$=STR$(NumRecords%)+ ".0" +CRLF$ 'Now write it back out to disk Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 PRINT "Write Updated Number of Records to disk" ByteCount%=0 Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 PRINT "Flush data to secure it" Result%=File.Flush() PError "Flush to disk failed",Result%,0 PRINT "Create Header entry if it doesn't exist" Offset%=512 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Read the Header block Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read file",Result%,0 'Header exists ? IF INSTR(1,Buffer$,"Log File")<1 THEN PRINT "Creating File Header" Offset%=512 PRINT "Seek to ";Offset% Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 Buffer$="Log File Started at "+DATE$+" "+TIME$+CRLF$ Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 Result%=File.Flush() PError "Flush to disk failed",Result%,0 ENDIF PRINT "Write a simulated Temperature entry to the Log file" Offset%=1024+(NumRecords% * 512) Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Simulate temperature logging Buffer$=Quot$+DATE$+Quot$+","+Quot$+TIME$+Quot$+","+Quot$+STR$(20 + RND(1),2,2)+Quot$+CRLF$ PRINT "Write New Log record out :";Buffer$; Result%=File.Write(Buffer$,ByteCount%) PError "Failed to write to file",Result%,0 PRINT "Flush log record to secure it" Result%=File.Flush() PError "Failed to Flush data to disk. Error Code:",Result%,0 PRINT "Read and display our logging file" Buffer$=STRING$(128," ") Offset%=0 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Get Number of Log records Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 'Allow for 10 million records NumRecords%=VAL(MID$(Buffer$,1,INSTR(Buffer$,".0")-1)) PRINT "Num Records = ";STR$(NumRecords%) 'Get Header Offset%=512 Result%=File.Seek(Offset%) Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 PRINT "Header = ";Buffer$; 'Seek to start of logging records Offset%=1024 Result%=File.Seek(Offset%) PError "Failed to seek to position "+STR$(Offset%),Result%,0 'Display each Log Record FOR I%=1 TO NumRecords% Offset%=1024 + I%*512 Result%=File.Seek(Offset%) Buffer$=STRING$(128," ") Result%=File.Read(Buffer$,ByteCount%) PError "Failed to Read File ",Result%,0 PRINT "Record";STR$(I%,7);" = ";Buffer$; NEXT I% PRINT "Close File" Result%=File.Close() PError "Failed to Close File",Result%,0 PRINT "Close Driver" Result%=File.Driver.Close() PError "Failed to Close Driver",Result%,0 IF Result%<>0 THEN PRINT "Please issue CPU Restart command at MMBasic command prompt" ENDIF END '************************************************* ' ' Debugging Tools ' '************************************************* '************************************************* ' ' Print Error Message if Code% is NON-Zero ' END if Hard% is NON-Zero ' ' SUB PError(Msg$,Code%,Hard%) IF Code%=0 THEN EXIT SUB PRINT "Error : ";Msg$;". Error Code:";Code% AND &Hff IF Hard%<>0 THEN END END SUB '************************************************* ' ' Display Hexdump and Result code if TRACE is O ' ' SUB DoTrace(Msg$, Result%, Numbytes%) IF TRACE=0 THEN EXIT SUB PRINT Msg$;" returned &H";HEX$(Result%); IF NumBytes%<>0 THEN PRINT " NumBytes:";NumBytes%; ENDIF HexDump(AddrOfRam%,Length%) PAUSE 10 END SUB '*********************************************** ' 'Do Hex Dump of memory area ' ' SUB HexDump(Addr%,NumBytes%) LOCAL I%,J%,L$ PRINT "Address "; FOR I%=1 TO 16 PRINT " ";HEX$(I%-1);" "; IF (I%) MOD 4=0 THEN PRINT " "; NEXT I% PRINT " "; FOR I%=0 TO 15 PRINT HEX$(I%); NEXT I% FOR I%=Addr% TO Addr%+NumBytes%-1 STEP 16 L$="" FOR J%=0 TO 15 L$=L$ + CHR$(PEEK(BYTE I%+J%)) NEXT J% PRINT HEX$(I%,8);" "; FOR J%=1 TO 16 PRINT HEX$(ASC(MID$(L$,J%,1)),2);" "; IF J% MOD 4 = 0 THEN PRINT " "; NEXT J% PRINT " "; FOR J%=1 TO 16 IF (( ASC(MID$(L$,J%,1)) > &H1F) AND (ASC(MID$(L$,J%,1)) <&H80)) THEN PRINT MID$(L$,J%,1);""; ELSE PRINT "."; ENDIF NEXT J% NEXT I% END SUB '*********************************************** ' ' CUNCTION FAT Filesystem Driver ' ' (c) Copyright Peter Carnegie 2015 ' ' File.Driver.Init Initialise the Driver ' File.Driver.Close Close the Driver and release all resources ' File.Disk.Init Initialise the Disk Sub-System ' File.Disk.Mount Mount the disk into the filesystem ' File.Open Open File ' File.Close Close File ' File.Read Read from File ' File.Write Write to File ' File.Flush Flush bytes to disk ' File.Seek Move READ/WRITE pointer to position ' File.Ver Return Driver Version ' File.Length Returns length of File in Bytes ' ' The CFunction can of course be called directly from user code ' These MMBasic wrapper functions just make things neater and tidier ! ' ' '*********************************************** '*********************************************** ' ' Initialise the FAT FileSystem Device Driver ' ' CSPinNum% is the pin number used for CS (Chip Select) ' ' Returns the address of the persistent driver memory ' ' FUNCTION File.Driver.Init(CSPinNum%,Addr%) AS INTEGER 'Get address of the CFunction Driver itself LOCAL AddrOfSDCard%=PEEK(CFUNADDR Driver.SDCard) LOCAL Result%=Driver.SDCard(0,AddrOfSDCard%,CSPinNum%,Addr%) File.Driver.Init=Result% IF TRACE<>0 THEN PRINT "Persistent RAM starts at &H";HEX$(Addr%) ENDIF DoTrace("Initialise Driver") END FUNCTION '*********************************************** ' ' Initialise the Disk ' ' Returns 0 if Successful ' ' FUNCTION File.Disk.Init() AS INTEGER LOCAL Result%=Driver.SDCard(1) File.Disk.Init=Result% DoTrace("Initialise Disk") END FUNCTION '*********************************************** ' ' Mount the disk ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Mount.Disk() AS INTEGER LOCAL Result%=Driver.SDCard(2) File.Mount.Disk=Result% DoTrace("Mount Disk",Result%) END FUNCTION '*********************************************** ' ' Open File ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Open(Path$) AS INTEGER LOCAL Result%=Driver.SDCard(3,Path$) File.Open=Result% DoTrace("Open File",Result%) END FUNCTION '*********************************************** ' ' Read File - Sequential ' ' Returns 0 if succesful else non-zero ' On Entry ' ' On Exit ' Buffer$ will contain the bytes read in from disk ' NumBytes% will contain the number of bytes actually read ' If NumBytes%=0 then End Of File has been reached ' ' Use File.Seek to position the write pointer ' FUNCTION File.Read(Buffer$, NumBytes%) AS INTEGER LOCAL Result%=Driver.SDCard(4,Buffer$,NumBytes%) File.Read=Result% DoTrace("Read File",Result%) END FUNCTION '*********************************************** ' ' Write File - Sequential ' ' Returns 0 if succesful else non-zero ' On Entry ' Buffer$ contains the bytes to be written ' ' On Exit ' NumBytes% will contain the number of bytes actually written ' ' Use File.Seek to position the write pointer ' FUNCTION File.Write(Buffer$,NumBytes%) AS INTEGER NumBytes%=-1 LOCAL Result%=Driver.SDCard(5,Buffer$,NumBytes%) File.Write=Result% DoTrace("Write File",Result%,NumBytes%) END FUNCTION '*********************************************** ' ' Flush Data to disk ' ' Returns 0 if succesful else non-zero ' ' FUNCTION File.Flush() AS INTEGER LOCAL Buffer$="" LOCAL Offset%=0 LOCAL BytesWritten%=-1 LOCAL Result%=Driver.SDCard(5,Buffer$,BytesWritten%) File.Flush=Result% DoTrace("Write File (Flush)",Result%,BytesWritten%) END FUNCTION '*********************************************** ' ' Close File ' ' Returns 0 if succesful else non-zero ' Flushes any unwritten bytes to the physical disk ' ' FUNCTION File.Close() AS INTEGER LOCAL Result%=Driver.SDCard(6) File.Close=Result% DoTrace("Close File",Result%) END FUNCTION '*********************************************** ' ' Drive Close ' ' Returns 0 if succesful else non-zero ' Unconfigures SPI ' Unconfigures CS pin ' FREEs up persistent RAM ' ' FUNCTION File.Driver.Close() AS INTEGER LOCAL Result%=0 Result%=Driver.SDCard(7) File.Driver.Close=Result% DoTrace("Close Driver",Result%) END FUNCTION '*********************************************** ' ' File Seek ' ' Returns 0 if succesful else non-zero ' Moves Reading/Writing offset to Position% ' ' FUNCTION File.Seek(Position%) AS INTEGER LOCAL Result%=Driver.SDCard(8,Position%) File.Seek=Result% DoTrace("File Seek ",Result%) END FUNCTION '*********************************************** ' ' Driver Version ' ' Returns Driver Version as a FLOAT, eg 1.5 ' ' FUNCTION File.Ver() AS FLOAT LOCAL Result%=Driver.SDCard(9) File.Ver=Result% / 100 END FUNCTION '*********************************************** ' ' Length of File ' ' Returns Length of File in Length% ' Returns 0 if OK, non-zero otherwise ' ' FUNCTION File.Length(Length%) AS INTEGER LOCAL Result%=Driver.SDCard(10,Length%) File.Length=Result% DoTrace("File Length ",Result%) END FUNCTION '****************************************************************************** 'Created : 2015-08-10 15:20:23 UTC 'Author : Peter Carnegie 'Generator : CFuncGen Ver 2.1.5.0 ' CFUNCTION Driver.SDCard 00000686 10c00006 00801021 00862021 a0450000 24420001 5444fffe a0450000 03e00008 00000000 2407ffff 24c6ffff 10c70008 00001021 80830000 80a20000 00621023 14400003 24840001 1000fff7 24a50001 03e00008 00000000 27bdffe0 afbf001c 3c029d00 8c42008c 8c420000 2c830002 1460001e 8c42005c 8c430014 0083182b 1060001c 24030003 8c450000 14a3001e 000429c2 8c420018 3086007f 27a40010 00a22821 00063080 24070004 04110563 00000000 14400010 24030001 93a30013 00031e00 93a20012 00021400 00621825 93a20010 00621825 93a20011 00021200 00621825 10000004 7c63d800 10000002 24030001 24030001 00601021 8fbf001c 03e00008 27bd0020 1000ffff 00000000 3c029d00 8c42008c 8c420000 8c43005c 2484fffe 8c650014 24a5fffe 0085282b 10a00005 00001021 8c650008 8c620020 70851802 00621021 03e00008 00000000 90830015 00031a00 90820014 00621825 00031c00 9082001b 00021200 9084001a 00441025 03e00008 00621025 27bdffe8 afbf0014 afb00010 00808021 3c029d00 8c42008c 8c420000 8c43005c ac800000 8c840008 24050001 1085000c 24020001 8c650014 0085282b 10a00009 8fbf0014 50800001 8c64001c ae04000c 0411FFD0 00000000 ae020010 00001021 8fbf0014 8fb00010 03e00008 27bd0018 27bdffe0 afbf001c afb20018 afb10014 afb00010 00808021 3c029d00 8c42008c 8c420000 8c52005c 8c910000 26310001 3231ffff 12200027 24020003 8c830010 50600025 8fbf001c 3222000f 54400020 ae110000 24630001 ac830010 8c84000c 14800007 00111902 8e430010 0223182b 14600016 24020003 10000017 8fbf001c 8e420008 2442ffff 00621024 54400010 ae110000 0411FF75 00000000 00402021 2c430002 1460000b 24020001 8e430014 0083182b 10600007 24020003 ae04000c 0411FF98 00000000 ae020010 ae110000 00001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb20018 afb10014 afb00010 00808821 00a09021 0411FFA1 00000000 14400020 00408021 8e260000 30c6000f 02402021 8e250010 00063140 24070020 041104C7 00000000 0002802b 16000016 02001021 92420000 50400012 24100003 9242000b 30420008 14400008 02202021 02402021 8e250004 2406000b 0411FF32 00000000 10400007 02202021 0411FFA0 00000000 1040ffe4 00408021 10000002 02001021 02001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb20018 afb10014 afb00010 00a08021 3c029d00 8c42008c 8c520000 8c910004 02202021 24050020 2406000b 0411FF0B 00000000 8e090000 00002021 00001821 24080008 240a002f 2407002e 240b0008 01231021 80450000 30a200ff 24630001 2c460021 14c0001e 306300ff 504a001d 01231821 10470003 0088302b 14c00008 00000000 550b0017 01231821 54470015 01231821 01602021 1000ffed 2408000b 04a10005 2445ff9f 8e450044 00a21021 9042ff80 2445ff9f 30a500ff 2ca5001a 10a00003 02242821 2442ffe0 304200ff a0a20000 24840001 1000ffdd 308400ff 01231821 ae030000 2c420021 a222000b 00001021 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffe0 afbf001c afb10018 afb00014 00808021 afa60028 80c20000 24030020 14430006 00a08821 24c60001 afa60028 80c20000 5043fffd 24c60001 2403002f 54430004 ae000008 24c60001 afa60028 ae000008 8fa20028 90420000 2c420020 10400006 02002021 0411FF18 00000000 10000019 a2200000 02002021 27a50028 0411FF9A 00000000 14400013 02002021 02202821 0411FF64 00000000 1440000f 8fbf001c 8e030004 9063000b 5460000c 8fb10018 9222000b 30420010 10400005 02202021 0411FEF6 00000000 1000ffea ae020008 24020003 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffe0 afbf001c afb10018 afb00014 00808021 00a08821 240601fe 24070002 0411041F 00000000 14400018 24030003 92040001 00042200 92020000 00822025 7c042620 2402aa55 14820010 24030002 02002021 02202821 24060052 24070002 0411040F 00000000 14400008 24030001 92030001 00031a00 92020000 00621825 7c031e20 38634146 0003182b 00601021 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffb8 afbf0044 afb20040 afb1003c afb00038 00808821 3c029d00 8c42008c 8c500000 ae00005c 04110363 00000000 30420001 1440006a 24030002 27a40010 00002821 0411FFC5 00000000 24030001 1443001a 00009021 27a40010 00002821 240601be 24070010 041103E4 00000000 1440005b 24030001 93a20014 10400058 24030006 93b2001b 00129600 93a2001a 00021400 02429025 93a20018 02429025 93a20019 00021200 02429025 27a40010 02402821 0411FFA9 00000000 24040003 10440047 24030001 14400045 24030006 27a40010 02402821 2406000d 24070024 041103C6 00000000 1440003d 24030001 93a2001a 00021200 93a30019 00431025 1440000c 93a30013 93a3002a 00031e00 93a20029 00021400 00621025 93a30027 00431025 93a30028 00031a00 00431025 93a30013 70431002 93a60012 00063200 93a30011 00c33025 02469021 ae320018 93a50010 ae250008 93a30015 00031a00 93a40014 00641825 ae230010 93a40017 00042200 93a70016 00872025 1480000b 00031902 93a70026 00073e00 93a40025 00042400 00e42025 93a70023 00872025 93a70024 00073a00 00872025 00862023 00822023 00832023 0085001b 00a001f4 00002812 24a50002 ae250014 3404fff7 00a4282b 10a00009 24040003 24030006 00601021 8fbf0044 8fb20040 8fb1003c 8fb00038 03e00008 27bd0048 ae240000 93a50032 00052e00 93a40031 00042400 00a42025 93a5002f 00852025 93a50030 00052a00 00852025 ae24001c 02439021 02421021 ae220020 ae200004 ae11005c 1000ffe7 00001821 27bdffa0 afbf005c afb10058 afb00054 00803021 3c029d00 8c42008c 8c420000 8c51005c ae200004 27a20024 afa20014 27a40010 27a50030 0411FEFB 00000000 1440001b 00408021 93a20030 10400017 93a2003b 30420010 54400015 24100003 27a40030 0411FE18 00000000 ae22002c 93a3004f 00031e00 93a2004e 00021400 00621025 93a3004c 00431025 93a3004d 00031a00 00431025 ae220028 ae200024 24020001 10000002 ae220004 24100003 02001021 8fbf005c 8fb10058 8fb00054 03e00008 27bd0060 27bdffd0 afbf002c afb60028 afb50024 afb40020 afb3001c afb20018 afb10014 afb00010 0080a821 00c09821 3c029d00 8c42008c 8c420000 8c50005c acc00000 12000049 24020005 8e030004 30630001 10600045 24020004 8e120028 8e020024 02429023 0245102b 00a2900a 1240003e 00001021 0080a021 24160200 8e020024 304301ff 5460001e 8e060024 8e110008 2631ffff 00021a42 02238824 323100ff 5620000e 8e040030 54400003 8e040030 10000003 8e02002c 0411FD93 00000000 2c430002 50600004 ae020030 ae000004 10000025 24020001 8e040030 0411FDB8 00000000 14400004 00518821 ae000004 1000001d 24020001 ae110034 8e060024 30c601ff 02c61023 0052882b 0251100a 00408821 00002021 0295200b 8e050034 00403821 041102F1 00000000 50400004 8e020024 ae000004 1000000b 24020001 00511021 ae020024 02519023 8e620000 00511021 12400003 ae620000 1000ffc7 0291a021 00001021 8fbf002c 8fb60028 8fb50024 8fb40020 8fb3001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0030 27bdffd0 afbf002c afb60028 afb50024 afb40020 afb3001c afb20018 afb10014 afb00010 00a09021 00c09821 0080a021 3c029d00 8c42008c 8c420000 8c50005c acc00000 12000077 24020005 8e030004 30640001 10800073 24020004 14a00011 30630040 5060000a 8e030004 00002021 00002821 04110307 00000000 50400004 8e030004 ae000004 10000066 24020001 2402ffbf 00621024 ae020004 10000061 00001021 54600006 8e030028 8e030024 2402fe00 00621024 ae020024 8e030028 8e020024 00621023 0052182b 10600004 24150200 10400053 00409021 24150200 2416ffbf 8e020024 304301ff 54600028 8e110024 8e110008 2631ffff 00021a42 02238824 323100ff 5620000e 8e040030 54400003 8e040030 10000003 8e02002c 0411FD15 00000000 2c430002 50600004 ae020030 ae000004 1000003a 24020001 8e040030 0411FD3A 00000000 14400004 00512821 ae000004 10000032 24020001 ae050034 00002021 041102CA 00000000 50400004 8e020004 ae000004 10000029 24020001 34420040 ae020004 8e110024 323101ff 02b18823 0232102b 0242880a 02802021 02202821 041102BA 00000000 50400004 8e020024 ae000004 10000019 24020001 00511021 ae020024 8e620000 00511021 ae620000 8e020024 304201ff 5440000d 02519023 00002021 00002821 041102A8 00000000 50400004 8e020004 ae000004 10000007 24020001 00561024 ae020004 02519023 1640ffb2 0291a021 00001021 8fbf002c 8fb60028 8fb50024 8fb40020 8fb3001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0030 27bdffe0 afbf001c afb00018 3c029d00 8c42008c 8c500000 00002021 00002821 27a60010 0411FF63 00000000 ae00005c 8fbf001c 8fb00018 03e00008 27bd0020 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 3c029d00 8c42008c 8c420000 8c50005c 1200004d 24020005 8e030004 30630001 10600049 24020004 8e020028 0044902b 0092100a 00409021 8e030024 ae000024 12400041 00001021 8e110008 10600012 00118a40 2463ffff 2642ffff 0051001b 022001f4 00001012 0071001b 022001f4 00002012 0044102b 54400008 8e04002c 00111023 00431824 ae030024 02439023 10000003 8e040030 8e04002c ae040030 0232102b 10400017 00119823 02519023 0411FC88 00000000 00402021 2c420002 54400006 ae000004 8e020014 0082102b 54400004 ae040030 ae000004 1000001a 24020001 8e020024 00511021 ae020024 02531021 00511821 0223182b 5460ffec 00409021 8e020024 00529021 ae120024 0411FC9E 00000000 54400004 8e040008 ae000004 10000008 24020001 2484ffff 8e030024 00031a42 00831824 00431021 ae020034 00001021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 00052840 0085001b 00a001f4 00001012 03e00008 2442ffff 27bdffe0 afbf001c afb10018 afb00014 3c029d00 8c43008c 8c710000 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040003 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030003 24050014 00a4180b 00602021 24050008 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 2404000e 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 2403000e 24050029 00a4180b 00602021 24050002 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040019 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030019 2405000e 00a4180b 00602021 24050008 0040f809 00003021 3c02bf81 ac40f230 3c05aa99 24a56655 ac45f230 3c045566 348499aa ac44f230 3c03bf81 8c66f200 7c066b44 ac66f200 3c06bf81 8cc7fa84 24100001 7e071804 acc7fa84 3c06bf81 8cc7fb04 24080003 7d071804 acc7fb04 ac40f230 ac45f230 ac44f230 8c62f200 7e026b44 ac62f200 34038120 3c02bf80 ac435800 3c029d00 8c420000 8c440000 3c050003 34a5d090 0411FF8D 00000000 3c03bf80 ac625830 ae300038 8fbf001c 8fb10018 8fb00014 03e00008 27bd0020 27bdffe8 afbf0014 afb00010 3c029d00 8c43008c 8c700000 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040003 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030003 24050014 00a4180b 00602021 00002821 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 2404000e 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 2403000e 24050029 00a4180b 00602021 00002821 0040f809 00003021 3c029d00 8c420010 3c03bf81 8c65f220 7ca5d800 3c030661 24630053 10a3000b 24040019 3c03bf81 8c64f220 7c84d800 3c030660 24630053 00832026 24030019 2405000e 00a4180b 00602021 00002821 0040f809 00003021 3c02bf81 ac40f230 3c05aa99 24a56655 ac45f230 3c045566 348499aa ac44f230 3c03bf81 8c66f200 7c066b44 ac66f200 3c06bf81 8cc7fb04 7c071804 acc7fb04 ac40f230 ac45f230 ac44f230 8c62f200 24040001 7c826b44 ac62f200 ae000038 8fbf0014 8fb00010 03e00008 27bd0018 27bdffe8 afbf0014 3c029d00 8c420004 0040f809 24040064 8fbf0014 03e00008 27bd0018 308400ff 3c02bf80 ac445820 3c03bf80 8c625810 30420001 1040fffd 3c02bf80 8c425820 03e00008 00000000 240300ff 3c02bf80 ac435820 3c03bf80 8c625810 30420001 1040fffd 3c02bf80 8c425820 03e00008 304200ff 27bdffe0 afbf001c afb20018 afb10014 afb00010 309100ff 3c029d00 8c42008c 8c500000 7c111420 04410009 00a09021 24040077 00002821 0411FFF1 00000000 2c430002 1060002f 8fbf001c 3231007f 8e020054 8e030050 ac430000 0411FFDD 00000000 8e020058 8e030050 ac430000 0411FFD8 00000000 02202021 0411FFCA 00000000 00122602 0411FFC7 00000000 7e443c00 0411FFC4 00000000 7e443a00 0411FFC1 00000000 324400ff 0411FFBE 00000000 24020040 12220006 24040095 3a310048 24020001 24030087 00402021 0071200a 0411FFB4 00000000 2410000a 0411FFBC 00000000 7c021c20 04610004 2610ffff 321000ff 1600fff9 00000000 8fbf001c 8fb20018 8fb10014 8fb00010 03e00008 27bd0020 27bdffd0 afbf002c afb40028 afb30024 afb20020 afb1001c afb00018 3c029d00 8c42008c 8c510000 0411FEB7 00000000 8e220054 8e230050 ac430000 2410000a 0411FF9E 00000000 2610ffff 321000ff 1600fffb 24040040 00002821 0411FFA2 00000000 24030001 1443005a 00009021 24040048 240501aa 0411FF9B 00000000 24030001 14430033 240400e9 27b40010 27b30014 02808021 0411FF88 00000000 a2020000 26100001 1613fffb 93a30012 24020001 14620047 00009021 93a30013 240200aa 54620044 a2320048 10000007 24102710 0411FF65 00000000 16000004 240400e9 10000039 00009021 240400e9 3c054000 0411FF7C 00000000 5440fff5 2610ffff 12000033 00009021 2404007a 00002821 0411FF74 00000000 5440002e a2320048 0411FF65 00000000 a2820000 26940001 1674fffb 2402000c 93b20010 32520040 24030004 0072100a 10000021 00409021 00002821 0411FF63 00000000 2c420002 24030002 24120001 0062900b 240300e9 24130041 0062980b 10000005 24102710 0411FF39 00000000 52000011 00009021 02602021 00002821 0411FF52 00000000 5440fff7 2610ffff 52000009 00009021 24040050 24050200 0411FF4A 00000000 10000003 0002900b 10000002 a2320048 a2320048 8e220054 8e230050 ac430000 0411FF35 00000000 3c029d00 8c420000 8c440000 3c050098 34a59680 0411FE3B 00000000 3c03bf80 ac605800 3c04bf80 ac825830 34028120 ac625800 2e420001 8fbf002c 8fb40028 8fb30024 8fb20020 8fb1001c 8fb00018 03e00008 27bd0030 27bdffd0 afbf002c afb50028 afb40024 afb30020 afb2001c afb10018 afb00014 00809021 00c09821 00e0a821 3c029d00 8c42008c 8c540000 92830048 30630008 00051240 24040051 0043280a 0411FF15 00000000 14400029 24100001 34109c40 241100ff 0411FF04 00000000 14510005 2610ffff 1600fffb 00000000 1000001f 24100001 240300fe 1443001c 24100001 00138823 26310202 12600006 02358823 0411FEF5 00000000 2673ffff 1660fffc 00000000 12400009 02558021 0411FEEE 00000000 a2420000 26520001 1650fffb 00000000 10000004 00000000 26b5ffff 56a0ffff 26b5ffff 0411FEE3 00000000 2631ffff 1620fffc 00008021 8e820054 8e830050 ac430000 0411FEDB 00000000 02001021 8fbf002c 8fb50028 8fb40024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0030 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 00808021 3c029d00 8c42008c 10800012 8c510000 10a0004a 00009821 8e220040 10400047 00859021 92040000 26100001 0411FEB2 00000000 8e220040 2442ffff 1212003e ae220040 5440fff8 92040000 1000003b 00009821 50a00014 8e300040 92230048 30630008 00051240 24040058 0043280a 0411FEB7 00000000 14400030 24130001 240400ff 0411FE9C 00000000 240400fe 0411FE99 00000000 24020200 ae220040 10000026 00009821 26100002 12000008 2610ffff 2412ffff 00002021 0411FE8E 00000000 2610ffff 1612fffc 00002021 0411FE94 00000000 3042001f 24030005 1443000e 24130001 10000005 24101388 0411FE78 00000000 10000002 2610ffff 241200ff 0411FE87 00000000 10520003 2e130001 1600fff6 24130001 8e220054 8e230050 ac430000 0411FE7E 00000000 10000003 02601021 00009821 02601021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 27bdffd8 afbf0024 afb30020 afb2001c afb10018 afb00014 00809021 00a09821 3c119d00 8e22003c 0040f809 24040060 00408021 8e22008c ac500000 00001821 00001021 24040018 00031880 02031821 ac600000 24420001 1444fffb 00401821 3c029d00 8c42008c 8c510000 24020060 ae22003c 3c029d00 24421a18 3c039d00 24631dc8 0062202b 10800004 00621023 00529021 10000003 ae320044 00529021 ae320044 ae33004c 3c129d00 8e420028 0040f809 02602021 24030001 00431004 ae220050 8e420024 02602021 0040f809 24050006 ae220054 8e420024 02602021 0040f809 24050005 ae220058 8e420010 02602021 24050008 0040f809 00003021 8e220054 8e230050 ac430000 02001021 8fbf0024 8fb30020 8fb2001c 8fb10018 8fb00014 03e00008 27bd0028 27bdffd0 afbf002c afb40028 afb30024 afb20020 afb1001c afb00018 00a09021 00c0a021 8c820000 8c830004 00432025 14800010 00e09821 3c029d00 8c42008c 8c420000 2410ffff 14400098 2411ffff 8ca40000 8cc50000 0411FF9E 00000000 ae620000 ae600004 00008021 1000008f 00008821 24040001 1444000d 24040002 1460000b 2410ffff 3c029d00 8c42008c 8c420000 10400085 2411ffff 0411FE50 00000000 00408021 10000080 00008821 1444000a 24040003 14600008 00008821 3c029d00 8c42008c 8c440000 0411FAD6 00000000 10000075 305000ff 14440014 24040004 14600012 00000000 82420000 26440001 00821021 a0400001 82430001 24020020 14620005 24030020 24840001 80820000 5043fffe 24840001 0411FB54 00000000 305000ff 10000060 00008821 1444000e 24040005 1460000c 27a60010 26440001 92450000 0411FB7B 00000000 8fa30010 a2430000 ae830000 ae800004 305000ff 10000051 00008821 14440012 24040006 14600010 27a60010 26440001 92450000 0411FBD0 00000000 304200ff 50400004 8fa20010 00408021 10000043 00008821 ae820000 ae800004 00008021 1000003e 00008821 14440007 24040007 14600005 00008821 0411FC52 00000000 10000036 305000ff 54440016 24040008 54600014 24040008 3c109d00 8e02008c 8c520000 0411FD32 00000000 8e020010 8e44004c 00002821 0040f809 00003021 8e03008c 8e020044 0040f809 8c640000 8e02008c ac400000 00008021 1000001f 00008821 14440008 24040009 14600006 00008821 8e440000 0411FC42 00000000 10000016 305000ff 14440004 2404000a 1060000f 24100096 2404000a 1444000e 2410ffff 5460000d 2411ffff 3c029d00 8c42008c 8c420000 8c420028 ae420000 ae400004 00008021 10000004 00008821 10000002 00008821 2411ffff 02001021 02201821 8fbf002c 8fb40028 8fb30024 8fb20020 8fb1001c 8fb00018 03e00008 27bd0030 41909a80 808f418e 49454545 8f8e4949 4f929290 55554f99 9b9a9959 9f9e9d9c 554f4941 a7a6a5a5 abaaa9a8 afae21ac b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc END CFUNCTION 'MIPS32 M4K ' '****************************************************************************** The only Konstant is Change |
||||
Page 1 of 3 ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |