# Pic16LF877a Help with Banks

#### maxpower097

Joined Feb 20, 2009
785
Ok about 5 years ago a company came to me with some code to work on, they couldn't find anyone to work on it at all. They tried to fly people in etc... but no luck, lots of talk, very little production. The code was originally written by a IT class and professor as a class project. Runs right about 5000 lines of code. 5 years ago I taught myself the basics and actually managed to make all the changes they wanted. Yea! Me! >>>>TimeWarp 5 years>>>>. Same people contact me about makeing new code for a new device they are working on. All the previous programmers that took the job took the deposit and ran. Can't really blame em because the people I work for are the kind of people who think they know what their doing but don't which makes htem twice as dangerous. Well I accepted the job on salary and the got the assembly code for the old device they need some work on. I try to build the asm and I get all these errors. I comb the code and some idiot was trying to mix C with ASM without declaring anything or that he's gonna write some C code. I filtered that out and it removed all the errors I was having. Now I've got about 200 warning messages saying Operand in not in Bank0 check config bits. Were using the BankSet1 command but its not being recognized anymore.
Heres some code from the BankSet commands.

Rich (BB code):
__CONFIG  _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _XT_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

Include File
Rich (BB code):
;Register
PORTA                        EQU     H'0005'
PORTB                        EQU     H'0006'
;Status Bits
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
;Config Bits
_CP_ALL                      EQU     H'1FFF'
_CP_OFF                      EQU     H'3FFF'
_DEBUG_OFF                   EQU     H'3FFF'
_DEBUG_ON                    EQU     H'37FF'
_WRT_OFF                     EQU     H'3FFF'    ; No prog memmory write protection
_WRT_256                     EQU     H'3DFF'    ; First 256 prog memmory write protected
_WRT_1FOURTH                 EQU     H'3BFF'    ; First quarter prog memmory write protected
_WRT_HALF                    EQU     H'39FF'    ; First half memmory write protected
_CPD_OFF                     EQU     H'3FFF'
_CPD_ON                      EQU     H'3EFF'
_LVP_ON                      EQU     H'3FFF'
_LVP_OFF                     EQU     H'3F7F'
_BODEN_ON                    EQU     H'3FFF'
_BODEN_OFF                   EQU     H'3FBF'
_PWRTE_OFF                   EQU     H'3FFF'
_PWRTE_ON                    EQU     H'3FF7'
_WDT_ON                      EQU     H'3FFF'
_WDT_OFF                     EQU     H'3FFB'
_RC_OSC                      EQU     H'3FFF'
_HS_OSC                      EQU     H'3FFE'
_XT_OSC                      EQU     H'3FFD'
_LP_OSC                      EQU     H'3FFC'
Source
Rich (BB code):
#define  BankSet0        bcf STATUS,RP0 ; Set the RAM bank to 0
#define  BankSet1        bsf STATUS,RP0 ; Set the RAM bank to 1

; Bank-Select Names (for use with BANKSEL directive)
BANK0         EQU     PIR1
BANK1         EQU     PIE1
BANK2         EQU     EEDATA
BANK3         EQU     EECON1
Now the code used to run perfectly with no errors or messages. Now everytime BankSet1 is called. The following commands send messages saying operand not in Bank0. Then it goes back to BankSet0 and no more messages. Then call BankSet1 and the lines after it all give the Bank0 message. Any idea whats causing this? It also won't program anymore. I tried hooking my pk3 up to it pin for pin and it won't detect it. Any ideas?

#### R!f@@

Joined Apr 2, 2009
9,647
I dunno much but doesn't the data sheet tells u how to select banks ?

To me the banksel directive always works but I never worked on tht PIC yet.

#### maxpower097

Joined Feb 20, 2009
785
See thats the problem, when I last worked on the code the BankSet functions worked great. So many people have molested this code its just a nightmare. Now my programmers not even seeing the chip.

#### Markd77

Joined Sep 7, 2009
2,796
The message is generated even if you have changed to the correct bank. If you put
ERRORLEVEL -302
at the top of the assembler it will get rid of the message.

#### John P

Joined Oct 14, 2008
1,749
Rich (BB code):
#define  BankSet0        bcf STATUS,RP0 ; Set the RAM bank to 0
#define  BankSet1        bsf STATUS,RP0 ; Set the RAM bank to 1

; Bank-Select Names (for use with BANKSEL directive)
BANK0         EQU     PIR1
BANK1         EQU     PIE1
BANK2         EQU     EEDATA
BANK3         EQU     EECON1
Now the code used to run perfectly with no errors or messages. Now everytime BankSet1 is called. The following commands send messages saying operand not in Bank0. Then it goes back to BankSet0 and no more messages. Then call BankSet1 and the lines after it all give the Bank0 message. Any idea whats causing this? It also won't program anymore. I tried hooking my pk3 up to it pin for pin and it won't detect it. Any ideas?
I admit to being confused here, but it seems to be the order of the day.

However, if I could ask to have one thing clarified it would be what BankSet0 and BankSet1 are supposed to be doing. Context suggests that they're setting the bank (high/low) used for indirect addressing. This is done by setting/clearing bit 7 of STATUS, which the manual calls IRP. But the code there seems to be setting/clearing bit 5, RP0.

RP0 is used along with RP1 (bit 6) to select a bank (0-3) for direct addressing, and in fact those four registers, PIR1, PIE1, EEDATA and EECON1 are located in the banks in the correct order, so it does seem that it's the direct addressing mode that's intended by BANKSEL. That would suggest that BankSet is doing the other thing, namely setting the bank for indirect addressing. I contend that if so, it won't do it correctly.

So, I want to ask if maybe
Rich (BB code):
#define  BankSet0        bcf STATUS,RP0 ; Set the RAM bank to 0
#define  BankSet1        bsf STATUS,RP0 ; Set the RAM bank to 1
should actually be
Rich (BB code):
#define  BankSet0        bcf STATUS,IRP ; Set the RAM bank to 0
#define  BankSet1        bsf STATUS,IRP ; Set the RAM bank to 1

#### maxpower097

Joined Feb 20, 2009
785
I'll give it a whirl John thanks. If that doesn't work I'll post some code examples if it being used. I did notice in the code some bank changes were done with IRP bit.

No go same results.Except I got like 100 (302) msg, and 1(305)

Last edited:

#### maxpower097

Joined Feb 20, 2009
785
They are supposed to switch from Bank 0 to Bank 1, Heres a code example

Rich (BB code):
Dw300   EQU     DTasc+1     ;
;
goto    DOSEdump2 ;;;;;;;;;;;;;;; temporary statement ;;;;;;;;;;;;;;;;;;;;;;;
;
BankSet1            ;if  is not 0000 then prompt for confirmation before continuing

movf    UserPIN,W
iorwf   UserPIN+1,W
iorwf   UserPIN+2,W
iorwf   UserPIN+3,W
BankSet0
btfsc   Zflag
goto    DOSEdump2
;
bcall   PWreadU
Bold and underlined are the only lines with (302) Bank msg. But every thing after I do a BankSet1 I get those messages except for when I come back to Bank0. Neither of the BankSet(x) functions cause an alarm. Just after 1 and before if goes back to 0.

#### t06afre

Joined May 11, 2009
5,936
"302 Register in operand not in bank 0. Ensure that bank bits are correct.
This is a commonly seen reminder message to tell you that a variable that is being accessed in not in bank 0. This message was added to remind you to check your code, particularly code in banks other than 0. Review the section on banksel (banksel - Generate Bank Selecting Code) and bankisel (bankisel - Generate Indirect Bank Selecting Code (PIC12/16 MCUs)) and ensure that your code uses bank bits whenever changing from ANY bank to ANY other bank (including bank 0).
Since the assembler or linker can't tell which path your code will take, you will always get this message for any variable not in bank 0. You can use the errorlevel command to turn this and other messages on and off, but be careful as you may not spot a banking problem with this message turned off"
I do not use Assembler much now. But I agree with with R!f@@. The Banksel directive is quite powerful. This directive is an instruction to the assembler and linker to generate bank selecting code to set the bank to the bank containing the designated label.
Rich (BB code):
banksel TRISB           ;Since this register is in bank 1,
;not default bank 0, banksel is

;used to ensure bank bits are correct.

clrf    TRISB           ;Clear TRISB. Sets PORTB to outputs.
;where PORTB is located.
movlw   0x55            ;Set PORTB value.
movwf   PORTB

#### MrChips

Joined Oct 2, 2009
19,148
Last edited:

#### John P

Joined Oct 14, 2008
1,749
I think the example you've quoted may prove my point, but you haven't looked in the right place to find the result.

If you'd look up where in processor memory UserPIN+1, UserPIN+2, and UserPIN+3 are located, you'd have a chance to solve this. Because then you'd know which bits in STATUS need to be set in order to access those locations, either by direct access (which is what the example is doing) or by indirect access.

Code:
Dw300   EQU     DTasc+1     ;
;
goto    DOSEdump2 ;;;;;;;;;;;;;;; temporary statement ;;;;;;;;;;;;;;;;;;;;;;;
;
BankSet1            ;if  is not 0000 then prompt for confirmation before continuing

movf    UserPIN,W
iorwf   UserPIN+1,W
iorwf   UserPIN+2,W
iorwf   UserPIN+3,W
BankSet0
btfsc   Zflag
goto    DOSEdump2
;
bcall   PWreadU

#### maxpower097

Joined Feb 20, 2009
785
Believe me I hate banks! Thats why I dumped the p16 and went to the p24-p32. But I gotta solve this problem. We'll see. I'll try everything I need to.

#### hgmjr

Joined Jan 28, 2005
9,029
I think that MrChips has given the best advice. Nix the PIC and move to an AVR. You will never have another problem with banks unless you write a bad check.

hgmjr

#### John P

Joined Oct 14, 2008
1,749
You can do lots of good stuff with a PIC processor, but you'll go crazy trying to get anywhere with assembly language. A compiler will take care of all that bank-switching and you'll never need to know anything about it.

#### MrChips

Joined Oct 2, 2009
19,148
I'm not quite sure what the person had in mind when they designed the PIC. The only thing I can think of is the RCA 1802 which relied on a lot of context switching.

The Atmel AVR was designed with the compiler in mind and hence produces very efficient code.

#### hgmjr

Joined Jan 28, 2005
9,029
You can do lots of good stuff with a PIC processor, but you'll go crazy trying to get anywhere with assembly language. A compiler will take care of all that bank-switching and you'll never need to know anything about it.
John P. is right. The PIC is a programmer-friendly microcontroller when you use a high-level language. Assembly Language programming is challenging whether your target is a PIC, an AVR or any other micro for that matter.

It is just that bank switching makes Assembly Language programming an intense exercise in keeping track of which bank you are in at any given point in the execution. Still there are those who relish such a challenge. I admire their patience and skill.

hgmjr

#### maxpower097

Joined Feb 20, 2009
785
I'm well aware of the PIC AVR thing. I personally like PICs over AVRS but absolutely hate assembly and the bank thing. Unfortunetaly I can't scrap the chip and goto another or else I'd have to throw away 6000 MCU's. That and the codes pretty much already written, its the people before me who have screwed it up. Now I'm just trying to recover the work that was completed when I left, then add some simple funtions. But the ASM code is 5300 lines. I really really really don't wanna write 5300 lines of code from scratch. So if I switched chips I'd be looking at, at least 3-6 months of programming. We've gotten quotes from microchips people they recommend and they quoted 3 people working 1 year, or 50 asians working 1 month. So you can see switching chips is out of the question. But after this is done I get to start on the new model on a PIC32 which is more my style. Fits my motto, write some letters and let the compiler figure it out.

#### MrChips

Joined Oct 2, 2009
19,148
Can you port the code to C?

#### maxpower097

Joined Feb 20, 2009
785
Doubtful. Now I got it programming, but the codes screwed. If I switched it to C I'd even be more behind the ball. So far I have the LCD init'ing then stops with the LCD displaying
_____________<<<<<<<<<
_______________________
_____________<<<<<<<<<
_______________________

#### maxpower097

Joined Feb 20, 2009
785
I do not use Assembler much now. But I agree with with R!f@@. The Banksel directive is quite powerful. This directive is an instruction to the assembler and linker to generate bank selecting code to set the bank to the bank containing the designated label.
Rich (BB code):
banksel TRISB           ;Since this register is in bank 1,
;not default bank 0, banksel is

;used to ensure bank bits are correct.

clrf    TRISB           ;Clear TRISB. Sets PORTB to outputs.
;where PORTB is located.
movlw   0x55            ;Set PORTB value.
movwf   PORTB
Ok I''ve replaced the first BankSet1 command with banksel TRISB, bsf STATUS,RP0, bsf STATUS,IRP, and every other way I can think of and the warning keeps coming up. This is also where my code seems to breakdown in real time so I think the BankSet msgs are the cause of the issue.

As far as UserPIN0,1,2,3 are on the pic's internal epprom. Would more examples of the BankSet1's in the code help more?

#### Markd77

Joined Sep 7, 2009
2,796
The 302 warning is nothing to worry about if you have changed to the right bank. See my earlier post for how to get rid of it, and t06afre has quoted the explanation.
The 305 warning means that you have left off a ",W" or ",F" and it has defaulted to ",F" I think.

The complier can't always know if the bank is correct so it just gives the warning for everything not in bank 0.
eg
btfsc STATUS, C
BCF STATUS, RP0
BSF STATUS, RP0
clrf TRISA

Also make sure that after context saving in the interrupt, you change to the correct bank, because it could be in the wrong one in any complex program. Restoring context will put it back in the right bank.

Last edited: