what I have found so far that USBUART_1_GetAll(rdBuffer) doesn't receive the whole string. It receives chars separately. So it's working like USB U AR T_GetChar() then.
USBUART_GetAll() returns you the retrieved data. So when you get only a single byte this just means that the PSoC hasn't received more at this moment. And since you call it as soon as _DataIsReady() return yes, this situation is rather likely.
This also depends on how the sender is transmitting - if each character is send in its own USB packet, this also will increase the likelihood of this. If, on the pother hand, the sender sends the whole string as one packet, it should never occur.
Note that _GetAll() doesn't return a null-terminated string, which might explain why atoi doesn't return what it should.
thank you very much,
that is clear now. I find the functions are not described well in the reference document. At least for me.
What is then suggested method to get the message? Using getchar and checking the terminator probably?
If you cannot ensure that the senders sends the whole message in one go, you need to handle single characters. Just use _GetChar() and construct the message, until you reach the separator. Just remember - you are basically doing serial communication!
I think the _GetAll() is just there because USBUART is just a special version of the generic USB component, where it makes more sense. The UART mode is just character-based, there is no notion of a 'message' there.
The speed of UART transfer is relatively slow compared to the speed of the processor, so you will need something to decide if the message you expect is already complete or if you have to wait for some more characters.
There are some approaches to ensure that.
1st. Messages of fixed length.
2nd. The message itself contains information about its length.
3rd. A "finish"-character, usually something like Newline (0x0a) Carriage Return (0x0d) FormFeed(0x1a) or Escape (0x1b). All these characters are taken from the ASCII-set of "Non-Printable" chars, which start with the "Space" (0x20)
Of course the sender of the message has to comply to one of the above rules.
I vote for Bob's third approach, as it is self healing, eg. if a message
becomes corrupted, the 3'rd approach acts as a message framing byte.
Of course one can always consider applying an ECC algorithim to the
message but that takes BW and limits max messaging speed.
But when the message becomes corrupt, the frame delimit might be the one getting lost :)
But USB already has its own transport-level protocol, ensuring that nothing gets lost. So when using USBUART, there should be no need to add another protocol on top of that (provided that you trust the other side to send its data correctly).
Thank you so much for such a great attention to my little problem.
I'll stay with getchar approach and \r\n termination as it's something I've used before. Normaly psoc's APIs worked well for me even if I didn't understand what they did. But not this time.
I've just checked the simple echo back and it still doesn't work:
/* get the char into the buffer */
temp = USBUART_1_GetChar();
/* echo the char back */
this perfectly works (nearly - i think it should send chars back in column once I heat enter but it reports them in a row) with a single char sent from terminal but once it goes to 3 chars, the psoc strarts loosing chars and then sends rubbish back. Is something wrong with my code again?
Correct me if I am wrong, the only perfect transport protocol would take an infinite
amount of time, hence there will never be perfect packet transport. So framing
objects, retransmission, all fall under Shannon limits.
I wonder if someone used usbuart to send data to chip. I'd love to have a look on implementation. The exapmple project from cypress sends only a single char to the chip and that works well. but once there are more chars in a message the USBUART_1_DataIsReady() seems do not work correctly