I have following define:
#define DEVICE_ID ((uint8_t)0x3f)
and I have following function:
void LIS3DSH_Init(LIS3DSH_InitTypeDef* LIS3DSH_InitStruct)
{
// uint8_t ctrl=0x00;
uint8_t ident=0x00;
LIS3DSH_LowLevel_Init();
LIS3DSH_Read(&ident,
LIS3DSH_WHOAMI_REG_ADDR,
1);
if(DEVICE_ID==ident)
{
// LIS3DSH detected
}
else
{
// LIS3DSH not detected
failureHandler();
}
} // LIS3DSH_Init
Now, if I go step-by-step in this function, the ident variable gets value 0x3f after LIS3DSH_Read function call, which is ok. My question is, why the hell if clause jumps to failureHandler? The values of DEVICE_ID and ident are the same - both are 0x3f, if should not jump to failureHanlder(). I am working on LIS3DSH accelerator library using IAR C/C++ and STM32F4 Discovery Board. Here is a screenshot of situation:
You should type-cast the if(DEVICE_ID==ident)
to be if( (uint8_t)DEVICE_ID == (uint8_t)ident)
This has been an issue for me in the past.
And yes, declare ident as volatile, and for debugging purposes, try adding a delay before the comparison via a for-loop with __no_operation();
inside it. Note that there are 2 underscores in front of that, not 1 (intrinsic NOP instruction), and that a single NOP takes roughly ~29ns on a 168MHz board, measured via scope.
Also, since you have IAR, you might as well pop open the "assembly" view and look at what registers and/or constants are actually being compared. Open the "register" view as well...so you can see the register values themselves.