Register

Casio fx-9860G SD- How to read files in the sd card?

Discuss anything related to calculators. For specific help on certain games/programs check the Released Projects subforum.
Senior Member
Posts: 116
Joined: Mon Mar 02, 2015 10:53 am
Calculators: Casio fx-CG20

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby AmazoNKA » Sun Aug 07, 2016 8:13 pm

Did they also drop hex or raw mode from this function or is it of no help
Code: Select all
read File + START+ LENGTH TYPE - Output the content of File starting from START and going for LENGTH. If START is omitted, the entire file is reported. If LENGTH is omitted, the entire contents from the starting point is reported. If TYPE is omitted, the OpenLog will default to reporting in ASCII. There are three output TYPEs:

ASCII = 1
HEX = 2
RAW = 3
You may leave off some trailing arguments. Check the following examples.

Basic read + omitted flags:

Example: read LOG00004.txt
Output: Accelerometer X=12 Y=215 Z=317
Read from start 0 with length of 5:

Example: read LOG00004.txt 0 5
Output: Accel
Read from position 1 with a length of 5 in HEX:

Example: read LOG00004.txt 1 5 2
Output: 63 63 65 6C
Read from position 0 with a length of 50 in RAW:

Example: read LOG00137.txt 0 50 3
Output: André-- -þ Extended Character Test

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Mon Aug 08, 2016 5:51 pm

I meant the writing commands "append file" and "write file".
They use control codes below 0x20 (f. i. 0x1A, 0x0D). These control codes mustn't occur in the data-stream.
But we will go into detail, when you have received your sparkfun openlog.
I'll be back!

Senior Member
Posts: 116
Joined: Mon Mar 02, 2015 10:53 am
Calculators: Casio fx-CG20

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby AmazoNKA » Mon Aug 08, 2016 11:43 pm

I have just received it today - my god it's tiny - I didn't expect it to be so small - probably not breadboard compatible - I will check a bit later but someone else will need to solder it for me. Just want to double check with you if I need to cross tx and rx or does tx from calculator goes to tx on openlog and so on please. Thanks again.

Regarding writing to sd I imagine it is less important than being able read binaries from sd to be copied over to the calculator so even with some writing limitations it will be quite valuable expansion of calculator's functionality (at least to begin with. And perhaps later better bootloader can be applied to openlog or some workaround on calculator side can be designed to deal with control codes.)

I'm really impressed with your progress and feel that I'm only slowing you down with my questions but I truly appreciate your answers and hope you don't mind me being so scattered and not up to your speed.

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Tue Aug 09, 2016 6:10 am

This tiny little thing is valuable, indeed.

Concerning your questions: No bother. No bother.
I am glad, that you had this idea. It is a very interesting project.

Concerning the soldering: I will post a detailed description of how I interfaced the "board".
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Wed Aug 10, 2016 9:39 am

Manufacturers documentation: Show
OpenLog pinout
Connections
GRN: Reset pin and connects to the GRN pin on the Arduino Pro Mini. Pulling this line low will reset the ATmega328. Because there is a capacitor on this line, holding this line low will not keep OpenLog in reset.
RXI: Serial input into OpenLog.
TXO: Serial output from OpenLog.
VCC: 3.3V to 12V input. We recommend 3.3V to 5V.
GND: Ground
BLK: This pin is connected to GND. Connect this pin to BLK on the Arduino Pro Mini.

Connections to some fx-calculator:

GRN and BLK: not used
RXI: connect to Stereo 2.5 mm plug tip
TXO: connect to Stereo 2.5 mm plug middle
GND: connect to Stereo 2.5 mm plug base and to GND of the power supply
VCC: connect to VCC of the power supply

I use an USB standard A plug to power the sparkfun openlog.
I connected pin 1 of the USB connector to VCC and pin 4 of the USB connector to GND (see https://en.wikipedia.org/wiki/USB "5.2.1 standard connectors").

AmazoNKA wrote:I ... feel that I'm only slowing you down with my questions but I truly appreciate your answers and hope you don't mind me being so scattered and not up to your speed.
You are not slowing me down. In the first place I want to check for the basic capabilities of and for the problems with the openlog's serial interface. I am just curious. The last thing to check is the READ RAW thing. I implemented some test-functions in INSIGHT.G1A. I will check with INSIGHT.G3A, if there are special problems with the Prizm. Then I'll be ready for the time being. There will be enough work left for you with the user interface.
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Thu Aug 11, 2016 6:04 pm

I checked the "read file" function. It works as expected (ASCII, HEX and RAW).
Additionally I tried the communication on a Prizm. No problems encountered.
I'll be back!

Senior Member
Posts: 116
Joined: Mon Mar 02, 2015 10:53 am
Calculators: Casio fx-CG20

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby AmazoNKA » Thu Aug 11, 2016 11:27 pm

That's such a great news and progress.

After reading your chm documentation am I correct in assuming that insight's source code is part of your mini sdk? Sorry if i got it wrong but i never managed to find insight's specific source code so perhaps it is because i have never used mini sdk?

Thanks again

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Fri Aug 12, 2016 10:17 am

AmazoNKA wrote:After reading your chm documentation am I correct in assuming that insight's source code is part of your mini sdk? Sorry if i got it wrong but i never managed to find insight's specific source code so perhaps it is because i have never used mini sdk?
That has been in early 2011, when I started exploring the Prizm and publishing my first results:
https://www.omnimaga.org/casio-prizm/co ... #msg174367
https://www.omnimaga.org/casio-prizm/ca ... #msg174654
I already ceased publishing the miniSDK (and the INSIGHT-source) in these days. The miniSDK is intended to support fx-9860, fx-CG as well as fx-CP. Hence it is a bit complicated.
Nowadays I use INSIGHT to verify various ideas. It partly contains experimental code, which is not intended for general use.
The source is distributed over a lot of modules/libraries/headerfiles. Some of the modules/libraries/headerfiles are automatically generated by the miniSDK (f. i. syscalls).
Possibly would be a lot of work to get the complete source running on a different development-environment.

Concerning the sparkfun-project the following code is essential:
SparkFun.hpp: Show
Code: Select all
// syscalls are defined in syscall.hpp and syscall.cpp
// this file is used for derived functions

#ifndef __SPARKFUNCLASS_HPP__
#define __SPARKFUNCLASS_HPP__

#include "fx.hpp"

#include "tools.hpp"
#include "keyboard.hpp"
#include "serial.hpp"
#include "common.hpp"
#include "viewtext.hpp"

//#include "INSIGHT_common.hpp"
//#include "MemViewClass.hpp"
//#include "mcs.hpp"
//#include "app.hpp"
//#include "serial.hpp"
//#include "otools.hpp"


int SparkfunDialog();

class TSparkFunOpenLog {
public:
   // constructor
   TSparkFunOpenLog( void ){
      FAppending = FWriting = 0;
      FEchoOn = FVerboseOn = -1;
      FTimeOut = 100;
   }
   // destructor
   virtual ~TSparkFunOpenLog();
   
   int Open( void );
   int WaitReplay( void );
   int Close( void );
   int Query( void ); // ?
   int List( void ); // ls
   int Disk( void ); // disk
   int Init( void ); // init
   int Sync( void ); // sync
   int Reset( void ); // reset
   int NewFile( char*filename_8_3 ); // new file
   int AppendFile( char*filename_8_3 ); // append file
   int CloseAppendFile( void ); // send escape
   int ReadFile( char*filename_8_3, char*start, char*length, char*type  ); // append file
   int CommandMode( void );
   int SendData( void*buffer, int len );
   int Write( char*string );
   int WriteLn( char*string );
   int Baud( char*string ); // baud
   int WriteFile( char*filename_8_3, char*offset ); // write file
   int WriteFileLn( char*string );
   int CloseWriteFile( void ); // WriteFileLn( "" )
   int CatFile( char*filename_8_3 ); // read file ... HEX (cat is not supported any more since version 2.0)
   int SizeFile( char*filename_8_3 ); // size file
   int RemoveFile( char*filename_8_3 ); // rm file
   int ReadLn( char*buffer, int nMax );
   int ReadUntilChar( char*buffer, char terminator, int nMax );
   int Check( void );
   int Echo( int ON );
   int Verbose( int ON );
   
protected: 

private:
   int FAppending, FWriting, FTimeOut;
   int FEchoOn, FVerboseOn;
   
   int FSendCommand( char*_command );
   int FSendData( void*buffer, int len );
};

#endif
SparkFun.cpp: Show
Code: Select all
#ifndef __SPARKFUNCLASS_CPP__
#define __SPARKFUNCLASS_CPP__

extern "C" {

#include "sparkfun.hpp"

#ifdef fxCG
void Wait_ms( int duration ){OS_InnerWait_ms( duration );}
int LongToAsc(int value, unsigned char *dest, int digits){ itoa(value, dest); return 0; }
#endif

unsigned char mode96[] = {0,BAUD_9600,PARITY_NO,DATALENGTH_8,STOP_ONE,0};
unsigned char mode192[] = {0,BAUD_19200,PARITY_NO,DATALENGTH_8,STOP_ONE,0};
unsigned char mode1152[] = {0,BAUD_115200,PARITY_NO,DATALENGTH_8,STOP_ONE,0};

// ************************************************
// ************************************************
// ************************************************
/*
destructor
si 12.08.2016
*/
TSparkFunOpenLog::~TSparkFunOpenLog(){
   Close();
}

/*
Opens the serial interface.
refer to https://github.com/sparkfun/OpenLog/wiki/Config-File
si 11.08.2016
*/
int TSparkFunOpenLog::Open( void ){
int iResult;   
//   iResult = Serial_Open( mode96 );
//   iResult = Serial_Open( mode192 );
   iResult = Serial_Open( mode1152 );
   return 0;
}

/*
reads until 0x0D/0x0A has been received or a timeout has occurred.
0x0D/0x0A are not included in the return-buffer
si 11.08.2016
*/
int TSparkFunOpenLog::ReadLn( char*buffer, int nMax ){
int start_time, iResult;
int iReceived;
unsigned char b, lastchar;
   iReceived = 0;
   lastchar = 0;
   start_time = RTC_GetTicks();
   while (1){
      iResult = Serial_ReadOneByte( &b );
      if ( iResult == 0 ){
         start_time = RTC_GetTicks();
         if ( b == 0x0A ){
            if ( lastchar == 0x0D ){
               iReceived--;
               break;
            }   
         }
         buffer[ iReceived ] = b;
         if ( iReceived < nMax - 1 ) iReceived++;
         lastchar = b;
      };
      if ( RTC_Elapsed_ms( start_time, FTimeOut ) ) break;
   }   
   buffer[ iReceived ] = 0;
   return iReceived;
};

#define SIZE000 1000
#define SIZE001 5000

/*
reads any output of the sparkfun openlog into a TTextView-buffer until a timeout occurs
finally displays the result using TTextView.Execute
si 11.08.2016
*/
//#define WAITREPLY_1
#define WAITREPLY_2
//#define WAITREPLY_3

int TSparkFunOpenLog::WaitReplay( void ){
char hb[SIZE000];
char buffer[SIZE001];
int iResult;
TTextView*text;

#if defined(WAITREPLY_1) | defined(WAITREPLY_3)
int idx, idy, iWork;
int iOutput, start_value;
unsigned char b;
#endif
#if defined(WAITREPLY_3)
char hexb[10];
#endif

   memset( buffer, 0, SIZE001 );
   text = new TTextView;
   (*text).buffer = buffer;

#ifdef WAITREPLY_1
   idy = 1;
   idx = 0;
   iOutput = 0;
   start_value = RTC_GetTicks();
#endif
#if defined(WAITREPLY_3)
   hb[0] = 0;
#endif
   while (1){
      // process serial interface
#ifdef WAITREPLY_3
      iResult = Serial_ReadOneByte( &b );
      if ( iResult == 0 ){
         start_value = RTC_GetTicks();
         ByteToHex( b, (unsigned char*)hexb );
         hexb[2] = ' ';
         hexb[3] = 0;
         strcat( hb, hexb );
         iOutput++;
         if ( iOutput >= 10 ){
            if ( strlen( buffer ) + iOutput*3 < SIZE001 - 2 ){
               strcat( buffer, hb );
               strcat( buffer, "\x0D\x0A" );
            }   
            hb[0] = 0;
            iOutput = 0;
         }
      };
      // process keyboard
//      iResult = PRGM_GetKey();
//      if ( iResult == KEY_PRGM_EXIT ) break;
      if ( RTC_Elapsed_ms( start_value, FTimeOut ) ){
         if ( iOutput ){
            if ( strlen( buffer ) + iOutput*3 < SIZE001 - 2 ){
               strcat( buffer, hb );
               strcat( buffer, "\x0D\x0A" );
            }   
         }
         break;
      }   
#endif
#ifdef WAITREPLY_2
      iResult = ReadLn( hb, SIZE000 );
      if ( !iResult ) break;
      if ( strlen( buffer ) + iResult < SIZE001 - 2 ){
         strcat( buffer, hb );
         strcat( buffer, "\x0D\x0A" );
      }   
#endif
#ifdef WAITREPLY_1
//      iWork = Serial_GetReceivedBytesAvailable();
      iResult = Serial_ReadOneByte( &b );
      if ( iResult == 0 ){
         start_value = RTC_GetTicks();
         if ( b == 0x0A ){
         }else if ( b == 0x0D ){
            iOutput = 1;
         }
         if ( iOutput ){
            iOutput = 0;
            hb[ idx ] = 0;
            if ( strlen( buffer ) + idx < SIZE001 - 2 ){
               strcat( buffer, hb );
            }   
            idx = 0;
         }else{
            hb[ idx ] = b;
            idx++;
            if ( idx >= SIZE000 ) idx = SIZE000 - 1;
         }   
      };
      // process keyboard
//      iResult = PRGM_GetKey();
//      if ( iResult == KEY_PRGM_EXIT ) break;
      if ( RTC_Elapsed_ms( start_value, FTimeOut ) ) break;
#endif

   }   
   (*text).Execute(0);
   delete text;
   
   return iResult;
};

/*
closes the serial interface
si 12.08.2016
*/
int TSparkFunOpenLog::Close( void ){
   // wait for transmissions under way
   while ( Serial_Close( 0 ) == 5 );
   return 0;
}

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Once you're in command mode the list of available commands can be brought up by typing ?"
si 12.08.2016
*/
int TSparkFunOpenLog::Query( void ){
   return FSendCommand( "?" );
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Directory Manipulation"
si 12.08.2016
*/
int TSparkFunOpenLog::List( void ){
   return FSendCommand( "ls" );
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "System Settings"
si 12.08.2016
*/
int TSparkFunOpenLog::Echo( int ON ){
   if ( ON ) FSendCommand( "echo on" );
   else FSendCommand( "echo off" );
   return 1;
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "System Settings"
si 12.08.2016
*/
int TSparkFunOpenLog::Verbose( int ON ){
   if ( ON ) FSendCommand( "verbose on" );
   else FSendCommand( "verbose off" );
   return 1;
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Low Level Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::Disk( void ){
   return FSendCommand( "disk" );
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Low Level Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::Init( void ){
   return FSendCommand( "init" );
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Low Level Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::Sync( void ){
   return FSendCommand( "sync" );
}

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Low Level Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::Reset( void ){
   return FSendCommand( "reset" );
};

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "System Settings"
si 12.08.2016
*/
int TSparkFunOpenLog::Baud( char*string ){
   FSendCommand( "baud" );
   FSendCommand( string );
   return 1;
};

#define maxCommandReplySize 100
/*
intended to switch to command mode
perhaps it is better to edit config.txt accordingly
si 12.08.2016
*/
int TSparkFunOpenLog::CommandMode( void ){
int start_value;   
unsigned char buffer[maxCommandReplySize];
short actually_transferred;
// send an invalid command
   FSendCommand( "xyz" );
   Wait_ms( 100 );
// if not in command mode, the sparkfun openlog will not send an echo
   Serial_ReadNBytes( buffer, maxCommandReplySize, &actually_transferred );
   if ( actually_transferred == 0 ){
// not in command mode, send escape sequence
      Write( "\x1A\x1A\x1A" );
      Wait_ms( 100 );
      Serial_ReadNBytes( buffer, maxCommandReplySize, &actually_transferred );
   }   
   
//   start_value = RTC_GetTicks();
//   while (1){
//      iWork = Serial_GetReceivedBytesAvailable();
//      if ( RTC_Elapsed_ms( start_value, 1000 ) ){
//         // elapsed
//         break;
//      };
//   };   

   return actually_transferred;
};

/*
Write a string to the serial interface
si 12.08.2016
*/
int TSparkFunOpenLog::Write( char*string ){
   return FSendData( (void*)string, strlen( string ) );
};

/*
Write a string to the serial interface, terminated with "\x0D\x0A"
si 12.08.2016
*/
int TSparkFunOpenLog::WriteLn( char*string ){
   Write( string );
   return Write( "\x0D\x0A" );
};

#define CommandBufferSize 40

/*
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Basic Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::NewFile( char*filename_8_3 ){
char command[CommandBufferSize];
   strcpy( command, "new " );
   strcat( command, filename_8_3 );
   return FSendCommand( command );
};

/*
initialize "append file"-command
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Basic Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::AppendFile( char*filename_8_3 ){
char command[CommandBufferSize];
   FAppending = 1;
   strcpy( command, "append " );
   strcat( command, filename_8_3 );
   return FSendCommand( command );
};

/*
finalize "append file"-command
si 12.08.2016
*/
int TSparkFunOpenLog::CloseAppendFile( void ){
   if ( FAppending ){
      FAppending = 0;
      return Write( "\x1A" );
   } else return -1;
};

/*
initialize "write file"-command
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Basic Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::WriteFile( char*filename_8_3, char*offset ){
char command[CommandBufferSize];
   FWriting = 1;
   strcpy( command, "write " );
   strcat( command, filename_8_3 );
   strcat( command, " " );
   strcat( command, offset );
   return FSendCommand( command );
};

/*
send data in "write file"-mode
si 12.08.2016
*/
int TSparkFunOpenLog::WriteFileLn( char*string ){
   Write( string );
//   return Write( "\x0A" );
   return Write( "\x0D" );
//   return Write( "\x0D\x0A" );
//   return Write( "\x0A\x0D" );
};

/*
finalize "write file"-command
si 12.08.2016
*/
int TSparkFunOpenLog::CloseWriteFile( void ){
   if ( FWriting ){
      FWriting = 0;
      return WriteFileLn( "" );
   } else return -1;
};

/*
"read file"-command
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Viewing Files"
si 12.08.2016
*/
int TSparkFunOpenLog::ReadFile( char*filename_8_3, char*start, char*length, char*type  ){ // read file
char command[CommandBufferSize];
   strcpy( command, "read " );
   strcat( command, filename_8_3 );
   strcat( command, " " );
   strcat( command, start );
   strcat( command, " " );
   strcat( command, length );
   strcat( command, " " );
   strcat( command, type );
   return FSendCommand( command );
};

/*
"cat file"-command (depricated since version 2.0 (https://github.com/sparkfun/OpenLog/blob/master/CHANGELOG.md))
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Viewing Files"
si 12.08.2016
*/
int TSparkFunOpenLog::CatFile( char*filename_8_3 ){
char command[CommandBufferSize];
   strcpy( command, "read " );
   strcat( command, filename_8_3 );
   // TYPE=HEX
   strcat( command, " 0 10000 2" );
   return FSendCommand( command );
};

/*
"size file"-command
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Basic Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::SizeFile( char*filename_8_3 ){
char buffer[20];
char command[CommandBufferSize];
int iResult;
   strcpy( command, "size " );
   strcat( command, filename_8_3 );
   FSendCommand( command );
   iResult = ReadLn( buffer, 20 ); // read first line (this is irrespective of echo setting)
   iResult = ReadLn( buffer, 20 ); // read answer
   iResult = atoi( buffer );
   ReadLn( buffer, 20 ); // read prompt
   return iResult;
};

/*
"rm file"-command
refer to: https://github.com/sparkfun/OpenLog/wiki/Command-Set "Basic Commands"
si 12.08.2016
*/
int TSparkFunOpenLog::RemoveFile( char*filename_8_3 ){
char command[CommandBufferSize];
   strcpy( command, "rm " );
   strcat( command, filename_8_3 );
   return FSendCommand( command );
};

//
int TSparkFunOpenLog::SendData( void*buffer, int len ){
   return FSendData( buffer, len );
};

//
int TSparkFunOpenLog::FSendCommand( char*_command ){
   Write( _command );
   return Write( "\x0D" );
};

//
int TSparkFunOpenLog::FSendData( void*buffer, int len ){
   return Serial_BufferedTransmitNBytes( (unsigned char*)buffer, len );
};

// reads max. nMax serial data until terminator has been received.
int TSparkFunOpenLog::ReadUntilChar( char*buffer, char terminator, int nMax ){
int start_time, iResult;
int iReceived;
unsigned char b;
   iReceived = 0;
   start_time = RTC_GetTicks();
   while (1){
      iResult = Serial_ReadOneByte( &b );
      if ( iResult == 0 ){
         if ( b == terminator ) break;
         buffer[ iReceived ] = b;
         if ( iReceived < nMax - 1 ) iReceived++;
         start_time = RTC_GetTicks();
      };
      if ( RTC_Elapsed_ms( start_time, FTimeOut ) ) break;
   }   
   buffer[ iReceived ] = 0;
   return iReceived;
};

#define ans1 "xyz\x0D\x0D\x0Aunknown command: xyz\x0D\x0A!"
#define ans2 "\x0D\x0Aunknown command: xyz\x0D\x0A!"
#define ans3 "xyz\x0D\x0D\x0A\x0D\x0A!"
#define ans4 "\x0D\x0A!"
/*
sends an invalid command and checks the reply.
depending on the result, the function detects the ECHO- and VERBOSE-setting.
si 12.08.2016
*/
int TSparkFunOpenLog::Check( void ){
char buffer[40];
   FSendCommand( "xyz" ); // send unknown command
   ReadUntilChar( buffer, '>', 40 );
   FEchoOn = 0x1000;
   FVerboseOn = 0x1000;
   if ( !strcmp( buffer, ans1 ) ){ FEchoOn = 1; FVerboseOn = 1; };
   if ( !strcmp( buffer, ans2 ) ){ FEchoOn = 0; FVerboseOn = 1; };
   if ( !strcmp( buffer, ans3 ) ){ FEchoOn = 1; FVerboseOn = 0; };
   if ( !strcmp( buffer, ans4 ) ){ FEchoOn = 0; FVerboseOn = 0; };
   return ( FEchoOn << 1 ) + FVerboseOn;
}

// ************************************************
////////////////////////////////////////////
// Sparkfun OpenLog Dialog

// select function
char*SelectFunction( char*Heading, char*List ){
TStrListView*slv;
char*cResult;
int iResult;
//unsigned int key;

   cResult = 0;

   slv = new TStrListView;
   
   (*slv).frame_color = 0xFFFF;
   
   (*slv).SetFlags( (*slv).GetFlags() | FLAG_EXIT_ON_EXE );
   (*slv).SetHeading( Heading );
   (*slv).Assign( List );
   
   while(1){
      iResult = (*slv).browse();
      if ( lvmKEY + KEY_CTRL_EXE == iResult ){
         cResult = (*slv).SelectedItem();
        break;
      }
      if ( lvmKEY + KEY_CTRL_EXIT == iResult ) break;
   }
   
   delete slv;
   return cResult;
}


#define cmdDISK "disk\0"
#define cmdLIST "ls\0"
#define cmdQUERY "?\0"
#define cmdNEW "new file\0"
#define cmdWRITE "write file\0"
#define cmdAPPEND "append file\0"
#define cmdREAD "read file\0"
#define cmdCAT "cat\0"
#define cmdSIZE "size file\0"
#define cmdREMOVE "remove\0"
#define cmdINIT "init\0"
#define cmdSYNC "sync\0"
#define cmdRESET "reset\0"
#define cmdCHECK "check\0"
#define cmdECHO "echo\0"
#define cmdVERBOSE "verbose\0"
#define cmdCLEARLOGS "clear logs\0"
#define cmdBAUD "baud\0"

const char*SparkfunFunctions =
cmdLIST
cmdQUERY
cmdDISK
cmdWRITE
cmdAPPEND
cmdREAD
cmdCAT
cmdSIZE
cmdREMOVE
cmdINIT
cmdSYNC
cmdRESET
cmdCHECK
cmdECHO
cmdVERBOSE
cmdBAUD
cmdCLEARLOGS
cmdNEW
"\0";

#define cmdOn "ON\0"
#define cmdOff "off\0"

const char*OnOff =
cmdOn
cmdOff
"\0";

#define cmdBaud300 "300\0"
#define cmdBaud600 "600\0"
#define cmdBaud1200 "1200\0"
#define cmdBaud2400 "2400\0"
#define cmdBaud4800 "4800\0"
#define cmdBaud9600 "9600\0"
#define cmdBaud19200 "19200\0"
#define cmdBaud38400 "38400\0"
#define cmdBaud57600 "57600\0"
#define cmdBaud115200 "115200\0"

const char*BaudRates =
cmdBaud300
cmdBaud600
cmdBaud1200
cmdBaud2400
cmdBaud4800
cmdBaud9600
cmdBaud19200
cmdBaud38400
cmdBaud57600
cmdBaud115200
"\0";

#define cmdASCII "1\0"
#define cmdHEX "2\0"
#define cmdRAW "3\0"

const char*ReadTypes =
cmdASCII
cmdHEX
cmdRAW
"\0";

#define NoWaitReplay 1
#define ShowIResultHex 2
#define ShowIResult 4

// ************************************************
int SparkfunDialog(){
int iResult;
char*cResult;
char*cSubSelect;
TSparkFunOpenLog*sfol;
unsigned int Flags;
unsigned int key;
unsigned char hb[30];

   while (1){
      Flags = 0;
      cResult = SelectFunction( (char*)"SparkFun OpenLog", (char*)SparkfunFunctions );
      if ( !cResult ) break;
      if ( cResult ){
         sfol = new TSparkFunOpenLog;
         (*sfol).Open();
         iResult = (*sfol).CommandMode();
      }
      
      if ( !strcmp( cResult, cmdLIST ) ){
         (*sfol).List();
      }else if ( !strcmp( cResult, cmdQUERY ) ){
         (*sfol).Query();
      }else if ( !strcmp( cResult, cmdDISK ) ){
         (*sfol).Disk();
      }else if ( !strcmp( cResult, cmdCLEARLOGS ) ){
         (*sfol).RemoveFile( "LOG*.txt" );
      }else if ( !strcmp( cResult, cmdNEW ) ){
         (*sfol).NewFile( "neu.txt" );
      }else if ( !strcmp( cResult, cmdWRITE ) ){
         (*sfol).WriteFile( "neu.txt", "10" );
         (*sfol).WriteFileLn( "1. eeeee" );
         (*sfol).WriteFileLn( "2. fffff" );
         (*sfol).WriteFileLn( "3. ggggg" );
         (*sfol).CloseWriteFile();
      }else if ( !strcmp( cResult, cmdCAT ) ){
         (*sfol).CatFile( "neu.txt" );
      }else if ( !strcmp( cResult, cmdAPPEND ) ){
         (*sfol).AppendFile( "neu.txt" );
         (*sfol).WriteLn( "1. Zeile" );
         (*sfol).WriteLn( "2. Zeile" );
         (*sfol).WriteLn( "3. Zeile" );
         (*sfol).CloseAppendFile();
      }else if ( !strcmp( cResult, cmdSIZE ) ){
         iResult = (*sfol).SizeFile( "neu.txt" );
         Flags = Flags | NoWaitReplay | ShowIResult;
      }else if ( !strcmp( cResult, cmdREMOVE ) ){
         (*sfol).RemoveFile( "neu.txt" );
      }else if ( !strcmp( cResult, cmdINIT ) ){
         (*sfol).Init();
      }else if ( !strcmp( cResult, cmdSYNC ) ){
         (*sfol).Sync();
      }else if ( !strcmp( cResult, cmdRESET ) ){
         (*sfol).Reset();
      }else if ( !strcmp( cResult, cmdBAUD ) ){
         cSubSelect = SelectFunction( cResult, (char*)BaudRates );
         (*sfol).Baud( cSubSelect );
      }else if ( !strcmp( cResult, cmdECHO ) ){
         cSubSelect = SelectFunction( cResult, (char*)OnOff );
         if ( !strcmp( cSubSelect, cmdOn ) ) (*sfol).Echo(1);
         if ( !strcmp( cSubSelect, cmdOff ) ) (*sfol).Echo(0);
      }else if ( !strcmp( cResult, cmdREAD ) ){
         cSubSelect = SelectFunction( cResult, (char*)ReadTypes );
         (*sfol).ReadFile( "neu.txt", "0", "10000", cSubSelect );
      }else if ( !strcmp( cResult, cmdVERBOSE ) ){
         cSubSelect = SelectFunction( cResult, (char*)OnOff );
         if ( !strcmp( cSubSelect, cmdOn ) ) (*sfol).Verbose(1);
         if ( !strcmp( cSubSelect, cmdOff ) ) (*sfol).Verbose(0);
      }else if ( !strcmp( cResult, cmdCHECK ) ){
         iResult = (*sfol).Check();
         Flags = Flags | NoWaitReplay | ShowIResultHex;
      };
      
      if ( cResult ){
         if ( !( Flags & NoWaitReplay ) ) (*sfol).WaitReplay();
         if ( Flags & ( ShowIResultHex | ShowIResult ) ){
            Bdisp_AllClr_VRAM();
            locate( 1, 1 );
            PrintLine( (unsigned char*)cResult, 21 );
            memset( hb, 0, sizeof( hb ) );
            if ( Flags & ShowIResultHex ) IntToHex( iResult, hb );
            else if ( Flags & ShowIResult ) LongToAsc( iResult, hb, 10 );
            locate( 1, 2 );
            PrintLine( hb, 21 );
            GetKey( &key );
         }
         
         delete sfol;
      }
   }
   
   return 1;
}


// ************************************************
// ************************************************

}

#endif
The code is intended for reference only. There are some classes or modules, which source is not included, f. i. TStrListView and TTextView. These objects are related to the user interface.
The essential part, which serves the serial communication, works both with fx-9860 and fx-CG.
I will comment the code and update this post.
I'll be back!

Senior Member
User avatar
Posts: 605
Joined: Sat Sep 15, 2012 6:59 am
Location: Krautland ****
Calculators: Casio fx-7400GII, Casio fx-7400GII (SH4), Casio fx-9750GII, Casio fx-9750GII (SH4), Casio fx-9860G, Casio fx-9860G SD, Casio fx-9860G Slim, Casio fx-9860GII SD, Casio fx-9860GII SD Power Graphic 2, Casio Classpad 330 plus, Casio fx-CG20, Casio fx-CG50, Casio Classpad fx-CP400

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby SimonLothar » Fri Aug 12, 2016 6:49 pm

A little drawback: It seems that 115200 baud is not reliable. Sometimes the upper bit of a byte gets lost.
Due to the fact, that in the last 8 years I experienced the serial performance of the fx-calculators as being excellent at any speed, I blame the sparkfun openlog.
If I understood the Change Log right (f. i. version [3.2]), the serial module of the sparkfun openlog is not a piece of hardware, but part of the firmware, hence susceptible to programming errors. I am surprised.
My openlog has firmware version 3.3. Perhaps with version 4.0 things are better.
Luckily 57600 baud seems to be reliable.

---
"append file" seems to be appropriate to write any binary data except the escape-sequence (which is - contrary to the documentation - \x1A\x1A\x1A by default). That could be mended with padding. We should not stick to the hope, that the escape-sequence is not part of the data to write.
Up to firmware version 3.3 the escape-sequence is written to the file, too. According to the Change Log this is not an issue any more with version 4.0.
I'll be back!

Senior Member
Posts: 116
Joined: Mon Mar 02, 2015 10:53 am
Calculators: Casio fx-CG20

Re: Casio fx-9860G SD- How to read files in the sd card?

Postby AmazoNKA » Fri Aug 12, 2016 8:37 pm

Thanks for both replies. I haven't followed sparkfun versioning properly to be sure what I received... But checked that the pin holes spacing seems breadboard compatible :-) so hopefully I will get it connected soon. I ordered mine directly from sparkfun so i may have the latest version... However I'm leaving for holidays in a few hours so won't have access to all the hardware for some time - hopefully i will be able to test if my firmfirmware is better with any of those things. All the best wishes in meantime

PreviousNext

Return to General

Who is online

Users browsing this forum: No registered users and 3 guests