Indirect adressing (FSR, INDF registers)

Post
abrakada
Starting Member
2009/11/11 01:51:43
Hi all.
I use PIC18F2550 chip. It seems that decrementing INDF register doesnt  work with  DECFSZ instruction. I dont know why. Here is my code:

#pragma udata
char temp;
char counter;

void ds_TX(char data)
{
  FSR0=(short long)&temp;
  FSR1=(short long)&counter;
  FSR2=(short long)&data;
 
_asm
DS_TX:
   MOVLB    0x0F
   MOVF    INDF2,0,1   // data-->WREG
   MOVWF    INDF0,1        // WREG-->temp
   MOVLW    .8            // WREG=8 (counter)
   MOVWF    INDF1,1        // 0x8-->counter
DS_TX_Loop:
   BCF      TRISA,ds_pin,1
   BCF      PORTA,ds_pin,1    
_endasm
   pause_short(0xA);
_asm
   MOVLB    0x0F
   RRCF     INDF0,1,1 
   BTFSC     STATUS,2,1
   BSF         PORTA,ds_pin,1
_endasm   
  pause_short(0x32);
_asm
   MOVLB    0x0F
   BSF      PORTA,ds_pin,1    
   BSF      TRISA,ds_pin,1
   DECFSZ   INDF1,1,1 //decrement counter, out if zero
   GOTO    DS_TX_Loop
_endasm
}//end ds_TX


Pause procedure works good. Maybe something wrong with bank selecting? Can someone take a look please?

thanks.
post edited by abrakada - 2009/11/11 01:52:43
BitWise
Super Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 02:36:39
Are you sure that FSR0-2 are not being used by the C compiler?

In particular I thought C18 uses one of the (FSR2) as a function argument stack pointer in which case the calls you make between the ASM blocks may be changing the FSR registers.
ppater
Super Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 03:06:50
Hi,
Joke apart: for a bonehead who does not now C, what is a short long?
At first read that lets lol...
Is really such a monster exists?

BTW: You would not need to movlb 15 to address registers through access bank...
To answer your question, as BitWise said, it should work but we do not know:
- What pause_short does...
- If you are in extended mode, FSR2 has a special behavior and cannot be used as a simple pointer (and strongly used by compilers in extended mode)...
post edited by ppater - 2009/11/11 03:24:13
abrakada
Starting Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 07:13:51
Bonehead?!! This forum is to ask questions, isnt it? Maybe you have never made mistakes?
abrakada
Starting Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 07:26:30
i changed code to

#pragma udata access my_access
near char temp;
near int counter;

void ds_TX(char data)
{
 _asm
DS_TX:
    MOVF    data,0,0    // data-->WREG
    MOVWF    temp,0        // WREG-->temp
    MOVLW    .8            // WREG=8 (counter)
    MOVWF    counter,0    // 0x8-->counter
DS_TX_Loop:
    BCF      TRISA,ds_pin,0
    BCF      PORTA,ds_pin,0    
_endasm
    pause_short(0xA);
_asm
    RRCF     temp,1,0 
    BTFSC     STATUS,2,0
    BSF         PORTA,ds_pin,0
_endasm   
   pause_short(0x32);
 _asm
    BSF      PORTA,ds_pin,0    
    BSF      TRISA,ds_pin,0
    DECFSZ   counter,1,0 //decrement counter, out if zero
    GOTO    DS_TX_Loop
_endasm
}//end ds_TX


Maybe this better?
Stefan Uhlemayr
Super Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 12:05:18
ORIGINAL: abrakada

Bonehead?!! This forum is to ask questions, isnt it? Maybe you have never made mistakes?
Hi Vladimir,

you've pretty misinterpreted Philippe's post. He said, that he doesn't know "C" (he much more likes "Pascal", like I do ... Smile), and so he wondered about the "short long"-declaration in your example. "C" is really strange... grin

Greetings,
Stefan
ppater
Super Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 15:15:19
Hi, I often make mistakes, and you just made one...
I was just making a joke on myself and C and this funny syntax; is there a long short too?
ppater
Super Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/11 15:28:27
Hi again,
Ok, so you drop off FSRs; that's a method but like this you still don't know how to use them...
This time there may be a banking problem: where is data? And we still don't know what there is in the delay routine...
Now you may think that mixing HLL and ASM is not straightforward?
Not sure of the "near" behavior for variables too...
Here we really need a real C guru!
abrakada
Starting Member
RE: Indirect adressing (FSR, INDF registers) 2009/11/14 08:59:05
Here is a piece of code, that works:

void ds_TX(char data)
{
_asm
DS_TX:
   MOVWF    temp,0        // data-->temp
   MOVLW    0x8            // WREG=8 (counter)
   MOVWF    counter,0    // 0x8-->counter
DS_TX_Loop:
   BCF      TRISA,ds_pin,0
   BCF      PORTA,ds_pin,0    
_endasm
   pause_short(0xF);
_asm
   RRCF     temp,1,0 
   BTFSC     STATUS,0,0
   BSF         PORTA,ds_pin,0
   nop
_endasm   
  pause_short(0x29);
_asm
   BSF      PORTA,ds_pin,0    
   BSF      TRISA,ds_pin,0
   DECFSZ   counter,1,0 //decrement counter, out if zero
   GOTO    DS_TX_Loop
   nop
_endasm
}//end ds_TX

As you see i got rid of indirect adreesing. And in my second version was only the one mystake:

MOVF    data,0,0    // data-->WREG


It is superfluous to storage data into WREG, because it is already there on the moment of calling procedure.
And what about short long: i think it is something about big integer value (2 or three bytes long), but i am not C gosu.


thanks to all))
DarioG
Scheisse Menschen
RE: Indirect adressing (FSR, INDF registers) 2009/11/16 13:57:02
I was just thinking that, possibly, using Delay ("pause") routines written in assembler - which is a good idea anyway - would have avoided the FSR0 issue...