View previous topic :: View next topic |
Author |
Message |
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
[solved] Problem with a delay_ms |
Posted: Wed Feb 13, 2013 5:36 am |
|
|
Hello,
The following code runs well, and my led is blinking as intended :
Code: | #include <33EP256GP506.h>
#fuses ICSP1 // ICD uses PGC1/PGD1 pins
#fuses NOJTAG // JTAG disabled
#fuses NODEBUG // Debug mode for use with ICD
//#fuses ALTI2C1 // I2C1 mapped to ASDA1/ASCL1 pins
//#fuses ALTI2C2 // I2C2 mapped to ASDA2/ASCL2 pins
#fuses NOWDT // No watchdog timer
#FUSES FRC_PLL //Internal Fast RC oscillator with PLL
#FUSES
#use delay (clock=50000000)
#USE FAST_IO(a)
#USE FAST_IO(b)
#USE FAST_IO(c)
#USE FAST_IO(d)
#USE FAST_IO(e)
#USE FAST_IO(f)
#USE FAST_IO(g)
#define LED_BLINK PIN_A7
/////////////////////////
// Programme principal //
/////////////////////////
void main()
{
int i;
//
//// Ports I/O
set_tris_a(0xE37F);
set_tris_b(0xFFFF);
set_tris_c(0xFFFF);
set_tris_d(0xFFFF);
set_tris_e(0xFFFF);
set_tris_f(0xFFFF);
set_tris_g(0xFFFF);
//
//// Boucle
do
{
output_high(LED_BLINK);
for(i= 0; i<100; i++)
{
delay_ms(2);
}
output_low(LED_BLINK);
for(i= 0; i<100; i++)
{
delay_ms(2);
}
} while (TRUE);
} |
But, if I replace delay_ms(2) by delay_ms(3), my program doesn't work anymore, and my chip seems to reset constantly.
These symptoms also appears if I comment the for loops.
Last edited by Fabrici on Thu Feb 14, 2013 5:17 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9241 Location: Greensville,Ontario
|
|
Posted: Wed Feb 13, 2013 6:13 am |
|
|
I don't use that PIC but...
I see the last #FUSES doesn't have anything after it.
Perhaps that is 'resetting' all the FUSES to default values,which might enable the WDT alowing the PIC to be reset at <3ms ?
I'd dump the listing ( project.lst file ) and see what the fuses are set to.They'll be shown at the end of the file.
hth
Jay |
|
|
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
|
Posted: Wed Feb 13, 2013 7:22 am |
|
|
Hello Jay,
I deleted a lot of lines from my program, to isolate the issue, and ... forget this FUSE. I'm sorry for this. However, I've checked program by deleting it and the issue remains the same.
Here are the fuses shown at the end of the lst file :
Code: | Configuration Fuses:
Word 3L: 008B ICSP1 NOJTAG NODEBUG
H: FF00
Word 4L: 00F0 NOALTI2C1 NOALTI2C2 WDTWIN_25%
H: FF00
Word 5L: 007F WPOSTS16 WPRES128 PLLWAIT WINDIS NOWDT
H: FF00
Word 6L: 00E7 NOPR NOOSCIO IOL1WAY
H: FF00
Word 7L: 0081 FRC_PLL IESO
H: FF00
Word 8L: 0003 NOWRT NOPROTECT
H: FF00
Word 9L: 0000
H: FF00
Word 10L: 0000
H: FF00 |
Here is my compiler version :
Code: | CCS PCD C Compiler, Version 4.140, 7054 |
Fabrice |
|
|
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
|
Posted: Wed Feb 13, 2013 7:32 am |
|
|
By using the lst file, I've tried to see how compiler traduct delay_ms(2), and delay_ms(3). I was very surprised to see that it didn't generate the same type of code :
Code: | .................... delay_ms(3);
0023E: MOV #3,W0
00240: CALL 200
....................
.................... delay_ms(2);
00244: REPEAT #34E
00246: NOP
00248: REPEAT #3FFF
0024A: NOP
0024C: REPEAT #3FFF
0024E: NOP
00250: REPEAT #3FFF
00252: NOP
.................... |
|
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Wed Feb 13, 2013 7:33 am |
|
|
can you see a difference if you compare the .LST files for each version? |
|
|
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
|
Posted: Wed Feb 13, 2013 7:40 am |
|
|
Oooops, it seems that we've posted at the same time.
Effectively, generated code differs from delay_ms(2) and delay_ms(3) :
Code: | .................... delay_ms(3);
0023E: MOV #3,W0
00240: CALL 200
....................
.................... delay_ms(2);
00244: REPEAT #34E
00246: NOP
00248: REPEAT #3FFF
0024A: NOP
0024C: REPEAT #3FFF
0024E: NOP
00250: REPEAT #3FFF
00252: NOP
.................... |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Wed Feb 13, 2013 8:24 am |
|
|
OK. So once it goes over 2mSec, it starts using a subroutine. This is when it goes wrong.
Maybe try expanding the stack?.
Though you seem to be using so little, that I can't believe it'd overflow on this (normally it's things like complex printf statements, and maths that gives this problem), worth a try.
Or add some diagnostics, and see what the restart is caused by.
Best Wishes |
|
|
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
|
Posted: Wed Feb 13, 2013 11:04 am |
|
|
Using #build(stack=1024) or #build(stack=2048) doesn't seems to have any effect on this issue.
I've added some diagnostics to the code, and I can see that restart is caused by a trap conflict (RESTART_TRAP_CONFLICT).
I don't have a RS232 port connected with this application, and don't know how to investigate further.
The code that is executed by delay_ms(3) is this one :
Code: | .................... #use delay (clock=50000000)
*
00200: CP0 W0
00202: BTSC.B 42.1
00204: BRA 212
00206: REPEAT #21A3
00208: NOP
0020A: REPEAT #3FFE
0020C: NOP
0020E: DEC W0,W0
00210: BRA NZ,206
00212: RETURN |
and is called like this :
Code: | .................... delay_ms(3);
0029C: MOV #3,W0
0029E: CALL 200 |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Feb 14, 2013 2:17 am |
|
|
OK.
I think you are going to have to set up some error trapping, and try to find out what is happening.
'Trap conflict', is unfortunately a vague problem. It basically means an error that has not been handled by anything else!.
Question is 'what error'.
A quick search on the forum, will find a number of threads, giving 'how to' set up some error detection, and this should allow you to narrow down the actual problem. I'd guess possibly an address error trap.
A couple of other comments:
You have a #fuses line, with no fuse. Might give a compiler oddity.
You select the ICD pins, but then specify nodebug?.
These are the sort of things that can make the compiler do something 'unexpected'. Worth experimenting here.
Best Wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Feb 14, 2013 4:02 am |
|
|
OK.
I've just compiled it 'as is', except for getting rid of the odd fuse lines. Stuck it into a debugger.
It calls the delay routine, and the return address appears to be merrily on the stack. Executes the single cp instruction, and the return address has gone. Then when it returns (obviously), error.
A quick look, shows the problem. The compiler by default is locating the stack in an area where there is not the memory for it. Hence the value is not legitimate, and the return is lost.....
If you build the code with an explicit stack declaration:
#build (STACK=0x1000:0x1200)
Into an area of RAM that is suitable, then the code bursts into life.
It's obviously an error in the device database for the chip (what another....), and needs to be reported to CCS.
it actually puts the stack at the top of the SFR data space, where any addresses that actually are implemented are registers, and obviously should not be overwritten....
Best Wishes |
|
|
Fabrici
Joined: 11 Feb 2013 Posts: 19 Location: Toulouse - France
|
|
Posted: Thu Feb 14, 2013 5:10 am |
|
|
I've just tested and it works perfectly on my design.
Thank you so much for your help. |
|
|
Tasark
Joined: 25 Jan 2011 Posts: 12
|
|
Posted: Thu Feb 14, 2013 12:00 pm |
|
|
Quote: | If you build the code with an explicit stack declaration:
#build (STACK=0x1000:0x1200) |
I looked through the datasheet and couldn't find where it declares where the RAM is at address wise that you found. Could you point me there? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Feb 14, 2013 12:26 pm |
|
|
Big section about the memory (section 4), starts with program memory, then the RAM. The RAM 'map', has the SFR's occupying the addresses up to 0x1000, then RAM. The SFR area only has registers that actually 'exist' implemented. The default being used by the compiler is 0xF00, which is an almost unimplemented area at the top of the SFR's. The compiler is meant to default to using the top of the RAM area, so is getting this 'wrong'....
I'd probably put the stack at the top of RAM, but for a simple test went for the bottom. The chip itself defaults to using 0x1000 when it boots.
The reason to use the top, is that the low section can be accessed faster by code, so best not to 'waste' this for stack usage. 0xCE00 to 0xCFFF possibly.
Page 50 Fig 4.7 and page 109 section 4.4.4
Figure 4-16 specifically for your chip, but then they can't count, and have 0xEFFE before 0xD000.... For E read C here.
Best Wishes |
|
|
|