cancel
Showing results for 
Search instead for 
Did you mean: 

Hell Has Frozen Over, NFC CR95HF Library Evaluates True -> False

Richard Lowe
Senior III
Posted on March 29, 2017 at 10:12

Ok, I've seen some strange things in my day but this has got to be the most insane thing I've come across. Need a brilliant person to try to help me explain this:

The NFC CR95HF library is a work in progress but we are using it anyways. The chip detects all types of tags EXCEPT the ones we want to use, Type 4. So debugging the code I come across this situation.

if ((tagsToFind&TRACK_NFCTYPE2) || (tagsToFind&TRACK_NFCTYPE4A))
 {
 PCD_FieldOff();
 HAL_Delay(5);
 ISO14443A_Init( );
 if(ISO14443A_IsPresent() == RESULTOK)
 {
 if(ISO14443A_Anticollision() == RESULTOK)
 {
 if ( ( ( ISO14443A_Card.SAK & 0x60 ) == 0x00 ) && ( tagsToFind & TRACK_NFCTYPE2 ) ) /* TT2 */
 return TRACK_NFCTYPE2;
 else if ( ( ( ISO14443A_Card.SAK & 0x20 ) != 0x00 ) && ( tagsToFind & TRACK_NFCTYPE4A ) )/* TT4A */
 return TRACK_NFCTYPE4A;
 }
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Looking at line The first argument `

ISO14443A_Card.SAK & 0x20 ) != 0x00`

Passes but the next argument ( tagsToFind & TRACK_NFCTYPE4A

fails

..... strange.

tagsToFind is 0xFF

TRACK_NFCTYPE4A is 0x08

Hmmmm. 0xFF & 0x08 does not evaluate to 0.... OK, I'll separate them and make sure which one is failing.

 if ((tagsToFind&TRACK_NFCTYPE2) || (tagsToFind&TRACK_NFCTYPE4A))
 {
 PCD_FieldOff();
 HAL_Delay(5);
 ISO14443A_Init( );
 if(ISO14443A_IsPresent() == RESULTOK)
 {
 if(ISO14443A_Anticollision() == RESULTOK)
 {
 if ( ( ( ISO14443A_Card.SAK & 0x60 ) == 0x00 ) && ( tagsToFind & TRACK_NFCTYPE2 ) ) /* TT2 */
 return TRACK_NFCTYPE2;
 if( ( ( ISO14443A_Card.SAK & 0x20 ) != 0x00 ) ) // && ( tagsToFind & TRACK_NFCTYPE4A )
 {
 if( ( tagsToFind & TRACK_NFCTYPE4A ) )
 {
 return TRACK_NFCTYPE4A;
 }
 }
 }
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

What do you know, against all odds and CS universal laws, line 15 evaluates to 0. This must be a sick joke right.

So just for giggles, I add an else:

 if ((tagsToFind&TRACK_NFCTYPE2) || (tagsToFind&TRACK_NFCTYPE4A))
 {
 PCD_FieldOff();
 HAL_Delay(5);
 ISO14443A_Init( );
 if(ISO14443A_IsPresent() == RESULTOK)
 {
 if(ISO14443A_Anticollision() == RESULTOK)
 {
 if ( ( ( ISO14443A_Card.SAK & 0x60 ) == 0x00 ) && ( tagsToFind & TRACK_NFCTYPE2 ) ) /* TT2 */
 return TRACK_NFCTYPE2;
 if( ( ( ISO14443A_Card.SAK & 0x20 ) != 0x00 ) ) // && ( tagsToFind & TRACK_NFCTYPE4A )
 {
 if( ( tagsToFind & TRACK_NFCTYPE4A ) )
 {
 return TRACK_NFCTYPE4A;
 }
 else
 {
 return 1;
 ]
 }
 }
 }
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

AND THE HEAVENS HAVE OPENED, Now line 15 evaluates to

TRUE / 1

...... But wait... what just happened.... So I remove the else and what do you know.... line 15 is back to evaluating false again.....

I think my sweet little STM32L476 is possessed by demons and I need to exercise some digital god rituals or something.

4 REPLIES 4
AvaTar
Lead
Posted on March 29, 2017 at 11:24

I can't see any obvious mistake of yours - and neither explain what happens actually.

Beside perhaps some type promotion issues, it would be interesting to see the assembler code for both cases. Compiler bugs are rare, but not impossible.

BTW,

https://en.wikipedia.org/wiki/Hel_(location)

...
Richard Lowe
Senior III
Posted on March 29, 2017 at 14:50

I have a strange suspicion that it has something to do with stack space. This is running on a task of the RTOS.... Maybe?

Posted on March 29, 2017 at 15:06

I have a strange suspicion that it has something to do with stack space.

Seems not likely to me.

When I experience something that went against my expectation in such a manner, I use to do two things first:

  • turn off all optimizations
  • check the generated assembler code (and possibly step through)
Danish1
Lead II
Posted on March 30, 2017 at 14:37

I haven't looked at the

NFC CR95HF library source code, but onething springs to mind:

Presumably things like

TRACK_NFCTYPE4A are constants defined in a header.

Logic can break down horribly if the definition is an expression that is not adequately
 wrapped in bracketsbecause #defines are text substitutions e.g.
#define TEN8 | 2
int one= 1;

if (one& TEN) {// this expandsto one& 8 | 2,

// which is evaluated (one& 😎 | 2, and is always true

printf('one & TEN is true ');

}

But if instead you #define TEN (8 | 2) you get the expected result.

Hope this helps,

Danish