08m2+ hserin buffer problem

Bob_in_NJ

New Member
I am attempting to receive a 2-byte sequence using an 08M2+ at 2400 baud via HSERIN on C.1 (pin 6). The code loops, reading HSERIN until a qualified 1st byte is received. The code then moves on to read the 2nd byte approx 10 mSec later. At 2400 baud the byte is sent in approx 4.2 mSec (10 bits).

The problem I'm observing is that the 2nd byte is not always read correctly. If both bytes are read after they both have been received then the data is good. If the 1st byte is read before the 2nd byte is sent then that's OK as well.

The problem occurs when the 1st byte is read while the 2nd byte is being received. The corrupted 2nd byte is read as either 1) the 1st byte, 2) $FF or 3) part of the 2nd byte shifted over by a nibble ($F4). The correct 2nd byte has the value $46.

I have changed the timing of how data is both sent and received and observed the waveforms on a scope while outputting the data received by the 08M2+ to a terminal.

The results are very repeatable in terms of when the 2nd byte is corrupted. This bad data zone occurs when the reading of the 1st byte occurs after the 1st data bit of the 2nd byte and approximately two bit times after the 2nd byte's stop bit.

Has any one else seen this problem?
 

techElder

Well-known member
Welcome, Bob!

You didn't say what frequency you were running your 08M2+ at. Try increasing the frequency of your PICAXE and see if you just aren't processing the data fast enough.
 

AllyCat

Senior Member
Hi Bob,

Yes, welcome to the forum. I may have experienced a similar issue, but was using an interrrupt to receive the characters. Some M2 devices (but apparently not 08M2s) do have a "known issue" concerning the use of a variable in the first line of an interrupt routine.

See if para 6 (in particular) of post #1 in this thread looks to be relevant. Sadly, I didn't resolve the issue to my satisfaction, except by using PEEKSFRs.

Cheers, Alan.
 

Bob_in_NJ

New Member
Welcome, Bob!

You didn't say what frequency you were running your 08M2+ at. Try increasing the frequency of your PICAXE and see if you just aren't processing the data fast enough.
I was running the 08M2+ at the default 4MHz. Per your suggestion I set the frequency to 8MHz. There was no change in performance. HSERIN still returned an incorrect data value for the 2nd byte when the 1st byte is read while the 2nd byte is being received.

Does anyone have the gory details as to how exactly HSERIN operates? Either a flow diagram or assembly code will do. Verbal descriptions trend to sometimes leave out critical details. It's also not clear to me how framing and over-run errors are handled.

The PIC12F1840, on which the 08M2+ is based, has a description of the EUSART, receiving data and the 2 character buffer (pg 252):

"When all eight or nine bits of the character have been shifted in, they are immediately transferred to a two character First-In-First-Out (FIFO) memory. The FIFO buffering allows reception of two complete characters and the start of a third character before software must start servicing the EUSART receiver. The FIFO and RSR registers are not directly accessible by software. Access to the received data is via the RCREG register.

Immediately after all data bits and the Stop bit have been received, the character in the RSR is transferred to the EUSART receive FIFO and the RCIF interrupt flag bit of the PIR1 register is set. The top character in the FIFO is transferred out of the FIFO by reading the RCREG register."
 

Bob_in_NJ

New Member
View attachment 18421
Hi Bob,

Yes, welcome to the forum. I may have experienced a similar issue, but was using an interrrupt to receive the characters. Some M2 devices (but apparently not 08M2s) do have a "known issue" concerning the use of a variable in the first line of an interrupt routine.

See if para 6 (in particular) of post #1 in this thread looks to be relevant. Sadly, I didn't resolve the issue to my satisfaction, except by using PEEKSFRs.

Cheers, Alan.

It appears that HSERIN command on the 08M2+ isn't doing what I thought it should do. What I thought would be an asset turned into a problem. Since I have a lot of control over the timing of the incoming data, one solution is to simply delay the 2nd byte so it is not being received when the 1st byte is read. See attached image of waveforms showing that timing configuration.


However, after reading AllyCat's post, I decided to try to read the receive register (RCREG=$79) directly.

So I simply replaced my two lines of HSERIN SDAT with PEEKSFR RCREG,SDAT and...

ALL MY PROBLEMS WENT AWAY ! The reading of the 1st byte no longer interferes with value of the 2nd.

I can now read the 1st byte at anytime and the 2nd byte is always read correctly.

hserin.jpg
 
Last edited:

Goeytex

Senior Member
Without getting into to nitty-gritty of the M2 version of Hserin (You will never get the ASM), IMO it is relatively worthless for most applications . The data corruption you are seeing is likely (IMO) due to a timer conflict. The only "solution", if you can call it that, is to wait until both bytes are received before processing them. If you are expecting to process a stream of more than 2 bytes using M2 Hserin then IMO that's wishful thinking. You will likely have to peek some registers to do what you want.
 

Bob_in_NJ

New Member
I've attached a scope image showing waveforms when using PEEKSFR RCREG,x instead of HSERIN x. Now the timing between the 1st and 2nd bytes is not critical and both bytes are read without error.

So, I have at least two choices of how to read in two serial data bytes: 1) use HSERIN *BUT* wait until both bytes are received before using that instruction, 2) use PEEKSRF RCREG with no particular timing constraints with regard to when the 1st byte is read while receiving the 2nd byte.

I hope there are no other surprises lurking in the shadows.

Thanks Forum members for your help!
 

Attachments

hippy

Technical Support
Staff member
I hope there are no other surprises lurking in the shadows.
I suspect the only problem you might encounter is if you get an overrun in the data stream. In that case all reception stops until the overrun flag is cleared.

That, as I understand it, is the root issue described in the earlier linked reference; HSERIN keeps the overrun flag clear to allow further data to be received and doing that clearing, due to the silicon design, disrupts the next byte if it is in the process of arriving.

It should be possible to implement an HSERIN equivalent using just PEEKSFR and POKESFR in the way you are doing. As long as you check bytes are available before PEEKSFR RCREG and clear any overrun flag you should be okay.
 

AllyCat

Senior Member
Hi,

HSERIN keeps the overrun flag clear to allow further data to be received and doing that clearing, due to the silicon design, disrupts the next byte if it is in the process of arriving.
Ah, that's interesting, I don't think that was suggested as a/the cause in my previous thread. But I did have a feeling that something was "wrong" with the timing of HSERIN.

Whilst I did occasionally encounter overrun issues, it was only when I was "thrashing" the serial comms (with a large number of characters at a baud rate at least twice that achieveable with SERIN), and also returning immediately from the interrupt routine unless another character had already arrived in the buffer.

Since something must already have been "lost" if an overrun error does occur, I didn't bother to test for every received character, but just included a "recovery" routine as part of the main outer program loop. As hippy says, an overrun error does cause the serial comms to lock up "permanently". :(

Normally, I try to avoid the use of PEEK/POKE SFR commands because they are not compatible between the M2 and X2 families. But in this case the HSERIN facilities are so different that one may as well use the SFR solution for M2 devices.

Cheers, Alan.
 
Top