Serial port questions
Serial port questions
- 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?
Re: Serial port questions
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):
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
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.
1b) I tried this before. Here an idea (A is host, B client):
ClickMe: Show
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

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.
Re: Serial port questions
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..
Knew what the return value meant, but was hoping Simon could point out any error in how I used the syscalls

- SimonLothar
- Senior Member
-
- 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
Yes. The function is not aware of any physical success.happy wrote:1a) Serial_BufferedTransmitNBytes always returns 0. Whether the cable is plugged in or not. Is this the correct behaviour?
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..
Yes. A software handshake is the only way to apply a reliable failure detection.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)
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.
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: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)?
Serial_ReadNBytes is a buffer-based function, too. It is not aware of physical success.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?
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!
Re: Serial port questions
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?
- SimonLothar
- Senior Member
-
- 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
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?happy wrote:So I should set up a timer which keeps calling Serial_ReadNBytes(), right?
- 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!
Re: Serial port questions
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.
- SimonLothar
- Senior Member
-
- 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
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:If I have sent something, each call to Serial_ReadNBytes() should return something, right?
Yes.happy wrote:And I can keep calling it till end-of-message delimiter is found?
Contact spring tension! I'll bet!happy wrote:Btw, I digged up another cable, same problem. So I guess it is a code issue.
I'll be back!
Re: Serial port questions
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..
- nsg
- Senior Member
- Posts: 69
- Joined: Sat Feb 02, 2013 4:29 am
- Calculators: Casio Cfx Series, Casio fx-CG10
Re: Serial port questions
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.
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.
Who is online
Users browsing this forum: No registered users and 22 guests