HSERIN to non-default scratch pad location.

roho

Member
Hi all,

I'm transferring data between my PC (running a tcl programme) and a 28X2 (utilising the HSERIN/HSEROUT pair of pins), connectivity being via an AXE027. It's early days yet and there's a lot of debugging ahead of me, but basic two way communication is working. One problem I am facing is the reception of data into the 28X2's scratch pad. This is going to the default location of 0x000, where it is overwriting and corrupting data for transmission. It strikes me that there are two possible solutions to this. One is to re-locate the area of the scratch pad used for storing data for transmission away from that being used for reception. I am very reluctant to do this, however, as it will add a lot of complexity to the programme. The second solution would be to receive to a location in the scratch pad that is away from that being used for transmission data. At face value this should be trivial since the HSERIN command supports an argument defining the first location in the scratch pad that received data is dumped to. At this point I run into a very different problem.

A search of the programme reveals that the command HSERIN is not present! I have a vague memory that the code for receiving via HSERIN was given to me from this forum (Hippy, perhaps?) some while back, the consequence being that reception occurs by some arcane process that I do not have a good understanding of. I'll append the relevant sections of code, which needs to be modified to receive to a user-defined scratch pad location. Thanks for any help.

Code:
; Define the sub-routine for receiving messages from the PC.
task_pc_receive:
LET RxPointer = HSERPTR
LET RxMessageLen = 0x00
DO WHILE RxMessageLen = 0x00
  GET RxPointer, RxMessageLen
  IF RxMessageLen = "?" THEN                 ; Do we have anything to transmit?
    IF TxPointer = TxCounter THEN                        ; Nothing to transmit.
      HSEROUT 0, ("&")                                             ; Send NACK.
    ELSE                                               ; Something to transmit.
      HSEROUT 0, ("!")                                              ; Send ACK.
      LET Status = Status OR 0x80
    ENDIF
;  ELSE
;    FOR TempRx01 = 1 TO RxMessageLen      ; Receive <MessageLen> bytes of data.
;      GET TempRx01, RxPCData  ; Data must be processed.
;    NEXT TempRx01
;    HSEROUT 0, ("!")
  ENDIF
LOOP
RETURN

...<various bits of code until the HSER interface is set up and the sub-routine is called>...

; Set up the hardware serial data and I2C interfaces.
HSERSETUP B9600_16, 0x07
HI2CSETUP I2CMASTER, 0xA0, I2CSLOW_16, I2CBYTE

; The red LED being lit is the signal for the user to start the TCL script.
; We now wait for the question mark to arrive.
GOSUB task_pc_receive
 

roho

Member
I think I've found the answer. Automatic background receiving (which is what I'm doing) is to the location set by HSERPTR, and this appears to be writable as well as readable (at least the compiler doesn't complain when I do set it). Hopefully, all I need to do is set this as required.
 

Aries

New Member
I have used setting HSERPTR on many occasions, to prevent (or attempt to prevent) background receive corrupting other parts of scratchpad. As long as you have a large enough contiguous area to receive what comes in AND you reset HSERPTR when you can, then it should work.
 

inglewoodpete

Senior Member
Here https://picaxeforum.co.uk/threads/hserflag-vs-hserinflag.32139/post-334527 is a post where inglewoodpete has described using the HSERINPTR to limit background serial receive to use only 64 bytes of the scratchpad RAM.

He has used the interrupt to ensure that HSERINPTR gets updated as characters are received.
@Flesner, Thanks for digging out that earlier post. I saw this thread earlier today but had to rush out to an appointment, so was unable to reply at the time.

The principle of using the hSerInFlag interrupt can be further enhanced to any 'binary' region of the scratchpad. For example, any 8-, 16-, 32-, 64- etc. etc. -byte region of the scratchpad. For example, the 28X2 and 40X2 have 1024 bytes of scratchpad RAM - to use the uppermost 128-bytes of the scratchpad as a circular receive buffer, use a command like the following in your interrupt routine:
Rich (BB code):
hSerInPtr = hSerInPtr And %0001111111 Or %1110000000
Of couse, in this case the hSerInPtr needs to be initialised to 896 (the start of the last 128-byte group of 1024 byte scratchpad), as well as initialising interrupts for hSerIn.
 

hippy

Technical Support
Staff member
Yes, manually adjusting 'hSerPtr' should do the job. The only thing to be aware of when using Scratchpad as a serial receive ring buffer is that a high rate of data reception may cause 'hSerPtr' to have wrapped round to zero with data having been written there before the manual adjustment to the pointer has been made. Resetting 'hSerPtr' to where the start of received data is to be placed may be a better approach.
 

roho

Member
Thankyou for your replies, my understanding of the hardware serial receive has improved considerably as a result. Are HSERPTR and HSERINPTR different names for the same register? At least, I cannot think of what any difference might be.

My plan is to use the bottom 256 locations of the scratch pad for data storage for HSEROUT to the PC, the remainder will be for receiving data from the PC. Received data can be limited so that it will not cause HSERPTR to overflow, the intention is to set HSERPTR to the start of receive locations, i.e. 0x100, at the end of every reception.
 
Top