CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Cant write asm in correct adress

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
lozzik



Joined: 03 Nov 2006
Posts: 12

View user's profile Send private message

Cant write asm in correct adress
PostPosted: Fri Nov 03, 2006 4:10 am     Reply with quote

Hi,
i am using the PCWH 3,249
in my project there is some codes that have to be executet at startup before anything others. So i am writing it in the first letter in main function. But CCS generates some other codes before my code (defining variables etc.).
i have contactet with ccs support and they have said that i could it by using the #build, #org and #rom combination. i couldnt use the #rom and there is no examples in ccs
can anybody help me to execute my code before anything other.

Thanks an sorry for my english
Ttelmah
Guest







PostPosted: Fri Nov 03, 2006 5:00 am     Reply with quote

#build, is in the manual now. If you have an older compiler (before it was documented here), look in the compiler directory, for the 'readme.txt' file, which documents the 'extras'.
The key is that with this, you can move the start of the _CCS_ code to a point higher in memory. So if you have:
#build(reset=0x100)

CCS, will put _it's_ code, starting at address 0x100.
Then you would need to put your assembler at the bottom of memory, and end it with a jump to this address.
If you are using interrupts, you would need to either reloctate the handler for these as well, or 'jump round' this.
Have a look in the examples, for the bootloader stuff (ex_bootload.c). The bootloader is done, by having the bootloader code at the bottom of memory, where it is run first, and checks to see if particular conditions are met for it to start working. If not, the code then jumps to the relocated 'main' function. Hence the relocation involved, is exactly what you need to do.

Best Wishes
Guest








PostPosted: Fri Nov 03, 2006 7:47 am     Reply with quote

i have looked the example bootloader.c
and i write my code so:

first
#build(reset=0x00020)
then

#org 0,10{} //this adresses will be reserwed by compiling
then

#org 0
a jump to my code that has to be executed first
at the end of my code there is a jump back to main
#org default

with this code i have still a problem
the code that has to be executet first runs without any problems but it doesnt jump to main everytime, it jumps sometimes that shows the adress is true but why not everytime.
in summary the code works sometimes how can this be possible
Guest








PostPosted: Fri Nov 03, 2006 8:00 am     Reply with quote

Without seeing what your code is doing, this sounds like something in the addressing is wrong. Note that your 'org' statement, only allows enough space for five instructions in your code (10 != 0x10).
I'd suggest declaring as:
Code:

#build(reset=0x20)
#org 0,0x1F
void boot(void) {
#asm
   //No 'jump' is needed. This code is at address 0

   //Other code here as needed
   goto 0x20
#endasm
}

#org default
void main() {

Just one other comment. Some PICs, have a fault, that requires there is a NOP at address 0.

Best Wishes
lozzik



Joined: 03 Nov 2006
Posts: 12

View user's profile Send private message

PostPosted: Fri Nov 03, 2006 8:40 am     Reply with quote

here is my code

Code:
#include <18f4620.h>
#fuses intrc,NOWDT,PROTECT,NOLVP,NOBROWNOUT,NOMCLR,NOPBADEN
#build(reset=0x00020)
#org 0,0x10 {}
#use delay(clock=4000000)

void yaz(int i)
{
   output_b(i);
   output_high(PIN_A0);
   delay_us(2);
   output_low(PIN_A0);
}

#ORG 0
void jump_to_boot(void) //it jumps to boot program that has to be run first
{
   delay_cycles(1);
   goto_address(0x00066);
}
#ORG default


void boot(void)
{
int i;
for(i=3;i>0;i--)
{
      yaz(1);
      delay_ms(250);
      yaz(0);
      delay_ms(100);
}
   set_tris_b(0);
   output_b(0);
   set_tris_a(0x00);
   output_low(PIN_A2);
   goto_address(0x0009E); // jump to main
}
void main()
{
   setup_oscillator(OSC_4MHZ);
   delay_ms(20);
   while(1)
   {
      yaz(1);
      delay_ms(250);
      yaz(0);
      delay_ms(100);
   }
   boot();
}


and here is the list file


    CCS PCH C Compiler, Version 3.249, 34456 03-Kas-06 16:33

    Filename: C:\xxxx

    ROM used: 192 bytes (0%)
    Largest free fragment is 65316
    RAM used: 5 (0%) at main() level
    7 (0%) worst case
    Stack: 3 worst case (2 in main + 1 for interrupts)

    *
    00020: GOTO 009E
    .................... #include <18f4620.h>
    .................... //////// Standard Header file for the PIC18F4620 device ////////////////
    .................... #device PIC18F4620
    .................... #list
    ....................
    .................... #fuses intrc,NOWDT,PROTECT,NOLVP,NOBROWNOUT,NOMCLR,NOPBADEN
    .................... #build(reset=0x00020)
    .................... #org 0,0x10 {}
    .................... #use delay(clock=4000000)
    *
    00028: CLRF FEA
    0002A: MOVLW 07
    0002C: MOVWF FE9
    0002E: MOVF FEF,W
    00030: BZ 0050
    00032: MOVLW 01
    00034: MOVWF 01
    00036: CLRF 00
    00038: DECFSZ 00,F
    0003A: BRA 0038
    0003C: DECFSZ 01,F
    0003E: BRA 0036
    00040: MOVLW 4A
    00042: MOVWF 00
    00044: DECFSZ 00,F
    00046: BRA 0044
    00048: NOP
    0004A: NOP
    0004C: DECFSZ FEF,F
    0004E: BRA 0032
    00050: RETLW 00
    ....................
    .................... void yaz(int i)
    .................... {
    .................... output_b(i);
    00052: CLRF F93
    00054: MOVFF 07,F8A
    .................... output_high(PIN_A0);
    00058: BCF F92.0
    0005A: BSF F89.0
    .................... delay_us(2);
    0005C: NOP
    0005E: NOP
    .................... output_low(PIN_A0);
    00060: BCF F92.0
    00062: BCF F89.0
    .................... }
    00064: RETLW 00
    ....................
    .................... #ORG 0
    .................... void jump_to_boot(void) //it jumps to boot program that has to be run first
    .................... {
    .................... delay_cycles(1);
    *
    00000: NOP
    .................... goto_address(0x00066);
    00002: GOTO 0066
    .................... }
    00006: RETLW 00
    .................... #ORG default
    ....................
    ....................
    .................... void boot(void)
    .................... {
    .................... int i;
    .................... for(i=3;i>0;i--)
    *
    00066: MOVLW 03
    00068: MOVWF 06
    0006A: MOVF 06,F
    0006C: BZ 0088
    .................... {
    .................... yaz(1);
    0006E: MOVLW 01
    00070: MOVWF 07
    00072: RCALL 0052
    .................... delay_ms(250);
    00074: MOVLW FA
    00076: MOVWF 07
    00078: RCALL 0028
    .................... yaz(0);
    0007A: CLRF 07
    0007C: RCALL 0052
    .................... delay_ms(100);
    0007E: MOVLW 64
    00080: MOVWF 07
    00082: RCALL 0028
    .................... }
    00084: DECF 06,F
    00086: BRA 006A
    .................... set_tris_b(0);
    00088: MOVLW 00
    0008A: MOVWF F93
    .................... output_b(0);
    0008C: CLRF F93
    0008E: CLRF F8A
    .................... set_tris_a(0x00);
    00090: MOVWF F92
    .................... output_low(PIN_A2);
    00092: BCF F92.2
    00094: BCF F89.2
    .................... goto_address(0x0009E); // jump to main
    00096: GOTO 009E
    .................... }
    0009A: GOTO 00DA (RETURN)
    .................... void main()
    .................... {
    0009E: CLRF FF8
    000A0: BCF FD0.7
    000A2: CLRF FEA
    000A4: CLRF FE9
    000A6: MOVLW 60
    000A8: MOVWF FD3
    000AA: MOVF FC1,W
    000AC: ANDLW C0
    000AE: IORLW 0F
    000B0: MOVWF FC1
    000B2: MOVLW 07
    000B4: MOVWF FB4
    .................... setup_oscillator(OSC_4MHZ);
    000B6: MOVLW 60
    000B8: MOVWF FD3
    .................... delay_ms(20);
    000BA: MOVLW 14
    000BC: MOVWF 07
    000BE: RCALL 0028
    .................... while(1)
    .................... {
    .................... yaz(1);
    000C0: MOVLW 01
    000C2: MOVWF 07
    000C4: RCALL 0052
    .................... delay_ms(250);
    000C6: MOVLW FA
    000C8: MOVWF 07
    000CA: RCALL 0028
    .................... yaz(0);
    000CC: CLRF 07
    000CE: RCALL 0052
    .................... delay_ms(100);
    000D0: MOVLW 64
    000D2: MOVWF 07
    000D4: RCALL 0028
    .................... }
    000D6: BRA 00C0
    .................... boot();
    000D8: BRA 0066
    .................... }
    000DA: SLEEP

    Configuration Fuses:
    Word 1: 0900 NOIESO INTRC NOFCMEN RESERVED
    Word 2: 1E19 NOBROWNOUT NOWDT BORV21 NOPUT WDT32768
    Word 3: 0100 CCP2C1 NOPBADEN NOLPT1OSC NOMCLR RESERVED
    Word 4: 0081 STVREN NODEBUG NOLVP NOXINST RESERVED
    Word 5: C000 PROTECT NOCPD NOCPB
    Word 6: E00F NOWRT NOWRTD NOWRTC NOWRTB
    Word 7: 400F NOEBTR NOEBTRB


with this code if i run the circuit first it doesnt works (i mean the boot program runs and it doesnt return to main) after a reset both are working how can this possible

thanks
Guest








PostPosted: Fri Nov 03, 2006 9:11 am     Reply with quote

You are doing so much jumping around, that it is hard to work out what the implications are. I'd suggest tidying things a lot. You do not need two sets of org statements. Use something like this:
Code:

#include <18f4620.h>
#fuses intrc,NOWDT,PROTECT,NOLVP,NOBROWNOUT,NOMCLR,NOPBADEN
#build(reset=0x10)
#use delay(clock=4000000)
void yaz(int i); //prototype for yaz
void boot(void); //prototype for boot

#ORG 0,0xF
//Place at bottom of memory. It jumps to boot program that has to be run first
void jump_to_boot(void) {
   delay_cycles(1);
   boot();
   goto_address(0x10);
}

#org default
//Now everything else, wants normal definitions
void boot(void) {
   int i;
   for(i=3;i>0;i--) {
      yaz(1);
      delay_ms(250);
      yaz(0);
      delay_ms(100);
}
   set_tris_b(0);
   output_b(0);
   set_tris_a(0x00);
   output_low(PIN_A2);
   //goto_address(0x040); // jump to main
   //Do _not_ do this. This is fine if 'boot' is only used from the boot,
   //but since you also call it from the main, will result in a stack overflow
   //Let the code return,and handle this in the loader.
}

void yaz(int i) {
   output_b(i);
   output_high(PIN_A0);
   delay_us(2);
   output_low(PIN_A0);
}

void main(void) {
   setup_oscillator(OSC_4MHZ);
   delay_ms(20);
   while(1)
   {
      yaz(1);
      delay_ms(250);
      yaz(0);
      delay_ms(100);
   }
   boot();
}
lozzik



Joined: 03 Nov 2006
Posts: 12

View user's profile Send private message

PostPosted: Fri Nov 03, 2006 9:41 am     Reply with quote

Thank you for your repleys.
This code is much easier than the first.
I have written this one. But i have still the same problem. I cant understand how this can happen code works sometimes and somtimes not.
I am swtiching the circuit on everything is okey the boot program runs then it returns to main. I am switching the circuit off starting again this time the boot program runs again but it doesnt returns to main.
i am gonna try with different adresses and different pic.
lozzik



Joined: 03 Nov 2006
Posts: 12

View user's profile Send private message

PostPosted: Fri Nov 03, 2006 9:51 am     Reply with quote

here is the reply from ccs support
do you now using the #rom directive

Quote:
1. Use #BUILD( reset=xxxx ) to put the compilers jump to
main at some new place in memory (like 0x100).

2. Create a function with your code in it. At the end of this
function do a GOTO_ADDRESS(xxxx) and use #ORG to
fix this function at some address (yyyy).

3. Use #ROM 0={...} to insert a GOTO instruction at location 0
to jump to yyyy. You could do this in C with a #org'ed function
but make sure it does not run into the interrupt vector.


thanks again.
Ttelmah
Guest







PostPosted: Fri Nov 03, 2006 11:04 am     Reply with quote

Read what they say again.
You will see that they say you can do the jump using #org, _or_ #rom. The 'danger' with the ORG approach, is that if you have interrupt vectors in use (remember I asked this, and your sample code does not show this), it uses an extra instruction for the 'return' at the end of the ORG'd function, and this can clash with interrupt vectors. You do not need the ROM approach.
ROM, simply allows you to define individual bytes/words to be written to a particular memory location.
You couldn't use the ROM approach easily, since you are doing something they did not expect, and wanting to call the same routine again inside the main code. This _requires_ the extra return instruction is present...
Seriously, the code as posted works (I checked it did, before I posted it). The behaviour you are seeing is something to do with the enviroment you are testing it in.

Best Wishes
lozzik



Joined: 03 Nov 2006
Posts: 12

View user's profile Send private message

PostPosted: Sat Nov 04, 2006 1:28 am     Reply with quote

@Ttelmah

Thank you again for your replys
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group