Register

Serial communications

Discuss issues related to Calculator Hacking/Modding.
Senior Member
User avatar
Posts: 101
Joined: Sun Mar 27, 2016 10:24 am
Location: France
Calculators: Casio Afx 1.0, Casio fx-9860GII, Casio fx-CG50

Re: Serial communications

Postby cakeisalie5 » Fri Feb 10, 2017 12:04 am

I have a stupid question. It's about how you manage CESG502 *and* serial communications.

For what I've found, CESG502 requires a buffer bigger than the data actually received, otherwise it will return a ERROR_GEN_FAILURE.
Also, for serial devices like the FTDI thingy Util Pocket uses for its USB/serial cable, you need to put in the actual number of bytes you will receive (the buffering is managed internally).

So these are two incompatible ways to call ReadFile (lpNumberOfBytesRead must have two different values). Because of the design of the libp7, I have to find a way to distinguish what type of buffering the driver behind is using, using either the device path or the handle. I have tried various things, but no result for now... maybe you know a reliable way to find out if CESG502 is the driver behind the handle? Thanks in advance if you know ;)

My current guess (returns error 0x57, I have no idea why):
[EDIT: thanks to an answer on StackOverflow, I now know this device I/O control call is not correct at all]
Code: Select all
/* get product data */
CHANGER_PRODUCT_DATA ProductData;
DWORD ReturnedBytes = 0;
DWORD wsuccess = DeviceIoControl(fhandle, IOCTL_CHANGER_GET_PRODUCT_DATA,
    NULL, 0, &ProductData, sizeof(CHANGER_PRODUCT_DATA),
    &ReturnedBytes, 0);
if (wsuccess) logr_info("SUCCESS!");
else logr_info("Error #0x%08lx occurred", GetLastError());
Last edited by cakeisalie5 on Sat Feb 11, 2017 2:40 am, edited 1 time in total.
Part of the Planète Casio community (FR) - main author of Cahute

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: Serial communications

Postby SimonLothar » Sat Feb 11, 2017 2:08 am

I am not sure, if I understood your question right.
If you use a filename like "COMx", you use the serial interface, t. i. CESG502 is not involved.
If you use a filename, which you found by searching device "VID_07CF&PID_6101", you use USB. And then CESG502 is involved.

Apart from the command "SET LINK SETTINGS", which makes no sense for USB, I use the same transfer procedures for USB and serial communication in my program.
In the readfile/writefile-layer there are no differences to heed for. Luckily the differences between USB and serial are handled internally.
So I can use a lot of common code.
I'll be back!

Senior Member
User avatar
Posts: 101
Joined: Sun Mar 27, 2016 10:24 am
Location: France
Calculators: Casio Afx 1.0, Casio fx-9860GII, Casio fx-CG50

Re: Serial communications

Postby cakeisalie5 » Sat Feb 11, 2017 2:38 am

SimonLothar wrote:If you use a filename like "COMx", you use the serial interface, t. i. CESG502 is not involved.

Actually, I recently discovered that serial devices don't have to use the COMx or \\.\COMxx name format, see this article (I'm trying to get the OS theories right so my lib can work in a maximum of cases).
Also, I can't really have this approach in libp7 without doing it in an ugly way. I'm looking for a more failproof method... x)

SimonLothar wrote:In the readfile/writefile-layer there are no differences to heed for. Luckily the differences between USB and serial are handled internally.

... so at first, I was wondering how you managed to not get the ERROR_GEN_FAILURE. Then I understood that we had different approaches to this.
What I deduce is that you read exactly the number of bytes you are expecting, like, you're following exactly the logic of the what you receive from the driver.

The libp7 approach is slightly different, because, for example, I start off reading the packet type first (one byte) in order to distinguish whether to read screenstreaming or "normal" packet, and the driver probably doesn't like that... I'll investigate on how exactly the driver sends the data then. >_>

EDIT: So in fact I don't understand. I used an old FA-124 capture and checked if my theory (the driver first sends like, the first 6 bytes [the absolute minimum size of a packet], and if there is, in these six bytes, more to read, then the exact amount of bytes to read should be known... and even, no, you'd need to read at least 8 bytes for this) was right, but no: for example, the beginning of the EACK packet is sent in one go (063032313030413447...). And if I try to read less than this amount, CESG502 will send me a ERROR_GEN_FAILURE, and if I want to read more, then the approach won't work with serial devices, which require to read less or the exact number of bytes received in order to return immediately (otherwise, it'll wait for other bytes to come).

[here's the current way libp7 reads the packet data progressively]
So I'm a bit stuck here. How do you read a packet progressively?
Part of the Planète Casio community (FR) - main author of Cahute

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: Serial communications

Postby SimonLothar » Sat Feb 11, 2017 5:46 pm

I dug a bit deeper and had a look at nearly ten years old code. During the week I have been a bit short of time.
Indeed there is a difference between serial and USB.

In case of the serial interface,l it is possible to read one byte at a time.
serial: Show
Code: Select all
////////// serial //////////
FUNCTION tSio.GetOne( p : pointer ) : DWORD;
begin
  ReadFile( Handle, PCHAR(p)[0], 1, result, pO );
end;

In case of the USB interface,l it seems to be impossible to call readfile with nNumberOfBytesToRead==1. At least this is what I dimly remember, now, at last.
I used an intermediate 512 byte buffer.
If this buffer is empty, the next action of GetOne is trying to call readfile with nNumberOfBytesToRead==512.
If this buffer is not empty, the next action of GetOne is returning the next byte in the intermediate buffer.
USB: Show
Code: Select all
////////// USB //////////
const
  internalUSB_INBUFFERSIZE = 512;

var
  FUSB_INBuffer : array[ 1..internalUSB_INBUFFERSIZE ] of char;

/////
FUNCTION TUSB.GetOne( p : pointer ) : DWORD;
var
  iRead : DWORD;
  le : DWORD;
  s : string;
begin
  if FUSB_INBufferContent = 0 then begin
    ReadFile( FHandle, FUSB_INBuffer, internalUSB_INBUFFERSIZE, iRead, FpO ) then begin
    FUSB_INBufferContent := iRead;
    FUSB_INBufferPtr := 1;
  end;

  if FUSB_INBufferContent > 0 then begin
    PCHAR(p)[0] := FUSB_INBuffer[ FUSB_INBufferPtr ];
    if FUSB_INBufferPtr = FUSB_INBufferContent then begin
      FUSB_INBufferPtr := 1;
      FUSB_INBufferContent := 0;
    end
    else INC( FUSB_INBufferPtr );
    result := 1;
  end
  else result := 0;
end;
I'll be back!

Senior Member
User avatar
Posts: 101
Joined: Sun Mar 27, 2016 10:24 am
Location: France
Calculators: Casio Afx 1.0, Casio fx-9860GII, Casio fx-CG50

Re: Serial communications

Postby cakeisalie5 » Mon Feb 13, 2017 9:04 pm

So you're handling it in two different ways, as I can't do for now in libp7 (as the developer could send the USB device path directly to p7_cominit, and that shouldn't be forbidden or not recommended, as I think that's normal). So I'll keep looking out for this "find the handle's driver" method. :p

By the way, I've been trying other things, such as listening on the serial line in a direct transmission case, and I received this:
Code: Select all
0x10 0x10 0x10 0x10 0x10
0x10 0x10 0x10 0x10 0x10
0x05 0x30 0x30 0x30 0x37

Documentation says the 0x10 character is "Data Link Escape", and I found that there was no strict norm about how this character could be used. Also, here, it doesn't look like normal data escaping, so I don't really know how this thing work... do you? Thanks in advance :)
Part of the Planète Casio community (FR) - main author of Cahute

Senior Member
User avatar
Posts: 101
Joined: Sun Mar 27, 2016 10:24 am
Location: France
Calculators: Casio Afx 1.0, Casio fx-9860GII, Casio fx-CG50

Re: Serial communications

Postby cakeisalie5 » Wed Feb 15, 2017 5:27 pm

Also, Critor lent me his SB-88A cable (I was using a Util-Pocket cable until now), and it looks like the bytes that are not 0x10 are a little crappy (the 0x05,0x30,0x30,0x30,0x37 packet, with deformations that look random). Have you tried such a cable? Have you found any solution to this since fxRemote (as Critor stated to me the cable only did work with FA-124, not fxRemote)?

Thanks in advance :)
Part of the Planète Casio community (FR) - main author of Cahute

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: Serial communications

Postby SimonLothar » Thu Feb 16, 2017 5:56 am

cakeisalie5 wrote:So you're handling it in two different ways, as I can't do for now in libp7...
The USB-variant with an intermediate buffer should work for the serial interface as well. So it should be possible to work uniformly.
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: Serial communications

Postby SimonLothar » Thu Feb 16, 2017 6:26 am

cakeisalie5 wrote:ocumentation says the 0x10 character is "Data Link Escape", and I found that there was no strict norm about how this character could be used. Also, here, it doesn't look like normal data escaping, so I don't really know how this thing work...
I first noticed the 0x10 sequences with OsUpate-DLLs some time ago. But I did not investigate this. Perhape some synchronization means.
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: Serial communications

Postby SimonLothar » Thu Feb 16, 2017 7:15 am

cakeisalie5 wrote:Also, Critor lent me his SB-88A cable (I was using a Util-Pocket cable until now), and it looks like the bytes that are not 0x10 are a little crappy (the 0x05,0x30,0x30,0x30,0x37 packet, with deformations that look random). Have you tried such a cable? Have you found any solution to this since fxRemote (as Critor stated to me the cable only did work with FA-124, not fxRemote)?
I use self-assembled active cables only. These are most reliable. The passive cables like SB-88A use control lines as power supply. I usually initialize the serial interface with DCBFLAGSON=DTRON,RTSON and DCBFLAGSOFF=DTRHANDSHAKE,RTSHANDSHAKE. Perhaps you should experiment with DTRON and RTSON.

Some important source of information you can find here
I'll be back!

Senior Member
User avatar
Posts: 101
Joined: Sun Mar 27, 2016 10:24 am
Location: France
Calculators: Casio Afx 1.0, Casio fx-9860GII, Casio fx-CG50

Re: Serial communications

Postby cakeisalie5 » Mon Apr 03, 2017 4:06 pm

Just came here to say the cable now works whatever my DTR/RTS settings are (under Linux)... I don't know what the hell I did, but it works the same for the Util-Pocket cable (which is active) and SB-88A. I really don't know what I did to make it work. Here's the termios settings modifying process, and the default settings I use (values and flags are here), in case anyone is trying to do the same :)

Note that I didn't check if the Windows API stream works yet. I'm focusing on Linux right now, and on the library core.
Part of the Planète Casio community (FR) - main author of Cahute

Previous

Return to Calculator Hacking/Modding Discussions

Who is online

Users browsing this forum: Google [Bot] and 33 guests