You will need a protocoll.
Transfering (ASCII) strings. Each string is terminated by a non-printable character like LF or CR or even both. This will need a (interrupt driven) routine that fetches all incoming chars into a buffer.
There are different fixed-format messages sent:
First byte is the format-specifier (a number)
Second byte(or word) is the message length
the message follows.
this message will need a buffer algorithm, too.
Look for (google) "Circular Buffer Algorithm"
Alright, seeing as my goal is to transmit data blocks that are not just ASCII strings, I've decided to go with your second recommendation. I looked up circular buffers and played around with UART interrupts a bit, and couldn't understand the following behavior:
- On the transmission side I'm simply using UART_PutChar() in an infinite loop. On the receiving end I've enabled the "RX - On Byte Received" interrupt and in the ISR I'm printing the received byte. This works fine except for the fact that the ISR only executes 3 times once the transmitter PSoC starts and then never executes again (as in when I reset the transmitter, it causes the ISR on the receiving end to trigger 3 times but after that everything's idle). I thought the RX interrupt would continue to trigger infinitely because I'm transmitting a byte over and over again on the transmitter and the ISR should trigger each time a byte is received. I'm using a TX and RX buffer size of 4 on both sides.
- The buffer size property has me a bit confused since I'm coming across different wording of how it works in various posts. From what I understand, the 8051 at the core of the PSoC 3 has an 8-bit serial register, and each time a byte is received to it, it gets enqued to a 4-byte (default) FIFO buffer. And everytime I use UART_GetChar() or UART_GetByte() I'm simply dequeing a byte from the FIFO. Is this the case?
- How does the receiving PSoC discern the metadata which you're suggesting for a custom protocol (i.e. format specifier, number of bytes) from the actual transmitted data? Like suppose if the receiving PSoC is resetted while the transmitter is sending a data block, the receiver will (incorrectly) interpret the first byte it received as a format identifier. Will I have to incorporate a handshake procedure or something like that.
Thanks in advance.
When your interrupt is firing only 3 times you are doing something wrong. Best could be to upload the complete project here, so that we all can have a look at all of your settings? To do so, use Creator->File->Create Workspace Bundle (minimal) and attach the resulting file (do NOT use chrome, that still may not work).
The buffer size parameter MUST be set to four (4) because otherwise an internal interrupt will start fetching the received bytes into the buffer. This would work contrary to your own interrupt routine.
In my suggested protocol is a redundancy implied you may check: the format number specifies the number of bytes that get transfered. You can define additionally a trailler byte, so that you have better chances to synchronize. Additionally the amount of different formats is small. So when receiving an undefined format-number you know that it is rubbish at least to the trailling byte. When using words for these numbers you can even distinguish more unusual (fail) states very fast.
Alright, so after quite a bit of work I've managed to get most of my stuff working. Here's the format I use:
1st byte = format specifier
2nd byte = number of bytes
*corresponding number of bytes
trailing byte = CRC byte
The major problem I'm facing right now is this: If I turn on the receiver first and then the transmitter, everything usually works fine. But if I turn on the transmitter first and then the receiver it never works. In the attached code its because I just send out a handshake byte once when the transmitter starts and wait for a reply, so if the receiver isn't powered on at the time it never gets a handshake request. The obvious solution is to repeatedly transmit the handshake byte and wait for a reply, but if I do this, the transmitter goes completely haywire and completes the handshake even if the receiver is turned off. I checked and found out that the RX interrupt gets triggered for no reason when I'm continuously sending out bytes. Why's that?
Also, the CRC verification at the end seems to be malfunctioning at the transmitting end too. It just doesn't receive the reply which the receiver is sending it.
Attached is a workspace bundle of both projects (transmitter and receiver).
UART1.zip 2.6 MB
At the beginning of a protocoll very often a phase for negotiation is started. This is a question and answer phase where for instance different baud-rates are tested for usability and both sides agree to the same value.
A bit less complicated could be to repeatedly send a byte and wait for a defined time for an answer. Then staert the communication phase.
That's where the problem starts. When I repeatedly send a byte via the transmitter, its RX interrupt triggers and it somehow detects a correct response from the receiver even when the latter is completely powered off.