View previous topic :: View next topic |
Author |
Message |
Matro Guest
|
How to : 2 questions in 1 thread about CCS capabilities... |
Posted: Thu Mar 13, 2008 11:10 am |
|
|
Hi everybody,
As announced in the subject, I've got 2 (more) questions.
- How to change the location of the ISR dispatcher?
I found an explanation on CCS help (JUMP_TO_ISR) but I'd need to write my own dispatcher and I don't want to do so.
Is there a mean to keep the CCS ISR dispatcher but to change its location?
- How to change the behavior of "write_eeprom()"?
When compiled the "write_eeprom()" function launches the EEPROM writing and then waits for it to be finished.
I'd prefer that it checks at the beginning if a "write" is already in progress (and either wait for it to end or exit) and if it is OK that it launches the "write".
Is there a way to obtain this behavior without writing my own function?
Thanks in advance for your helpful answers,
Matro. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 13, 2008 11:39 am |
|
|
Quote: | I'd prefer that it checks at the beginning if a "write" is already in progress |
You can tell the compiler to do that by adding the #device statement
shown in bold below.
Quote: | #include <16F877.H>
#device(write_eeprom=ASYNC)
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
//======================================
void main()
{
write_eeprom(0x22, 0x34);
while(1);
} |
|
|
|
Matro Guest
|
|
Posted: Fri Mar 14, 2008 2:22 am |
|
|
That's perfect!
Thanks for that tip. Strange thing that it isn't documented in the help of CCS...
One of my 2 question already answered.
If somebody knows the solution for the first one it can be very helpful.
Thanks again for the help.
Matro. |
|
|
Ttelmah Guest
|
|
Posted: Fri Mar 14, 2008 4:15 am |
|
|
For the second question.
#build(interrupt=xxxx)
Best Wishes |
|
|
Matro Guest
|
|
Posted: Fri Mar 14, 2008 6:24 am |
|
|
Thanks for that tips.
It works fine. There is just a last problem to solve.
At now my code is as follow :
Code: |
#define INT_ADDR 0x020
#build(interrupt = INT_ADDR)
#ORG 0x004,0x01F
void jump_to_int(void)
{
#ASM
GOTO INT_ADDR
#ENDASM
}
|
As you can imagine I have to jump from the 0x004 address to my new ISR dispatcher.
This code works but due to the fact I declare a "jump_to_int" function the
"GOTO INT_ADDR"
is followed by a
"RETLW 00"
and I don't find it very proper.
Is there a mean to place this "GOTO INT_ADDR" in the 0x004 location without having this "RETLW 00" i.e. without creating a function?
Thanks in advance for every helpful answer (and thanks Ttelmah for that big step ;-) )
Matro |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Mar 14, 2008 1:12 pm |
|
|
Quote: | Is there a mean to place this "GOTO INT_ADDR" in the 0x004 location without having this "RETLW 00" i.e. without creating a function? | I was playing with this same question in my bootloader. A function will always terminate with a RETLW, that's why it is a function. The solution I found was to use #int_global. This places an empty ISR dispatcher at address 0x0004.
Code: | #define INT_ADDR 0x020
#int_global
void isr(void)
{
#asm
GOTO INT_ADDR
#endasm
} | My bootloader did not use interrupts. For you there might be a problem as I don't think the above workaround can be combined with the #build keyword.
Maybe we can give you a better solution if you tell us more about what you want to achieve.
- Why do you want to make your own dispatcher?
- And why have this next to the default CCS dispatcher?
- Which chip are you using (PIC16 or PIC18)? |
|
|
Matro Guest
|
|
Posted: Mon Mar 17, 2008 4:24 am |
|
|
Hi ckielstra,
I will explain a little bit more what I need if it can help you. :-)
I don't want to make my own dispatcher but to keep the CCS one.
But I want it to be place elsewhere that in the address 0x04.
Why?...
My program contains a bootloader and I don't want that the jump to it (addresses 0x00 - 0x03) can be erased.
The problem is that I work with a PIC16F88 with which the program memory is erased by 32-byte blocks.
And finally I want also the user to be able to change the ISR dispatcher.
So I can't place it at the standard 0x04 address because erasing this address and next ones will also delete the bootloader jump.
I hope I was clear in this explanation (and I hope too that somebody could find a solution).
Thanks for your answer but it can't definitely not be OK for me. ;-)
Matro. |
|
|
Matro Guest
|
|
Posted: Tue Mar 18, 2008 5:23 am |
|
|
Sorry to up this subject but it will be a very nice thing if my question could be answered. ;-)
Does somebody know how to compile a function that never returns (like the built-in "reset_cpu()" does)?
Or eventually how to place a single ASM instruction in a specific memory location?
Thanks in advance.
Matro. |
|
|
Guest_7068 Guest
|
|
Posted: Wed Mar 19, 2008 5:25 am |
|
|
See if this works for you
Code: |
#rom 0x0004={0x2840}
|
The #rom directive will put that data in the ROM location and it will not care if it overlaps with something else. So make sure you test this fully.
The 0x2840 is the Op-Code for a GOTO 0x0040. This opcode will assume that the PCLATH is cleared which is the case after reset. I have not tested this, but I think this hack should work. |
|
|
Matro Guest
|
|
Posted: Wed Mar 19, 2008 6:26 am |
|
|
Nice. I will test it and append this thread about it. But it is not today priority, so il will be in some time.
Thanks for the tip.
Matro. |
|
|
|