Register

Serial port questions

Discuss issues related to the fx-9860G Software Development Kit
Senior Member
Posts: 68
Joined: Tue May 08, 2012 5:40 pm

Serial port questions

Postby happy » Wed Feb 27, 2013 9:04 am

Code: Select all
void serialOpen()
    {
    if (Serial_IsOpen() == 3)
       {
        unsigned char mode[6] = {0, 9, 0, 0, 0, 0};
        Serial_Open(mode);
        Serial_ClearReceiveBuffer();
        Serial_ClearTransmitBuffer();
       }
    return 1;
    }

void serialSend()
    {
    if (serialOpen() == 1)
        {
        int ret = -1;
        char buf[256];
        strcpy(buf, "hello");
       ret = Serial_BufferedTransmitNBytes((unsigned char *) buf, strlen(buf));
        }
    }

void serialReceive()
    {
    int ret = 0;
    short size = 0;
    unsigned char recv[256];
    memset(recv, '\0', 256);
    ret = Serial_ReadNBytes(recv, Serial_GetReceivedBytesAvailable(), &size);
    }

void serialReceiveTimer()
    {
    if (serialOpen() == 1)
        {
        serialReceive();
        }
    }


Questions:
1a) Serial_BufferedTransmitNBytes always returns 0. Whether the cable is plugged in or not. Is this the correct behaviour?

1b) If yes, I guess I would have to implement my own protocol to make sure recipient knows end-of-message and sends back an ack, etc.? Are there any best practices I should follow? (w.r.t to sending data back and forth on serial ports)

2) serialReceiveTimer() is set in a timer to periodically look for data. I saw Serial_SetInterruptHandler() in the docs, so is Serial_SetInterruptHandler(0, (void *) serialReceive), the right way to set up the receiver (and not use a timer)?

3) Serial_ReadNBytes always returned 1. Whether cable was connected or whether the sender sent something. Actually since it only returns 1, I have no way of verifying if my send code worked either! What am I doing wrong?

Senior Member
User avatar
Posts: 113
Joined: Sun Dec 16, 2012 2:59 pm
Calculators: None

Re: Serial port questions

Postby Casimo » Wed Feb 27, 2013 3:44 pm

1a) That's correct. The calc doesn't know whether you plugged the cable in or not (so I think).

1b) I tried this before. Here an idea (A is host, B client):
ClickMe: Show
Code: Select all
CONN_START = 0xFF
CONN_SUCESS = 0xFE

A: CONN_START, wait for CONN_SUCESS
B: wait for CONN_START, CONN_SUCESS

...
Now they are aligned.
...

CONN_DATASTART = 0xFFFD
CONN_DATAEND = 0xFFFC

A: CONN_DATASTART, data, CONN_DATAEND, wait for DATA_SUCESS
B: (CONN_DATASTART available?) read data until CONN_DATAEND, DATA_SUCESS

...
CONN_END = 0xFFB

A: CONN_END, wait for CONN_SUCESS
B: (CONN_END available?) CONN_SUCESS

...
End of transmit.

Another idea: send CONN_START, then the lenght of data (That could be even better).
I think that you are also able to invent your own protocol.

2) I don't know :D

3) 1 means that there's no byte to read. Something is wrong with your cable or the calculator or the other one didn't really send data.
Image

Senior Member
Posts: 68
Joined: Tue May 08, 2012 5:40 pm

Re: Serial port questions

Postby happy » Wed Feb 27, 2013 4:11 pm

Thanks Casimo. I will make my own protocol, just wanted to check if that's how people did serial port programming.

Knew what the return value meant, but was hoping Simon could point out any error in how I used the syscalls :) Don't have another cable to test with, yet..

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 port questions

Postby SimonLothar » Wed Feb 27, 2013 4:18 pm

happy wrote:1a) Serial_BufferedTransmitNBytes always returns 0. Whether the cable is plugged in or not. Is this the correct behaviour?
Yes. The function is not aware of any physical success.
It only commits the data to the transmit buffer and triggers the first transmit event.
The remaining data are transmitted by the serial transmit interrupt handler automatically until the buffer is empty.
Though, the function is aware of a closed serial channel or insufficient buffer space, giving error codes 3 or 2, resp..

happy wrote:1b) If yes, I guess I would have to implement my own protocol to make sure recipient knows end-of-message and sends back an ack, etc.? Are there any best practices I should follow? (w.r.t to sending data back and forth on serial ports)
Yes. A software handshake is the only way to apply a reliable failure detection.
There is no best practise.
A simple single byte-handshake accompanied by appropriate timeout checks should be sufficient in most cases(f. i. ENQ, ACK, NAK).
A rather sophisticated method would be protocol 7.00, which uses special character padding and checksums to ensure failure detection.
Though, I think protocol 7.00 is overkill for most applications.

happy wrote:2) serialReceiveTimer() is set in a timer to periodically look for data. I saw Serial_SetInterruptHandler() in the docs, so is Serial_SetInterruptHandler(0, (void *) serialReceive), the right way to set up the receiver (and not use a timer)?
No. The serial interrupt handler must follow certain rules, f. i. to maintain the buffer pointers and to set certain serial register bits to ensure proper further behaviour of the serial interrupt hardware.

happy wrote:3) Serial_ReadNBytes always returned 1. Whether cable was connected or whether the sender sent something. Actually since it only returns 1, I have no way of verifying if my send code worked either! What am I doing wrong?
Serial_ReadNBytes is a buffer-based function, too. It is not aware of physical success.
If it returns 1, the serial system has not received any byte since the last query.
According to the code you posted, you do not check for the results of Serial_ReadNBytes.
How looks the transmitting code on the other side?


BTW.:
I usually implement a central input loop,
which repeatedly checks for the keyboard as well as for the the serial receive buffer.
If either source gives reason to act, the program decides accordingly.
I prefer to leave the interrupt job to the OS. It does the job very well.
I'll be back!

Senior Member
Posts: 68
Joined: Tue May 08, 2012 5:40 pm

Re: Serial port questions

Postby happy » Wed Feb 27, 2013 5:13 pm

SimonLothar wrote:According to the code you posted, you do not check for the results of Serial_ReadNBytes.
How looks the transmitting code on the other side?


Sender add-in calls serialSend() whenever user presses a key. In it, Serial_BufferedTransmitNBytes() always returns 0. In Receiver, I call serialReceive() whenever user presses a key, and print the return value of Serial_ReadNBytes(). Which is always 1. All this is just test code, real add-in will have to look for data in the background.

SimonLothar wrote:BTW.:
I usually implement a central input loop,
which repeatedly checks for the keyboard as well as for the the serial receive buffer.
If either source gives reason to act, the program decides accordingly.
I prefer to leave the interrupt job to the OS. It does the job very well.


So I should set up a timer which keeps calling Serial_ReadNBytes(), right?

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 port questions

Postby SimonLothar » Wed Feb 27, 2013 6:08 pm

happy wrote:So I should set up a timer which keeps calling Serial_ReadNBytes(), right?
I'd rather avoid a timer construct, if it is not absolutely necessary. As a timer handler should return as fast as possible, your timer handler has to transfer the serial buffer to a secondary buffer, which has to be checked in the central input loop anyhow. Why not process the serial result in the central input loop immediately?
Code: Select all
while( 1 ){
// some non-blocking keyboard check procedure
  keyboard_event = CheckKeyboard();
  switch ( keyboard_event ){
// process keyboard event
  }

// now look for a serial event (f. i. "expected-count-of-bytes-received" or "end-of_command-character-received")
  serial_event = CheckSerial();
  switch ( serial_event ){
// process serial event
  }
}

CheckSerial() could check the serial buffer, if it contains the expected amount of data (Serial_GetReceivedBytesAvailable()), before flushing the buffer with Serial_ReadNBytes(), which possibly retrieves an incomplete set of data. If you have to deal with incomplete sets of data, you need to manage a secondary buffer. This can be a disadvantage. If you wait for the expected amount of data, you can retrieve exactly this number of data with Serial_ReadNBytes() and process the complete data set at once.
If you do not know the amount of data to expect, than you can inspect the serial buffer with Serial_SpyNthByte() to check for expected patterns (f. i. "end-of_command-character-received").
I'll be back!

Senior Member
Posts: 68
Joined: Tue May 08, 2012 5:40 pm

Re: Serial port questions

Postby happy » Wed Feb 27, 2013 6:32 pm

SimonLothar wrote:CheckSerial() could check the serial buffer, if it contains the expected amount of data (Serial_GetReceivedBytesAvailable()), before flushing the buffer with Serial_ReadNBytes(), which possibly retrieves an incomplete set of data.


If I have sent something, each call to Serial_ReadNBytes() should return something, right? And I can keep calling it till end-of-message delimiter is found?

Btw, I digged up another cable, same problem. So I guess it is a code issue.

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 port questions

Postby SimonLothar » Wed Feb 27, 2013 6:51 pm

happy wrote:If I have sent something, each call to Serial_ReadNBytes() should return something, right?
Depends on how many bytes Serial_ReadNBytes() retrieves. If it retrieves all of the sent data, the next call of Serial_ReadNBytes() will return "none-available". If Serial_ReadNBytes() is called, while the sender is still busy, the next call of Serial_ReadNBytes() should return some bytes again. Of course the count of bytes retrieved during one call of Serial_ReadNBytes() depends on max_size, too.

happy wrote:And I can keep calling it till end-of-message delimiter is found?
Yes.

happy wrote:Btw, I digged up another cable, same problem. So I guess it is a code issue.
Contact spring tension! I'll bet!
I'll be back!

Senior Member
Posts: 68
Joined: Tue May 08, 2012 5:40 pm

Re: Serial port questions

Postby happy » Wed Feb 27, 2013 7:49 pm

SimonLothar wrote:If it retrieves all of the sent data, the next call of Serial_ReadNBytes() will return with "none-availabe". If Serial_ReadNBytes() is called, while the sender is still busy, the next call of Serial_ReadNBytes() should return some bytes again. Of course the count of bytes retrieved during one call of Serial_ReadNBytes() depends on max_size, too.


Noted.

SimonLothar wrote:Contact spring tension! I'll bet!


While I'm sure you're right, I tested with another barely used FX9860GII-2, still the same issue. Cable is loose too.

Will wait till next week till I get the '3Pin - Serial female' cable and try sending data from calc to an emulator on the PC and see if that works..

Senior Member
Posts: 69
Joined: Sat Feb 02, 2013 4:29 am
Calculators: Casio Cfx Series, Casio fx-CG10

Re: Serial port questions

Postby nsg » Fri Mar 01, 2013 1:23 am

I tried to connect prizm to cfx-9850 (which i bought cheap on ebay specially for that purpose). I failed to transfer anything or to get succesful communication using Send( Receive( basic commands.
I used 3 pin cable that came with Prizm. When inserted in prizm or in cfx if feels really loose and insecure, but very consistently so between calculators.

I noticed that if I apply some tension on an inserted connector, the error message appears a second or two later than when i do not do this.

I will check if i can see signal from CFX on the oscilloscope.

Next

Return to Casio fx-9860 SDK

Who is online

Users browsing this forum: No registered users and 20 guests