PDA

View Full Version : 16F to 18F transition pains



lurker
- 3rd December 2008, 16:19
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

Bruce
- 4th December 2008, 20:20
I would have to suspect something in your interrupt routine not working as expected, but it's hard to tell without seeing your complete routine, and a good deal more of your program code.

I've never had any problems with PBP not knowing where a variable is located, so I would for sure have to suspect something else.

lurker
- 5th December 2008, 01:35
Thanks for the reply, Bruce.

Upon further study of the data sheet, I was made aware of the existence of the XINST bit in CONFIG4 bit 6. The datasheet warns about flaky behavior in legacy apps if this bit is set. So I got out the JDM programmer and looked at the configuration bits (using WinPic). This bit was indeed set. Turning off this bit and reprogramming the configuration bits fixed the problem. (re: PIC18F2525/2620/4525/4620 Data Sheet DS39626E pg 314, section 24.2.4).

-Dan