Is Hserin really this slow?

BillBWann

Member
I’ve been trying to use Hserin in a project where quite long sequences of characters are being received and it would be difficult to process the characters and not miss any arriving characters - but I’ve been very disappointed with Hserin.

To demonstrate my problem, I’ve set up this test situation. I have an HC-12 connected to pin b.2 of an 18M2 and I’m sending it the letters “ABCDEFGHIJKLMNOP” from another HC-12. The HC-12’s are setup in FU3 mode at 4800 baud.

When I use this program running on the 18M2 at 16MHz, I get the 16 letters printed correctly.

Code:
#picaxe 18m2
#no_data

setfreq m16

do
    bptr=28
    serin [5],b.2,T4800_16,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc

    if bptr>28 then
        b0=bptr-1
        for bptr=28 to b0
            sertxd (@bptr)
        next bptr
    endif
loop

However when I use this program (largely copied from the manual) which utilizes the hardware serial and I run the 18M2 at 32MHz, I largely get garbage.

Code:
#picaxe 18m2
#no_data

setfreq m32

hsersetup B4800_32, %1000 ;  baud 4800 at 32MHz, no hserout

do
    w1 = $FFFF ; set up a non-valid value
    hserin w1 ; receive 1 byte into w1
    if w1 <> $FFFF then ; if a byte was received
        sertxd (w1)
    endif
loop
This is an example of the garbage I receive.
Code:
A¨(TGHI©Š5NOý
The first letter always gets through and you can see some of the later characters have also got through but its different every time. I’ve tried running the 18M2 at slower frequencies but they all seem to perform similarly and only ever reliably receive the first character.

I also tried setting the sending serial port to 2 stop bits so there was a slightly bigger gap between characters but it didn’t seem to make any difference.

If I send the 16 characters from a Picaxe terminal, all the letters get through presumably because that terminal inserts sizable gaps between the sent characters.

I would have expected that Hserin would perform better than Serin and I’d hoped to be able to do a couple of other things between arriving characters.

At a baud rate of 4800, characters arrive about every 2 msecs so with Hserin having a 2 byte buffer and the 18M2 running at 32 MHz, I expected to be able to run a number of lines of code and not miss any characters.

Is Hserin really this hopeless or am I doing something silly?
 

BillBWann

Member
I just realized that the serin code I posted just now has an error in it and the serin statement should have a timeout of 5 msecs which at M16 should have been ...

Code:
serin [20],b.2,T4800_16,@bptrinc,.............
 

Aries

New Member
I'm not sure that sertxd(w1) would show the characters correctly anyway.
Code:
b2 = "A"
b3 = "B"
sertxd(#w1,".")
sertxd(w1,".")
gives
Code:
16961..
- i.e. w1 has "AB" but prints nothing because it is not a printable character.
You could try sertxd(b2,b3) instead, but unless you know you have had exactly 2 characters and the next one hasn't started, you may well get corruption of w1 while you are processing it.
 

westaust55

Moderator
In your Hserin example change to the use of a byte variable instead of a word variable.

Hserin is intended to work with bytes and sertxd is also intended to work with bytes.
 

hippy

Technical Support
Staff member
The main difference in your code is that your SERIN grabs all the characters received then shows what they were after they have all been received.

Your HSERIN loop reports each character as it is received.

I would guess this is causing some characters to be missed or corrupted.

You could optimise your HSERIN code, something like below but you'll want some sort of terminating condition ...
Code:
Do
  b1 = 1
  Do
    HSerIn w0
  Loop Until b1 = 0
  @bPtrInc = b0
Loop
The ideal solution would be to use a PICAXE-X2 and utilise its background HSERIN capability. That way one is never polling and nothing should be missed.
 

AllyCat

Senior Member
Hi,

A PICaxe can't do very much processing in 2 ms, even at a 32 MHz clock frequency. You might find that changing from Word to Byte variables will help a little by reducing the number of interpreter "Tokens" to be executed.

However, in a similar (but more complex) situation with an 08M2, I did find that directly PEEKSFRing the Hardware Serial Buffer was significantly more reliable than the HSERIN command (because the latter appears to be slower). The full thread starts here but you might find posts #4 to #8 are particularly relevant.

Cheers, Alan.
 

BillBWann

Member
Thanks to everyone who offered their thoughts on this. I’ll try to address them all.

Yes, I agree that the use of bytes rather than words seems more logical and I used them in my original program but when that didn’t work, I used the example given in the manual. I assumed that that was the “official” way to do it but I couldn’t see any difference in performance between the two in that neither of them worked unless the characters were sent from a picaxe terminal.

However, the problem doesn’t just seem to be that the program can’t keep up because I’d noted that the program was looping a number of times while waiting for the next character to arrive even when the characters were sent without gaps.

Yes Hippy, I take your point that sertxding the characters takes time but the sertxd rate is very high compared to the Hserin receive rate and I’d also observed that even so, the program was still looping while waiting for the next character. For the record though, I ran your suggested code but it didn’t fare any better.

AllyCat, I’m indebted to you for your reference to your earlier work on this. For me, your approach has saved the day. As an aside, I’ve also been very grateful on many occasions for the work you did on readinternaltemp which I’ve used a lot over the years.

For anyone who wants to practically use Hserin, I certainly recommend you read Alan’s paper from #6. Much of the code below is extracted from Alan's more complicated program. It is the equivalent of my Hserin example in #1 – the difference being that this one works.


Code:
#picaxe 18m2
#no_data
symbol RCREG    = $79    ; Serial receive register
symbol PIR1     = $11    ; RCIF = 32 = Received byte NOT yet read, 16 = TXIF = NO byte in buffer
setfreq m32
hsersetup B4800_32, %1000 ;  baud 4800 at 32MHz, no hserout
do
    do
        peeksfr PIR1,b0                    ; Read the Hardware Serial Status byte
    loop while bit5 <> 1                    ; There is an Unread byte in the receive buffer
    peeksfr RCREG,b0                ; Read it
    sertxd (b0)
loop
Alan’s method allowed me to implement what I had originally set out to do with Hserin and that was to use an 18M2 to receive a file from a utility such as Tera Term and save it directly to a 24LC512 EEPROM. The following code does that. It waits indefinitely to receive the first byte and then continues to receive and save all subsequent bytes until the transmission stops. It then sertxd out from the 24LC512 all the characters that its received. The last few lines of code would be best remmed out if you were sending a binary file with lots of unprintable characters.

Code:
#picaxe 18m2
#no_data

symbol EepromStart=0    ; Start address for writing to 24LC512 EEPROM
symbol Tmeout=8        ; Maximum waiting period for next character (TeraTerm>=8, Picaxe terminal>=120)

symbol RCREG     = $79    ; Serial receive register
symbol PIR1     = $11    ; RCIF = 32 = Received byte NOT yet read, 16 = TXIF = NO byte in buffer
symbol lpcntr=b1        ; No Hserin data loop counter
symbol addr=w1            ; External EEPROM address
symbol endaddr=w2        ; External EEPROM end address
symbol tempbptr=w2    ; Temporary value of bptr
symbol flag=b6            ; Flag for start of data flow

Hi2CSETUP i2cmaster,%10100000,i2cslow,i2cword    'To communicate with on-board 65k byte EEPROM
pause 100

setfreq m32

hsersetup B4800_32, %1000 ;  baud 4800 at 32MHz, no hserout

addr=EepromStart    ; Set 24LC512 eeprom start address

Start:
flag=0    ; Wait indefinitely while flag=0 for first byte of data to be received

do
    bptr=28    ; Set above picaxe variables
    do            ; receive up to 8 bytes of data or timeout
        lpcntr=0    ; Initialize timeout loop counter
        do
            peeksfr PIR1,b0
            if flag>0 then
                inc lpcntr
            endif
        loop while bit5 <> 1 and lpcntr<Tmeout                    ; Wait a while for another byte of data
    
        if lpcntr<Tmeout then    ; if hasn't timed out then must be a new character
            peeksfr RCREG,@bptr                ; Read it
            bptr=bptr+1        ; note that bptrinc incremented by 2 for some reason so not used
            flag=1    ; timeout will apply from now on
        endif
    loop while bptr<36 and lpcntr<Tmeout    ; collect up to 8 characters
    tempbptr=bptr-1    ; remember how many bytes in buffer in case its less than 8
    bptr=28
    If lpcntr<Tmeout then    ; presumably there are 8 characters as didn't time out
        Hi2cout addr,(@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc)    'Save 8 bytes to EEPROM
        addr=addr+8
    else
        for bptr=28 to tempbptr    ; save the bytes that did arrive
            Hi2cout addr,(@bptr)
            addr=addr+1
            pause 100    ; required here as writes are done in quick succession
        next bptr
    endif

loop while lpcntr<Tmeout    ; continue to receive characters until there is a gap in transmission
endaddr=addr-1
pause 100

for addr=EepromStart to endaddr    ; This sertxd's all the received characters (rem out if non-ascii file being sent)
    Hi2cin addr,(b0)
    sertxd (b0)
next addr
sertxd (cr,lf,"End EEPROM address=",#endaddr,cr,lf)

Goto start    ; This could be remmed out if don't want to store two or more contiguous files in 24LC512
An interesting point that came out from this for me was just how big a gap that the picaxe terminal puts between characters. This program has a settable constant (Tmeout) for the maximum number of times around the loop without terminating while waiting for the next character. When Tera Term is used to send the file, that constant can be set down at 8 but for the picaxe terminal sending multiple characters, it needs to be 120 or more.

Anyway, again thanks to everyone.
 

BillBWann

Member
I just realized that there is a potential problem with the code included in the previous post. I modified the code to allow a variable starting address in the 24LC512 just before I posted and I now realize that because of paging limitations when writing to the EEPROM, this starting address would need to be a multiple of 8. Similarly, if you were sending more than 1 file at a time and expecting each one to be appended to the previous file, then each file would have to have a length which was a multiple of 8.

I hope this makes sense.
 

inglewoodpete

Senior Member
One of the problems with logging (with SerTxd) data received via hSerIn is that some of the benefits of using the hardware UART in the PIC/PICAXE get overridden by using the SerTxd command. The reason is that SerTxd's output is bit-banged, requiring critical timing for the serial bits to be generated. To enable the strict timing for bit-banging, internal interrupts used for managing the hardware UART have to be disabled. This creates the very real situation where hardware serial data reception events are ignored and incoming characters get dropped.

I learned the hard way and now use background serial data reception exclusively. Logging should be treated as a lower priority and can only be done when it is safe to do so. I have found that background hSerIn works reliably at up to 76,800 baud.
 

AllyCat

Senior Member
Hi,

Alternatively, in place of SERTXD you might output single characters using HSEROUT (or even POKESFR to the buffer), which AFAIK does not disable the internal interrupts. Personally, I like the "challenge" of using the 08M2 (in particular), which is rather a different beast to any of the X2 family. Usefully, the HSEROUT on 08 and 14M2 is the same pin as for the SERTXD (SerOut) pin.
An interesting point that came out from this for me was just how big a gap that the picaxe terminal puts between characters.
Yes, IIRC the "nominal" default gap was quoted as 5 ms, but at least with PE5 on my ancient Dell it was nearer to 20 ms. That seems quite consistent with up to 120 passes of your test loop running at m32.
Much of the code below is extracted from Alan's more complicated program. It is the equivalent of my Hserin example in #1 – the difference being that this one works.

As an aside, I’ve also been very grateful on many occasions for the work you did on readinternaltemp which I’ve used a lot over the years.
It's interesting that you also found that PEEKSFRing the flag and the buffer registers appears faster than the resident HSERIN command. A clue might be as Technical said in post #8 of my linked thread:
"One of the limitations of the M2 command is that there is no 'error reporting' and so the firmware simply tries to silently reset itself if, for instance, the buffer overruns and generates an error flag. As the only way to correct a buffer overrun in the PIC is to toggle the UART enable bit, and if this enable toggle then also occurs 'mid next byte' you could also get a corrupt byte received,...".
Since we each appear to have found that the SFR method may need to "wait" for the next character to be received, perhaps there's time to also test the 'overrun' flag?

However, I'm reluctant to suggest a "bug" in HSERIN because of my experience with READINTERNALTEMP (as you happened to mention it) which IMHO proved rather a "disappointment". It did have a bug that I reported and which was duly "patched" in PE6. Sadly, that raised two issues: firstly it's now necessary to write two different versions of code, depending on which Editor is to be used, and secondly the patch uses a surprisingly large amount of Program memory. So I generally "gave up" on READINTERNALTEMP and created a new function/algorithm CHIPTEMP (post #3) which can be used entirely with SFR commands, thus is fully compatible with PE5 and PE6.

Cheers, Alan.
 

hippy

Technical Support
Staff member
Yes, IIRC the "nominal" default gap was quoted as 5 ms, but at least with PE5 on my ancient Dell it was nearer to 20 ms.
I think what happens on older Windows versions, when one asks to be woken up in 5ms, Windows put the program to sleep for a minimum 'clock tick' and that used to be something like 18ms.

These days it's not entirely clear how long a 'clock tick' is and it does seem to vary depending on OS version and configuration.

Since we each appear to have found that the SFR method may need to "wait" for the next character to be received, perhaps there's time to also test the 'overrun' flag?
Possibly, but you are starting to move to doing all the checking the firmware does for HSERIN into the PICAXE program which will be slower so it may be introducing the same issues, and in some cases perhaps making things worse.

I suspect the reason it works is an overrun situation; PEEKSFR simply ignores that and carries on regardless where the firmware would try to rectify things as Technical indicates.
 
Last edited:

AllyCat

Senior Member
Hi,
I suspect the reason it works is an overrun situation; PEEKSFR simply ignores that and carries on regardless ...
Not quite, because IF the OverRun flag gets set, then the UART hardware locks up and no further characters are received until it is released (as described by Technical). I don't recall all the details now, but I believe that using HSERIN was the easiest way to release the lockup, although presumably it could be done with a few POKESFR commands.

IF the OverRun flag does become set, then at least one byte will presumably have been "lost", so I think we all agree that that needs to be avoided. However, it appears that directly reading the serial buffer is a "better" method of doing that than HSERIN. ;)

I've just looked at a "base" PIC data sheet and see that the OverRun flag is in a different SFR to the "Character Received" flag,, so the additional check(s) would indeed add a significant delay. It will depend on each specific users' application: (1) Whether an OverRun error will ever occur and if so, (2) Whether (and when) the error needs to be detected and (3) What strategy is available to recover from that error.

Cheers, Alan.
 

BillBWann

Member
Inglewoodpete, your experience with Hserin differs from mine and I suspect that the Hserin problem is caused by something else than sertxd disabling internal interrupts. I think this firstly because the demo program that I included in #7 doesn’t suffer from that problem and it includes a sertxd statement. To test it out, I used Tera Term to send a picaxe bas file and then copied what was received in the terminal window into a new program window. Doing a successful syntax check on it confirmed that it had been received error free. And I did this a few times and it always worked flawlessly.

The other reason I believe that Hserin can’t be fixed by removing sertxd’s is the program below. I wrote it using Hippy’s suggestion in #5 and it doesn’t include a sertxd until all the characters have arrived. Unfortunately, it still only reliably receives the first character sent unless the characters are sent slowly via the picaxe terminal.

Code:
#picaxe 18m2
#no_data
symbol RCREG     = $79    ; Serial receive register
symbol PIR1     = $11    ; RCIF = 32 = Received byte NOT yet read, 16 = TXIF = NO byte in buffer

setfreq m32
hsersetup B4800_32, %1000 ;  baud 4800 at 32MHz, no hserout
bptr=28
Do
  b1 = 1
  Do
    HSerIn w0
  Loop Until b1 = 0
  @bPtrInc = b0
Loop while bptr<36
bptr=28
sertxd (@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,@bptrinc,cr,lf)
Actually, I usually had to send it more than 8 characters to get it to display the received characters because it invariably misses at least one character completely.

As regards the checking of error flags, I think it’s much more practical to ignore them completely. Firstly, that because I’ve found Alan’s method to be incredibly reliable and I’ve sent many 10 of kilobytes and never received a single error. The other reason is that, as Alan says, what can you do if you detect it? You certainly can’t correct it and if the transfer continues you’ll end up with a file which might superficially look OK but will contain errors which will be hard to find. With no error checking, it will be very obvious that something has gone wrong and where it occurred because the hardware will have locked up at that point - but so far that has never happened to me. If confirmation of an error free transmission is required, then I’d suggest using a checksum.

My file transfers have used a pair of HC-12s. If it was a noisier link, then some error checking might well be required but you’d need to have two way communications so that the sending program could resend the missed data and things would then get very complicated – probably better to simply get a more reliable link.

Finally, this is a bit OT but did anyone notice my comment in one of the lines of code in the second program of #7?

Code:
            peeksfr RCREG,@bptr                ; Read it
            bptr=bptr+1        ; note that bptrinc incremented by 2 for some reason so not used
Why is that occurring?
 

hippy

Technical Support
Staff member
There is something odd going on if HSERIN is missing characters at 4800 baud when run at 32MHz.

At 4800 baud a byte will be received every 2ms or so and the HSERIN loop will almost certainly have executed within that time at 32MHz.

Even a SERTXD of a byte at 38400 baud at 32MHz ( 4800 at 4MHz ) should take less than 300us.

There is PICAXE execution overhead in all the commands but, given the double-buffering of serial in, nothing should be missed until a check on HSERIN became more than 4ms apart, and it is hard to see how that could be happening.

I really cannot see how the code in Post #13 wouldn't work, that accumulating the 8 bytes sent doesn't work, how bytes would be missed.
 

hippy

Technical Support
Staff member
If a PICAXE is sending I would recommend testing with just one character sent with a one second gap between them and see how that goes. Perhaps with a modified SERTXD -

SerTxd("Got",TAB, #bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0,TAB,#b0,TAB,b0,CR,LF)

Then start to increase the number of bytes sent, see what happens.
 

hippy

Technical Support
Staff member
Finally, this is a bit OT but did anyone notice my comment in one of the lines of code in the second program of #7?
Code:
peeksfr RCREG,@bptr                ; Read it
bptr=bptr+1        ; note that bptrinc incremented by 2 for some reason so not used
Why is that occurring?
The only thing I can think is that with "PeekSfr <adr>, @bPtrInc", the firmware is seeing the destination as @bPtrInc, is applying an increment, is reading the SFR, storing it where bPtr now points to and, seeing it is @bPtrInc, is applying another increment.

I don't have an 18M2 to hand but you could try this ...
Code:
#Picaxe 18M2
#Terminal 4800
#No_Data

Symbol ADRESL = $3B ; $09B

Do
  SerTxd( CR, LF, "=====================", CR, LF )
  For bPtr = 0 To 10
    @bPtr = 0
  Next
  For bPtr = 0 To 10
    SerTxd( #@bPtr, " " )
  Next
  SerTxd( CR, LF )
  bPtr = 0
  For b27 = 1 To 5
    PokeSfr ADRESL, b27
    PeekSfr ADRESL, @bPtrInc
  Next
  For bPtr = 0 To 10
    SerTxd( #@bPtr, " " )
  Next
  Pause 1000
Loop
 

inglewoodpete

Senior Member
Inglewoodpete, your experience with Hserin differs from mine and I suspect that the Hserin problem is caused by something else than sertxd disabling internal interrupts. I think this firstly because the demo program that I included in #7 doesn’t suffer from that problem and it includes a sertxd statement. To test it out, I used Tera Term to send a picaxe bas file and then copied what was received in the terminal window into a new program window. Doing a successful syntax check on it confirmed that it had been received error free. And I did this a few times and it always worked flawlessly.
I suspect that we are talking about different subjects. I have never used the foreground hSerIn because of the advantages I have found using background serial receive into the scratchpad (at up to 76800 baud). Also I rarely use asynch serial on M2 chips, preferring X2s due to their scratchpad feature.
 

AllyCat

Senior Member
Hi,

I didn't test HSERIN as comprehensively as Bill has, but I do recall from my testing over 4 years ago that the difference between the HSERIN and PEEKSFR RCREG methods (in my case at 4800 baud, 16 MHz) was like chalk and cheese, with the behaviour of HSERIN (in M2 devices) appearing rather "strange" and inexplicable.

Recently I've been re-reading the EUSART section in the Microchip data sheet(s), particularly concerning the Framing and OverRun flags, and made some interesting observations. The Framing bit is a (non fatal) error flag attached to each received byte, indicating that the Stop bit was not at the correct level (in some ways similar to a parity bit), but I think it's worth quoting the OverRun description almost in full (with my emphasis):

"The receive FIFO buffer can hold two characters. An overrun error will be generated if a third character, in its entirety, is received before the FIFO is accessed. When this happens the OERR bit of the RCSTA register is set. The characters already in the FIFO buffer can be read but no additional characters will be received until the error is cleared. The error must be cleared by either clearing the CREN bit of the RCSTA register or by setting the EUSART by clearing the SPEN bit of the RCSTA register" {and re-enabling it].

So we actually have almost three character periods after the start bit (or two after the character-received flag is set) to read a byte from the buffer, before an OverRun occurs. Of course on average we must still read the bytes at the rate they are transmitted, but it gives some margin for interrupt latency, etc. The "critical path" in the program for receiving characters is typicaly: (1) Check the character-received flag is set, (2) Read the byte, (3) Store the byte (somewhere), (4) Advance the buffer pointer (if not automatic) and (5) Check / correct for a buffer wraparound if using a circular buffer (optional), (6) Juimp back to (1). If well-coded, this seems quite plausible at 4800 baud, 16 MHz, particularly as a circular buffer won't wrap on consecutive bytes.

But if we are receiving bytes then the OverRun flag cannot be set, so it is not necessary to read it and add to the critical path ! However, if there is no byte in the buffer then we normally have to "kill time" (for one to arrive), so we can easily read the OverRun flag which takes only two or three instructions (depending whether using a bit-addressable variable). What to do if the flag is set is another matter: Time is no longer critical (because at least one byte is almost certainly lost) and in the case of a file transfer, for example, we probably just abort and start again.. For other situations we might just log (or count) the error and/or report it via SERTXD. Or we might try to "recover" operation as cleanly as possible; clearing CREN might be less disruptive than re-enabling or issuing an HSERIN.:

However, if the characters / bytes are totally concatonated (continuous) then we have an almost random bit sequence, so it's not possible to assure immediate re-synchronisation. We could at least read the Framing error flags, rejecting those bytes and perhaps any added Parity bits (as we are in the SFR domain), but there is always the possibility that a "lucky sequence" (or is it unlucky) of random bits will appear as a valid ASCII character byte.

Finally, if one is using an interrupt-driven structure (as in my original thread linked at #6), it would be wise to read the OverRun flag immediately before returning from the interrupt, and probably also poll it in the "main" program to prevent the risk of a total lock-up (or lock-out). Perhaps I'll revisit my original code sometime soon, but for me one of the greatest "inconveniences" of HSERIN is that the Hardware can be used only with idle-high signals (so not directly with the PE / terminal).

Cheers, Alan. .
...
 

BillBWann

Member
Hippy, I ran your program from #16 and got ....

Code:
=====================
0 0 0 0 0 0 0 0 0 0 0
0 1 0 2 0 3 0 4 0 5 0
Which seems to confirm that it double increments. Does this mean that this firmware glitch would apply to all similar statement and for all chips?

I also added your sertxd statement to detail the bytes that Hserin did produce. The output is different every time and the only obvious consistency is that the first byte is correct. Below are 3 responses when the sending string was “ABCDEFGH”.

Code:
Got  01000001    65    A
Got  01000010    66    B
Got  00101000    40    (
Got  01010100    84    T
Got  10010100    148    ”
Got  11010100    212    Ô
Got  00010100    20     
Got  11111010    250    ú

Got  01000001    65    A
Got  01000010    66    B
Got  01000011    67    C
Got  01000100    68    D
Got  01010001    81    Q
Got  11010100    212    Ô
Got  00010100    20     
Got  11111010    250    ú

Got  01000001    65    A
Got  10101000    168    ¨
Got  00101000    40    (
Got  01010100    84    T
Got  10010100    148    ”
Got  11010100    212    Ô
Got  00010100    20     
Got  11111010    250    ú
As you can see, the garbage characters received aren't totally random but I'm not sure that I can draw any useful conclusion from that.

I’m away from home at the moment so accurately measuring the gap between characters sent from a picaxe to the 18M2 would be difficult. Mind you, I think knowing the actual send rate that Hserin will accept is becoming pretty academic. We know that it’s significantly slower than Alan’s SFR method and I really can’t see any situation where I’d use Hserin rather than Alan's. Certainly, Hserin doesn’t lock up but I’d prefer to have control over what happens when an overrun or a framing error occurs rather than simply ignoring it and pressing on regardless as Hserin appears to do.

Thanks Alan for that further info. That’s interesting that you may have nearly 3 character periods when the program could be elsewhere and still not cause an overrun. I’m glad that this exercise to transfer data to the 24LC512 when I didn't have an X2 available, has made me take a detailed look at Hserin and consequentially at your findings because it seems that the hardware serial on the M2 chips opens up a number of possibilities that I would previously have assumed required an X2.

I look forward to reading about whatever you discover when you revisit your interrupt driven application of Hserin.
 

hippy

Technical Support
Staff member
Hippy, I ran your program from #16 and got .... Which seems to confirm that it double increments. Does this mean that this firmware glitch would apply to all similar statement and for all chips?
Possibly but perhaps not. Firmware differs between commands, versions, chips and families so, that it's an issue in one case, doesn't necessarily mean it will be an issue in others.

Apart from checking the revision history for the particular chip the only way to tell if there is an issue is to try it.

But, as "PeekSfr <adr>,@bPtr : bPtr=bPtr+1" is a substitute for "PeekSfr <adr>,@bPtrInc" it's annoying but not the end of the world.

I think knowing the actual send rate that Hserin will accept is becoming pretty academic. We know that it’s significantly slower than Alan’s SFR method and I really can’t see any situation where I’d use Hserin rather than Alan's.
My guess would be, if blaming HSERIN, that it receives a byte, reads it, resets the on-chip hardware status, which is causing the hardware to lose track of the next byte which is already being transmitted.

Just peeking the received register doesn't reset the hardware so the next byte can then be received unimpeded.

So, assuming the back-to-back nature of data is simply pushing HSERIN too hard, this should work for handling the data using PEEKSFR, based on Alan's code -
Code:
#Picaxe 18M2
#Terminal 38400
#No_Data

Symbol RCREG       = $79  ; $199

Symbol PIR1        = $11  ; $011

Symbol TMR1IF_BIT  = bit0
Symbol TMR2IF_BIT  = bit1
Symbol CCP1IF_BIT  = bit2
Symbol SSPIF_BIT   = bit3
Symbol TXIF_BIT    = bit4
Symbol RCIF_BIT    = bit5
Symbol ADIF_BIT    = bit6
Symbol TMR1GIF_BIT = bit7

SetFreq M32
HSerSetup B4800_32, %1000
Do
  For bPtr = 20 To 27
    Do
      PeekSfr PIR1, b0
    Loop Until RCIF_BIT = 1
    PeekSfr RCREG, @bPtr
  Next
  For bPtr = 20 To 27
    b0 = @bPtr
    SerTxd( "Got", TAB, #bit7,#bit6,#bit5,#bit4,#bit3,#bit2,#bit1,#bit0, TAB, #b0, TAB, b0, CR, LF )
  Next
  SerTxd( CR, LF )
Loop
That should all work as desired. It should loop fast enough that it doesn't miss anything, and there should be no corruption, no framing errors, no overruns.

The worst case would be that more data was received while the SERTXD's were executing to show what had been received.
 

BillBWann

Member
My guess would be, if blaming HSERIN, that it receives a byte, reads it, resets the on-chip hardware status, which is causing the hardware to lose track of the next byte which is already being transmitted.
Yes, that sounds like a very good explanation on why Hserin is failing. On that basis, I think its use should be avoided and Alan’s used in preference unless you’re expecting to receive individual bytes that are widely separated.

So, assuming the back-to-back nature of data is simply pushing HSERIN too hard, this should work for handling the data using PEEKSFR, based on Alan's code -
Yes, Hippy, that will work and is essentially what I did back in #7 for my EEPROM transfer program although that program is complicated slightly by including provision for a timeout after the first byte has been received. I’ve used that program to transfer many tens of kilobytes of back-to-back bytes of data @ 4800 baud and never had a lockup.

I would think that if you were simply SERTXDing the data to the terminal, then it would be more efficient to do it immediately as I did in my first example in #7 rather than bunch them all up. I only bunched them up for my EEPROM transfer program because that allows more time between consecutive Hi2couts for the 24LC512 EEPROM to accept the data.
 
Top