EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Chipcon/8051 sanity check

Started by FreeRTOS.org March 12, 2007
"Mike Silva" <snarflemike@yahoo.com> wrote in message 
news:1173799493.317207.143470@v33g2000cwv.googlegroups.com...
> That is very weird stuff.
> Are you sure that XSP points to the proper memory?
Going back to my C example: volatile char c = 0; { c++; } which generates: 000366 85 10 82 MOV DPL,XSP(L) 000369 85 11 83 MOV DPH,XSP(H) 00036C E0 MOVX A,@DPTR 00036D 24 01 ADD A,#0x01 00036F F0 MOVX @DPTR,A 000370 80 F4 SJMP 0x0366 SPX contains 0xF1FF, whereas the datasheet states that 0xF000 to 0xFEFF is XRAM. This would therefore seem to be ok. XSP(L) and XSP(H) are in IDATA.
> Have you tried confirming that the code bytes that are getting loaded > into the device are the same bytes in your ASM listing?
The original code - before I cut out everything usefull - has a checksum that is validated on powerup.
> Have you tried changing the MOVX @DPTR,A to a NOP?
> Or even the MOVX A,@DPTR (if it's pointing to the wrong address, could > this read be clearing the INT before it gets recognized?) > What happens if you hard-code the DPTR loading to a fixed known-safe > address?
Makes no difference :-(
> > > Just more straws for your growing collection. :-\
Thanks for the straws anyhow. -- Regards, Richard. + http://www.FreeRTOS.org A free real time kernel for 8, 16 and 32bit systems. + http://www.SafeRTOS.com An IEC 61508 compliant real time kernel for safety related systems.
FreeRTOS.org wrote:
> 000366 C2 AF CLR EA > c++; > 000368 85 10 82 MOV DPL,XSP(L) > 00036B 85 11 83 MOV DPH,XSP(H) > 00036E E0 MOVX A,@DPTR > 00036F 24 01 ADD A,#0x01 > 000371 F0 MOVX @DPTR,A > 000372 D2 AF SETB EA > asm("NOP"); > 000374 00 NOP > 000375 80 EF SJMP 0x0366 > > > As you say - the NOP is required otherwise the interrupt does not fire at > all. I think this is expected though.
not quite, because there is a jump between the INT access opcodes, but you will have a somewhat impractical small % of time where INT is enabled.
> > > > I have tried replacing the increment of c within the loop with the following > inline assembler: > > 1 asm( "MOVX A, @DPTR" ); > 2 asm( "MOV DPL, SP" ); > 3 asm( "NOP" ); > 4 asm( "NOP" ); > 5 asm( "NOP" ); > > With all lines in the problem occurs. > > With line 1 commented out, the problem still occurs. > > With line 2 commented out the problem goes away - even though there are 3 > NOPs following. > > Aaarg!
Rather than remove the lines, I'd swap them with ones of equal size/time, but benign (like NOP) - that keeps as much the same as possible. ie you can determine if it is the smaller loop, or some acceess, that is the trigger. There are bugs where the loop size affects things, as the opcode length changes, and you can get stability when the SW/INT 'phase lock', and problems when they do not. Also check if the code memory location affects this, tho your listing show it moving around - ie pack a variable block of NOPs before the loop. <paste> > with the processor sat in this tight loop the scope shows that lots of timer
> interrupts are being missed, and there is no longer a clean square wave > being output on P1.
Can you get a handle on how many/how long, as that can give clues on the mechanism at work. > 0003D2 75 D8 00 MOV TIMIF,#0x00 Is clearing a whole byte needed ? Std Cores clear TF0, TF1 in HW, and this looks to be a bit-addressable byte. -jg
>> I have tried replacing the increment of c within the loop with the >> following inline assembler: >> >> 1 asm( "MOVX A, @DPTR" ); >> 2 asm( "MOV DPL, SP" ); >> 3 asm( "NOP" ); >> 4 asm( "NOP" ); >> 5 asm( "NOP" ); >> >> With all lines in the problem occurs. >> >> With line 1 commented out, the problem still occurs. >> >> With line 2 commented out the problem goes away - even though there are 3 >> NOPs following. >> >> Aaarg! > > Rather than remove the lines, I'd swap them with ones of equal size/time, > but benign (like NOP) - that keeps as much the same as possible. > ie you can determine if it is the smaller loop, or some acceess, that > is the trigger.
Good plan. The behaviour was the same however. Replacing line 2 with a NOP fixed the problem, whereas replacing line 1 with a nop had no effect.
> There are bugs where the loop size affects things, as the opcode length > changes, and you can get stability when the SW/INT 'phase lock', and > problems when they do not. > > Also check if the code memory location affects this, tho your listing > show it moving around - ie pack a variable block of NOPs before the loop. > > <paste> > > with the processor sat in this tight loop the scope shows that lots > of timer >> interrupts are being missed, and there is no longer a clean square wave >> being output on P1. > > Can you get a handle on how many/how long, as that can give clues on the > mechanism at work.
It is always exactly one interrupt that is missed at a time, never two in a row and always with consistent frequcy when running the tight loop test (see below). With the original code (complete application, different execution paths, etc) it was more like one in 100. However the complete application did sit in a tight loop waiting for the start of a new control cyle, so maybe that is something to look at. In the test program: for( ;; ) { asm( "MOV DPL, sp" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); } 30 NOPs - every 41st interrupt is missed. 15 NOPs - problem goes away. 14 NOPs - every 13th interrupt is missed. 13 NOPs - every 18th interrupt is missed. Change the code to: for( ;; ) { __disable_interrupt(); asm( "MOV DPL, sp" ); __enable_interrupt(); asm( "NOP" ); asm( "NOP" ); } Now exactly every other interrupt is missed. Too much information.
> > 0003D2 75 D8 00 MOV TIMIF,#0x00 > Is clearing a whole byte needed ? > Std Cores clear TF0, TF1 in HW, and this looks to be a bit-addressable > byte.
The original code used TIMIF &= ~0x40; which translated to CLR TIMIF.6 Thanks for taking the time to come up with your suggestions. -- Regards, Richard. + http://www.FreeRTOS.org A free real time kernel for 8, 16 and 32bit systems. + http://www.SafeRTOS.com An IEC 61508 compliant real time kernel for safety related systems.
FreeRTOS.org wrote:
 >> 2    asm( "MOV DPL, SP" );
> Good plan. The behaviour was the same however. Replacing line 2 with a NOP > fixed the problem, whereas replacing line 1 with a nop had no effect.
note that 2 is not a one cycle line, and this does seem to be loop-cycle related. <snip>
> In the test program: > > for( ;; ) > { > asm( "MOV DPL, sp" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > } > > 30 NOPs - every 41st interrupt is missed. > > 15 NOPs - problem goes away. > > 14 NOPs - every 13th interrupt is missed. > > 13 NOPs - every 18th interrupt is missed.
Wow. Still, it is looking like an Int phase issue. Did you try asm( "MOV DPL, B" ); - just in case the SP read has wrinkles.... (same time as MOV DPL, SP) what about fewer NOPs, down to these SJMP $; LJMP $; AJMP $ ( ie no loop at all, try all 3 opcodes ) It's looking like perhaps a JMP cannot be properly interrupted ?.
> > The original code used > > TIMIF &= ~0x40; > > which translated to > > CLR TIMIF.6
Does that make any difference. I'd prefer the clr a single flag, as being safer. Does it say if the HW clears this flag, or not ? - leave it out, and if the 1ms toggle changes drastically, yes, you need it :) -jg
"Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
news:45f71bc4@clear.net.nz...
<snip>
>> In the test program: >> >> for( ;; ) >> { >> asm( "MOV DPL, sp" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> asm( "NOP" ); >> } >> >> 30 NOPs - every 41st interrupt is missed. >> >> 15 NOPs - problem goes away. >> >> 14 NOPs - every 13th interrupt is missed. >> >> 13 NOPs - every 18th interrupt is missed. > > Wow. Still, it is looking like an Int phase issue. > > Did you try > asm( "MOV DPL, B" ); - just in case the SP read has wrinkles.... (same > time as MOV DPL, SP)
Using a different register other than SP has seemingly no impact on the problem, hence I was concluding (somewhat unconvincingly) that it was the DPL that was causing the issue. Can't quite believe that though.
> what about fewer NOPs, down to these SJMP $; LJMP $; AJMP $ > ( ie no loop at all, try all 3 opcodes ) > It's looking like perhaps a JMP cannot be properly interrupted ?.
But: for(;;) { } is fine...........a single line of asm being the branch SJMP 0x0366. Just for kicks I tried this: label1: goto label2; asm( "NOP" ); asm( "NOP" ); label2: goto label3; asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); label3: goto label4; asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); label4: goto label5; asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); label5: goto label6; asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); asm( "NOP" ); label6: // asm( "MOV DPL, b" ); goto label1; and this is fine too, until I uncomment the line immediately below label6.
> > >> >> The original code used >> >> TIMIF &= ~0x40; >> >> which translated to >> >> CLR TIMIF.6 > > Does that make any difference. > I'd prefer the clr a single flag, as being safer. > Does it say if the HW clears this flag, or not ? > - leave it out, and if the 1ms toggle changes drastically, yes, you need > it :) > > -jg
I agree with respect to only clearing the single bit. I changed it as part of the test only. The docs are (to my mind) very ambiguous as to whether the line is needed or not, it seems so for some interrupts and not others. As it happens it makes no difference in this case, but the sample code that comes with the kit has it, so I thought it best to include it. -- Regards, Richard. + http://www.FreeRTOS.org A free real time kernel for 8, 16 and 32bit systems. + http://www.SafeRTOS.com An IEC 61508 compliant real time kernel for safety related systems.
FreeRTOS.org wrote:
> goto label6; > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > asm( "NOP" ); > label6: > // asm( "MOV DPL, b" ); > goto label1; > > > and this is fine too, until I uncomment the line immediately below label6.
What you have enabled is a 3 byte, 2 cycle opcode, of the general form MOV Dir,Dir If Jumps are ok, then it's starting to look like the 3 byte/2 cycle opcode has problems. [and one that certainly belongs in the errata :) ] Other 3 byte 2 cy MOV opcodes are MOV Dir.#Immed, and ANL/ORL/XRL Dir,#Immed so I'd try all forms, and also see if the SFR or DATA memory has any effect. [There are also LJMP/LCALL, DJNZ Dir,RelAdr, CJNE, and Bit opcodes that are 3 byte, 2 cycle ones.]
> I agree with respect to only clearing the single bit. I changed it as part > of the test only. The docs are (to my mind) very ambiguous as to whether > the line is needed or not, it seems so for some interrupts and not others. > As it happens it makes no difference in this case, but the sample code that > comes with the kit has it, so I thought it best to include it.
Seems they were unsure as well ! :) -jg
FreeRTOS.org wrote:
> Change the code to: > for( ;; ) > { > __disable_interrupt(); > asm( "MOV DPL, sp" ); > __enable_interrupt(); > asm( "NOP" ); > asm( "NOP" ); > } > > Now exactly every other interrupt is missed.
Richard, Did you nail this down in the end ? -jg
"Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message 
news:460c2ab8$1@clear.net.nz...
> FreeRTOS.org wrote: >> Change the code to: >> for( ;; ) >> { >> __disable_interrupt(); >> asm( "MOV DPL, sp" ); >> __enable_interrupt(); >> asm( "NOP" ); >> asm( "NOP" ); >> } >> >> Now exactly every other interrupt is missed. > > Richard, > > Did you nail this down in the end ? > > -jg >
Hmm. I eventually got a response from TI. Snippets include "the behaviour is expected" (huh?). "The device is not suitable for volume production or software development". Paraphrasing the rest: "the device is no longer available, customers ordering a dev kit we will now be shipped an ABC dev kit in its place, which has a compatible interface, and then the real part later this year". I also note a waiver form dated January this year saying that the part will only be shipped to customers who sign the waiver to indicate that they know it doesn't work. Red faces all round I think, including us when we talk about our new budget and timescales with our customer :o( (I did not select the part in the first place but we are left with the bill). -- Regards, Richard. + http://www.FreeRTOS.org A free real time kernel for 8, 16 and 32bit systems. + http://www.SafeRTOS.com An IEC 61508 compliant real time kernel for safety related systems.
FreeRTOS.org wrote:
> "Jim Granville" <no.spam@designtools.maps.co.nz> wrote in message > news:460c2ab8$1@clear.net.nz... > >>FreeRTOS.org wrote: >> >>>Change the code to: >>> for( ;; ) >>> { >>> __disable_interrupt(); >>> asm( "MOV DPL, sp" ); >>> __enable_interrupt(); >>> asm( "NOP" ); >>> asm( "NOP" ); >>> } >>> >>>Now exactly every other interrupt is missed. >> >>Richard, >> >> Did you nail this down in the end ? >> >>-jg >> > > > > Hmm. I eventually got a response from TI. Snippets include "the behaviour > is expected" (huh?). "The device is not suitable for volume production or > software development". > > Paraphrasing the rest: "the device is no longer available, customers > ordering a dev kit we will now be shipped an ABC dev kit in its place, which > has a compatible interface, and then the real part later this year". > > I also note a waiver form dated January this year saying that the part will > only be shipped to customers who sign the waiver to indicate that they know > it doesn't work. > > Red faces all round I think, including us when we talk about our new budget > and timescales with our customer :o( > (I did not select the part in the first place but we are left with the > bill).
Yes, it was sounding very like an errata item :) So there was no practical work-around on this ? How different is the replcement part ? -jg

The 2024 Embedded Online Conference