16F to 18F transition pains
I have an application that currently works in a 16F877A part. The code consists of a PBP body with interrupt code written in assembly. Anticipating the need for added functionality, I am attempting to port this code to an 18F4620, as the pinout for the part is compatible.
I'm using the Colt bootloader, with code offset to 0x800.
I'm having some problems with this, so I would like to know some of the more common mistakes made in this sort of transition. The ones I've seen include- removing references to PIR bits
- fast interrupt contexts
- bank select register
- FSR handling
All explicit program variables are placed in bank 1 (verified by inspection of the .lst file). Interrupt code appears to function normally. Scalar variables common to the interrupt code and the main body appear to be accessible. Vectors accessed by the interrupt code using the FSR0H:FSR0L pair do not appear to be accessible by the main body of the code. The interrupt code enters and exits with the following procedure:
IntrSrv; 18F automatically saves W, status and BSR in a 1-deep stack. Use retfie FAST to
; return from interrupt...
clrf BSR
incf BSR
movff PCLATH, _psave ;
movff PCLATU, _psaveu ;
movff FSR0L, _fsave
movff FSR0H, _fsaveh
clrf FSR0H ; variables are confined to bank 1
incf FSR0H
.
.
.
; Restore FSR, PCLATH, STATUS and W registers
isrDone
movff _fsave, FSR0L
movff _fsaveh, FSR0H
movff _psaveu, PCLATU ;
movff _psave, PCLATH ;
retfie FAST ; Return from interrupt
An additional symptom I'm seeing is that HSEROUT is incapable of displaying any value besides 0 for a variable, regardless of whether that variable is involved with interrupts or not. For example, this code fragment is referenced from the main loop. rxLdPtr is a modulo-8 pointer that's used to load received serial port characters into a circular buffer. It is incremented in the interrupt code. if rxLdPtr != rxUnldPtr then
gosub cmdGet
HSEROUT ["rxLdPtr=",dec rxLdPtr,CR,LF]
if rxLdPtr = 7 then
Led = 1
else
Led = 0
endif
endif
Each time I input a character, this code appears to execute, as I see the HSEROUT occur. However, I only see a "0" returned by the HSEROUT. The Led illuminates on every eighth character as expected.
I assume that the PBP compiler builds code that correctly references variables with respect to bank. The Led would not behave properly otherwise. I do not understand why HSEROUT can't reference the same variable.
rxbuffer is the buffer pointed to by rxLdPtr. If I attempt to look at the character received, the Led test fails, as a lowercase "a" does not illuminate the Led.
if rxLdPtr != rxUnldPtr then
gosub cmdGet
if rxbuffer[rxLdPtr] = "a" then
Led = 1
else
Led = 0
endif
endif
The interrupt code that loads the characters into the buffer worked fine on the 16F part, using the FSR. I'm now using FSR0, setting FSR0H to a 0x1 (to reference bank 1, which is where the buffer resides). Both halves of FSR0 are saved and restored in the interrupt code. At this point, I'm assuming that I either- still have a referencing problem in the interrupt code, or
- PBP is failing to reference the buffer in some unknown fashion (which might also be related to the aforementioned HSEROUT behavior)
Are there any other common pitfalls I should look for in porting this type of code (PBP body with assembly interrupt code)from the 16F to the 18F platforms?
Thanks-
Dan