hserin on M2 parts - how to use?

matherp

Senior Member
I'm confused as to the use of hserin on m2 parts. The example in the manual is
Code:
hsersetup B9600_4, %00 ; baud 9600 at 4MHz
main:
w1 = $FFFF ; set up a non-valid value
hserin w1 ; receive 1 byte into w1
if w1 <> $FFFF then ; if a byte was received
hserout 0,(w1) ; echo it back out
end if
goto main ; loop
This looks as though it will read both bytes in the buffer however the text says "If two bytes are expected in the buffer it is necessary to use two
separate hserin commands to retrieve both bytes."

Either way, the example appears to preclude reception of full binary data that could include any value (i.e if 255 is a valid input). Is there a register I can read to see if data is in the buffer rather than just looking for a change in value?

Thanks
 

matherp

Senior Member
OK

I've answered my own question. It can be done by reading the RCIF bit in the PIR register

Code:
#picaxe14M2
setfreq M32
hsersetup B2400_32,%1000
do
	peeksfr $11,b0 ' Read PIR1
	b0=b0&32 ' mask for RCIF
	if b0=32 then
		peeksfr %01111001,b1 ' read RCREG, equivalent to hserin b1
		sertxd(#b1,cr,lf)
	endif
loop
 

hippy

Technical Support
Staff member
Either way, the example appears to preclude reception of full binary data that could include any value (i.e if 255 is a valid input).
Actually the example is as it is to ensure data of any value can be read, why it reads into a word variable rather than a byte variable. Whatever is received it will set w0 to a value between $0000 to $00FF inclusive, which is different from its initialised $FFFF.
 

rossitech

New Member
I have been going round in circles with Hserin commands! One byte works fine, although I have to send a second byte to clear the buffer.
My problem is that I need to send two bytes and most of the time it works fine, but randomly the second byte gets corrupted, which happens quite often. I realise it is a timing issue so I have tried delays, baud rate and clock freq changes but it is the same. I tried your SFR code and it works but I can only read one byte. So my question is.. How do you read two bytes using this SFR function? Or maybe I can get the SFR to act as an interrupt to trigger Hserin b0, Hserin b1?
Your help is much appreciated! ;-)
OK

I've answered my own question. It can be done by reading the RCIF bit in the PIR register

Code:
#picaxe14M2
setfreq M32
hsersetup B2400_32,%1000
do
	peeksfr $11,b0 ' Read PIR1
	b0=b0&32 ' mask for RCIF
	if b0=32 then
		peeksfr %01111001,b1 ' read RCREG, equivalent to hserin b1
		sertxd(#b1,cr,lf)
	endif
loop
 

hippy

Technical Support
Staff member
Not sure why the second byte would be corrupted but you should be able to read the bytes directly with PEEKSFR as 'matherp' suggests. The way I would do it is -

Code:
Symbol PIR1  = $11 ; $011
Symbol RCREG = $79 ; $199
HSerSetup B2400_4,%000
Do
  PeekSfr PIR1, b0
  If bit5 = 1 Then
    PeekSfr RCREG, b1
    SerTxd( #b1, CR, LF )
  End If
Loop
It might be worth trying this for receiving two bytes. Wait for the first, when it arrives, pause so the second will have been received, then read both ...

Code:
Symbol PIR1  = $11 ; $011
Symbol RCREG = $79 ; $199
HSerSetup B2400_4,%000
Do
  PeekSfr PIR1, b0
  If bit5 = 1 Then
    Pause 10
    PeekSfr RCREG, b1
    PeekSfr PIR1, b0
    If bit5 = 1 Then
      PeekSfr RCREG, b2
      SerTxd( "Two : ", #b1, " ", #b2, CR, LF )
    Else
      SerTxd( "One : ", #b1, CR, LF )
    End If
  End If
Loop
 

AllyCat

Senior Member
Hi,

Welcome to the forum. we may need to know exactly how the two bytes are being timed (e.g. where they are coming from) and confirmation that definitely only two bytes are being trasnmitted, assuming that you are able to measure this.

I encountered similar issues described in this thread but you may find it far to detailed and complex. To summarise, it appears that HSERIN actually does quite a lot of internal processing between the bytes (to prevent or allow the PIC{axe} to recover from hardware lockups), to the extent that the SFR commands can actually receive the bytes faster than HSERIN (but of course a maximum of only two at a time).

Take a look particularly at my "PCB 'scope" photo in #1 and later comments from "technical" in #8 of my thread above.

Cheers, Alan.
 

Flenser

Senior Member
rossitech,

You probably need to post the code that you are having these problems with.

hsersetup sets up the PIC chips hardware USART and then we have the option of reading the data either by using the hserin command or by accessing the PICs SFR registers directly using the peeksfr command.

The PICs hardware USART has a two byte FIFO buffer and in my testing using peeksfr:
- I have sent two bytes at 38400 baud with out ever losing a byte or receiving a corrupt byte.
- I have sent 400 bytes at 9600 baud (to test my program is actually able to keep up at 9600 baud) without ever getting a corrupt byte.
 

AllyCat

Senior Member
Hi,

- I have sent 400 bytes at 9600 baud (to test my program is actually able to keep up at 9600 baud) without ever getting a corrupt byte.
What were your test conditions for that? i.e. HSERIN or PEEKSFRs, clock frequency and source of data (PE, another PICaxe or ...) and where are the characters being sent, etc.? Concatenated 9600 baud characters take only 1ms each and a PICaxe at 4 MHz can't do much in that time (not even close a program loop).

I don't dispute that what you say is perfectly possible, but (only) at an elevated clock frquency and/or received from the PE or another PICaxe (which introduce intercharacter delays by default).

Cheers, Alan.
 

hippy

Technical Support
Staff member
You probably need to post the code that you are having these problems with.
That will probably help as will details of exactly what is being sent to the PICAXE.

Details of what the corrupt bytes are and what they were expected to have been may help identify what type of corruption is occurring and why that may be.
 

Flenser

Senior Member
AlleyCat,

What were your test conditions for that
14M2@32MHz using peeksfr

I first measure how long it takes the code to process each character by using the PE terminal to send the string "ab" at 38400 baud 100 times (I'm typing CTRL-V & Enter 100 times) and using DPScope to capture a 100 sample average triggered on the rising edge of the the first EN pulse of the first character (I'm driving an LCD in 4 bit mode so ther are two EN pulses for each character). This screen capture shows the two EN pulses for the first character and the first EN pulse for the second character. The time between the cursors in this screen capture is 855.3uS:
dpscope_ab_timing.jpg

Then to test that the code can keep up with a long series of continuous characters I paste this string into the PE terminal at 9600 baud:
"00000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222222233333333334444444444555555555566666666667777777777888888888899999999990"

The code is here http://www.picaxeforum.co.uk/showthread.php?28873-AXE133-ported-to-14M2-using-hardware-UART-needs-no-delay-between-chars-upto-4800-baud
See post #2 for updated code that runs at 9600baud.
 

AllyCat

Senior Member
Hi Flenser,

Thanks. Yes, I also had no problems using 4800 baud at 16 MHz (equivalent to 9600 @ 32 MHz) with PEEKSFRs, even when using an interrupt and sending 4-bit parallel data to the LCD via I2C to an expander. It was only when I attempted to use HSERIN that the "errors" appeared. :(

With reference to your finished project thread, yes a (conditional) DO ... LOOP can execute at exactly the same speed as an IF ... GOTO loop, because the PE may write exactly the same interpreter "opcodes" to the PICaxe. But there is a difference between the execution times of "true" and "false" paths (when ultimately converted to either a "Jump" or a "Fall-through"). So the AXE133 program structure can be improved a little, as I described in this thread.

Cheers, Alan.
 
Top