View previous topic :: View next topic |
Author |
Message |
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
#ASM directives |
Posted: Thu Jul 29, 2004 6:44 am |
|
|
I still have big troubles while writing in FLASH memory with a 18F442 and had to implement assembly language routine specifyied by microchip datasheet but this is not the debate right now.
My question is why can't I implement "MOVLW ee_block>>8" between the 2 directives. The more surprising is that when the compiler translate code from C to assembly that's exactly what it does. But when I want to rewrite it myself between the two directives it doesn't compile any more !
My second question is : I noticed some other differences between what you see in the .lst file and the way you have to implement your own assembly language. Is this documented somewhere ?
exemple :
void whatever_function()
{
int16 eeblock;
#ASM
MOVLW ee_block>>8
MOVWF FSR0H
MOVLW ee_block
MOVWF FSR0L
#ENDASM
} |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1933 Location: Norman, OK
|
ASM |
Posted: Thu Jul 29, 2004 7:06 am |
|
|
This compiler does not use MPASM to compile the assembly language portions and the CCS compiler abilities are limted. I have run into this on several occasions. In your case I would implement the shift using individual instructions. Some infomation on the ASM mnemonics is available in the manual under #ASM on page 28 of the 5/19/03 manual. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Thu Jul 29, 2004 9:12 am |
|
|
I tried MOVLW &ee_block +1 already but the compiler says expecting an identifier and gives an error |
|
|
Ttelmah Guest
|
|
Posted: Thu Jul 29, 2004 10:53 am |
|
|
Schmobol wrote: | I tryied MOVLW &ee_block +1 already but the compiler says expecting an identifier and gives an error |
You have to have a variable defined called 'ee_block', which is 'active' in the routine concerned (remember a variable defined in 'main', is not visible in a subroutine, and vice versa).
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Jul 29, 2004 2:32 pm |
|
|
Should be
|
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Fri Jul 30, 2004 12:36 am |
|
|
That's right. I just wrote those lines as an example but in the original file the declaration of the variables are right. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Jul 30, 2004 4:44 am |
|
|
Then maybe you should post the code that you are actually having problems with. |
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Mon Aug 02, 2004 12:37 am |
|
|
Here is the routine (it hasn't been cleaned up). When I use &ee_block I get an error at compiling saying"expecting an identifier"
Code: |
#BYTE TBLPTRU = 0xff8
#BYTE TBLPTRH = 0xff7
#BYTE TBLPTRL = 0xff6
#BYTE TABLAT= 0xff5
#BYTE EECON1 = 0xfa6
#BYTE EECON2 = 0xfa7
#BYTE INTCON = 0xff2
#BYTE INTCON2 = 0xff1
#BYTE INTCON3 = 0xff0
#BYTE PIE1 = 0xf9d
#BYTE PIE2 = 0xfa0
#BYTE FSR0H = 0xfea
#BYTE FSR0L = 0xfe9
#BYTE POSTINC0 = 0xfee
void kind_write_program_eeprom (int32 address, int16 data)
{
int16 current_data;
int16 ee_block[32];
int32 ee_block_address;
int ee_block_index;
int counter_hi, counter,i;
int flash_scratch[5];
//disable_interrupts(INT_RDA);
current_data = read_program_eeprom (address);
if (current_data != data) {
ee_block_address = address & 0xFFFFFFC0;
ee_block_index = (int)((address & 0x0000003F)>>1);
read_program_memory (ee_block_address, ee_block, 64);
ee_block[ee_block_index] = data;
disable_interrupts(GLOBAL);
setup_timer_0(RTCC_OFF);
setup_timer_1(T1_DISABLED);
flash_scratch[0]=INTCON;
flash_scratch[1]=INTCON2;
flash_scratch[2]=INTCON3;
flash_scratch[3]=PIE1;
flash_scratch[4]=PIE2;
INTCON&=0x07;
INTCON2&=0xff;
INTCON3&=0xe7;
PIE1=0;
PIE2=0;
//write_program_memory (ee_block_address, ee_block, 64);
#ASM
ERASE_BLOCK:
MOVFF &ee_block_address+2,TBLPTRU
MOVFF &ee_block_address+1,TBLPTRH
MOVFF &ee_block_address,TBLPTRL
BSF EECON1,7 // point to FLASH memory
BCF EECON1,6 // access FLASH memory
BSF EECON1,2 // enable write to memory
BSF EECON1,4 // enable Row Erase operation
//BCF INTCON, 7 // disable interrupts
MOVLW 0x55
MOVWF EECON2
MOVLW 0xaa
MOVWF EECON2
BSF EECON1,1
//BSF INTCON,7
TBLRD*-
WRITE_BUFFER_BACK :
MOVLW 8
MOVWF counter_hi
//CLRF FSR0H
MOVFF &ee_block+1, FSR0H <=================== this is here
MOVLW ee_block
MOVWF FSR0L
//BCF INTCON, 7
PROGRAM_LOOP :
MOVLW 8
MOVWF counter
WRITE_WORD_TO_HREGS :
MOVF POSTINC0, W
MOVWF TABLAT
TBLWT+*
DECFSZ counter
BRA WRITE_WORD_TO_HREGS
PROGRAM_MEMORY :
BSF EECON1, 7
BCF EECON1, 6
BSF EECON1, 2
//BCF INTCON, 7
MOVLW 0x55
MOVWF EECON2
MOVLW 0xaa
MOVWF EECON2
BSF EECON1, 1
DECFSZ counter_hi
BRA PROGRAM_LOOP
BCF EECON1, 2
//BSF INTCON, 7
#ENDASM
INTCON=flash_scratch[0];
INTCON2=flash_scratch[1];
INTCON3=flash_scratch[2];
PIE1=flash_scratch[3];
PIE2=flash_scratch[4];
clear_interrupt(INT_TIMER0);
clear_interrupt(INT_TIMER1);
clear_interrupt(INT_RDA);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); /* timer 0 16-bit uc = 0.1 µs */
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); /* timer 1 16-bit uc = 0.2 µs */
enable_interrupts(GLOBAL);
//vide_buffer_rs232();
//enable_interrupts(INT_RDA);
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 02, 2004 5:25 am |
|
|
The problem is that 'ee_block', is not itself a variable!...
When dealing with arrays, the 'name' of the array, is a shortcut, to the address of the array. The '&' function in assembler, takes the address of the variable, and allows you to then manipulate this. To deal with an array, you need to explicitely work with a variable, or omit the '&'.
So:
MOVFF &ex_block[0]+1, FSR0H
Should select the second byte.
Best Wishes |
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Mon Aug 02, 2004 5:52 am |
|
|
Thank you for your cooperation |
|
|
Schmobol
Joined: 01 Mar 2004 Posts: 22 Location: Nice, France
|
|
Posted: Mon Aug 02, 2004 6:01 am |
|
|
I have a doubt all of a sudden. What I want to do here is to load FSR0L with the lowwer part of ee_block[0] address and FSR0H with the upper part of it.
MOVFF &ex_block[0]+1, FSR0H is going to load FSR0H with the content of the address &ex_block[0]+1 not with the upper part of ee_block[0]. Isn't it ?
When compiled by CCS the assembly looks like
MOVLW ee_block>>8
ADDWFC @03,W
MOVWF FSR0H
...
Why can't I write MOVLW ee_block>>8 myself ? or something like MOVLW &ee_block[0]>>8 (error: expression must evaluate to a constant ). What's good in the lst file should be good for the #ASM #ENASM directive !
I get mixed up, could you help me clarifying the situation |
|
|
RossJ
Joined: 25 Aug 2004 Posts: 66
|
|
Posted: Sun Nov 21, 2004 7:09 pm |
|
|
Has anyone found a way around this problem (apart from using literal constants)? Has CCS acknowledged this as a bug? Has it been submitted?
I have found the following...
Code: |
int8 ee_block[10];
#asm
MOVLW ee_block // ok
MOVLW &ee_block[0] // ok
MOVLW ee_block + 1 // ok
MOVLW ee_block - 1 // ok
MOVLW ee_block * 1 // error: expression must evaluate to a constant
MOVLW ee_block / 1 // error: expression must evaluate to a constant
MOVLW ee_block & 1 // error: expression must evaluate to a constant
MOVLW ee_block >> 1 // error: expression must evaluate to a constant
#endasm
|
These are all constant expressions. However, it appears that only +/- are permitted!
Of course what is really needed is the high and low instructions offered by MPASM. |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
1 year later |
Posted: Sun Nov 27, 2005 12:12 pm |
|
|
I'm having the same problem.
Is there no solution yet?? |
|
|
Ttelmah Guest
|
|
Posted: Sun Nov 27, 2005 4:12 pm |
|
|
What problem?.....
The syntax in CCS, is different, but works OK. it is 'illogical', but the instructions work fine.
If you want something that makes it mentally easier to work with, try something like:
#define ASMLOBYTE(x) x
#define ASMHIBYTE(x) &x+1
Then if you have:
Code: |
int16 value;
//In your assembler, you can use:
#asm
MOVF ASMLOBYTE(value),0
//Will put the low byte of 'value' into W
MOVF ASMHIBYTE(value),1
//Will put the high byte of value into W
#endasm
|
Best Wishes |
|
|
|