I would like to use Bruce's message table code, but...
Hi Bruce,
I have been studying your code that you posted here on doing message tables from assembly code, and quite frankly I am baffled by parts of it. This wouldn't be problem if I could use it as is, but I really need to have the pointer increments to be by 1 (i.e.; 0,1,2,3,4,5,6, ect.).
Here are some snippits of your code with some questions I have next to them. If you get a chance can you please explain what is going on?
Code:
; This section appears to be locating the message table, but Im not
; really sure specifically what is going on especially with the first part
; where you are moving Upper msg_table into TBLPTRU
; (what is UPPER? I've used HIGH and LOW before, but never UPPER).
; TBLPTR is obviously short for Table Pointer.
movlw UPPER msg_table
movwf TBLPTRU
movlw HIGH msg_table
movwf TBLPTRH
movlw LOW msg_table
movwf TBLPTRL
; Now here we seem to be adding an offset into the message table using
; the same pointers we previously set to what I am asuming is the base
; address of our message table. This is where the beginning of a particular
; message resides within the table (correct?). Now here comes the questions
; of particular interest to me; does the fact that your pointers are in 16 byte
; increments mean that each message string can only be up to 16 bytes long?
; Or can the pointer be changed to any increment desired?
movf _ptr_pos,W ;prt_pos must hold message address
addwf TBLPTRL,F
clrf WREG
addwfc TBLPTRH,F
addwfc TBLPTRU,F
; Ok now that we have our index to a message set, we can begin retrieving
; the characters one by one, until we see the EOM character "~". What is
; tblrd *+ or more specifically *+ (is this doing a read and then increment?)
; Oh and what is "goto $-2" doing? (specifically $-2).
Next_Char
tblrd *+
movff TABLAT,_temp
bra Test_EOM ;test for EOM character
Continue
movf _temp,W ;move temp to w
movwf TXREG ;send it
btfss TXSTA,TRMT ;wait for data TX
goto $-2
bra Next_Char ;fetch next message character from table
; This part is fairly obvious, although there are some more of those $-2
; which I don't understand the purpose of, and what does "\r"
; and "\n" do? Actually to be more specific since I can see your comments,
; what my question really is; what or how does moving a literal of "\r" into
; W actually move the data (which I assume is a character from the table).
Test_EOM
movlw "~" ;check for EOM character
cpfseq _temp, 1 ;compare temp with w, if temp = ~ then end
bra Continue ;no EOM, so continue
movlw "\r" ;move data into TXREG
movwf TXREG ;send carriage return
btfss TXSTA,TRMT ;wait for data TX
goto $-2
movlw "\n" ;move data into TXREG
movwf TXREG ;send line feed
btfss TXSTA,TRMT ;wait for data TX
goto $-2
return ;finished with message, return to caller
If I was better versed in the assembly aspects of the 18F series I could probably figure this out on my own, but I only recently began working with this series of PIC chips.
Any help you can offer is appreciatted.
Thanks,
Now before somebody thinks we're going crazy...
If you look at the last code example you may be asking yourself "Hey isn't that the same thing as HSEROUT ["This is a string"]?"
Well... yes it is, sort of. What I really see to be accomplished here, has more to do with creating the framework for a customizable message string handling Function, then just mimicing an already available PicBasic Pro function. For testing purposes, it is just easier to send it out unaltered through the RS232 port. Ulimately, it will hopefully evolve into a great way to send either message strings, data, or both to any device you wish. While at the same time doing it in a way that is more like a built-in PicBasic Pro function.
A great example of what this could be used for, is imagine that you are interfaced to a device that would accept message strings via RS232, but always requires special commands to precede the message. Using what has already been developed here, all that would be required is to add these commands within the printSTR code (same as what was done for the carriage return and linefeed). Then every time you send a message such as @ SendStr "This is a string" the pre commands would be automatically sent as well.
Even better still, imagine if you were interfaced to several different devices or gateways, each one having special communication requirements (I2C, SPI, One-Wire, RS232, ect.). Every protocol could concievably be supported within the printSTR code, thereby allowing you to broadcast simultaneously to all devices via the single line SendStr function. Pretty cool huh!
We are only scratching the surface as to the possibilities.
I love your Macros, please keep them coming
Quote:
I've also got some MAJOR changes that allow you to do the above quote. Haven't tested them completely yet, but they look promising.
Hey Darrel, I really think we got you hooked on this :-)
Which is perfectly fine by me, and will surely be fun to see what's in store.
Any good ideas on the best way to deal with the interrupt disable issue? I was reading up on this a bit, and it seems like some approaches could cause latency problems. I am also not 100% sure of which parts of the stack manipulation are no no's while an interrupt is occuring (in otherwords, is it only during the PUSH, or POP or both).
My particular interest will be to implement the "printSTR" in an I2C format, since a video chip I am working with requires this. It also has fussy timing requirements that appear to lower than even the standard device speed. to top it off I have 2 chips on board, so I am using independant clock lines and a shared SDA, since they both have identical addresses. Presently I have everything working with a custom PicBasic Pro I2C routine, but I suspect I'll need to implement this as an ASM routine if it is to be incorporated into the "printSTR" routine. Unless your MAJOR changes would allow for this.
BTW: I like the USART routine, it makes it very easy which we all love.
Here's the latest code version
Darrel this incorporates your USART macro (works great):
Code:
DEFINE LOADER_USED 1 ' use for Boot Loader
DEFINE OSC 40 ' change to suit oscillator speed
'============================================
' Equates
'============================================
temp var byte ' temporary storage for character
Goto main ' skip around Macros
'============================================
' Macros
'============================================
' Send String Macro (must be located prior to Main)
ASM
SendStr macro Astring
call _prntSTR
data Astring,0
endm
ENDASM
' USART Initialization Macro (must be located prior to Main)
' [ Initialize USART for specified baud rate at current OSC speed ]
ASM
USART_Init macro Baud
clrf TXSTA, 0
_SPBRG = (OSC * 1000000) / 16 / Baud - 1 ; calc SPBRG @ High baud rate
if _SPBRG > 255 ; if SPBRG is too high
_SPBRG = (OSC * 1000000) / 64 / Baud - 1 ; calc for Low baud rate
bcf TXSTA, BRGH, 0 ; Set BRGH to Low Speed
if _SPBRG > 255
_SPBRG = 255
endif
else
bsf TXSTA, BRGH, 0 ; Set BRGH to High Speed
endif
bsf TXSTA, TXEN, 0 ; Set Transmit Enable bit
movlw _SPBRG
movwf SPBRG, 0 ; load the calulated SPBRG
movlw B'10010000' ; enable USART
movwf RCSTA, 0
endm
ENDASM
'============================================
' Main Program
'============================================
Main:
@ USART_Init 19200 ; set RS232 baudrate
' send messages through RS232
' format #1
@ SendStr "This is a string"
@ SendStr "yet another string again"
@ SendStr "and one more time!"
' format #2
ASM
SendStr "This is a string"
SendStr "yet another string again"
SendStr "and one more time!"
ENDASM
Done:
Goto Done ' loop forever
'============================================
' String Extraction and Print Routines
'============================================
' print string code (locate anywhere)
ASM
_prntSTR
;copy return address to TBLPTR and then pop it off the stack
movf TOSU,W
movwf TBLPTRU
movf TOSH,W
movwf TBLPTRH
movf TOSL,W
movwf TBLPTRL
POP
;TBLPTR should now be pointing to 1st character in string
Next_Char
tblrd *+ ; table read and post increment TBLPTR
movff TABLAT,_temp ; fetch character from message string
bra Test_EOM ; go test for EOM character
Continue ; If not EOM then...
movf _temp,W ; move character into TXREG and...
movwf TXREG ; send it!
btfss TXSTA,TRMT ; has it been transmitted?
goto $-2 ; If not, keep checking
bra Next_Char ; fetch next message character from table
Test_EOM
movlw .0 ; check for EOM character
cpfseq _temp,W ; compare temp with w, if temp = 0 then end
bra Continue ; no EOM, so continue
movlw "\r" ; move carriage return into TXREG and...
movwf TXREG ; send it!
btfss TXSTA,TRMT ; has it been transmitted?
goto $-2 ; If not, keep checking
movlw "\n" ; move line feed into TXREG and...
movwf TXREG ; send it!
btfss TXSTA,TRMT ; has it been transmitted?
goto $-2 ; If not, keep checking
;use incremented value of TBLPTR as new return address (push it)
PUSH
movf TBLPTRU,W
movwf TOSU
movf TBLPTRH,W
movwf TOSH
movf TBLPTRL,W
movwf TOSL
return ;finished with message, return to caller
ENDASM