MAG3110 Interrupt Pin Always HIGH

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MAG3110 Interrupt Pin Always HIGH

Jump to solution
2,343 Views
abdullahkahrama
Contributor IV

Hello,

I am trying to implement MAG3110 to my project and I have already communicated with the device and read the register contents. I am also reading ZYXDR bit successfully of which I can see that it changes. The datasheet says that this bit is logically connected to the interrupt pin but the interrupt pin doesn't change.


I am using FRDM-KL25Z to interface the sensor. I have connected the interrupt pin of MAG3110 to NMI pin. Also, for test purposes I have left this pin floating but nothing changes. It is always HIGH.


Here is my code:


/* ###################################################################

**     Filename    : main.c

**     Project     : MAG3110-Breakout

**     Processor   : MKL25Z128VLK4

**     Version     : Driver 01.01

**     Compiler    : GNU C Compiler

**     Date/Time   : 2015-01-10, 19:02, # CodeGen: 0

**     Abstract    :

**         Main module.

**         This module contains user's application code.

**     Settings    :

**     Contents    :

**         No public methods

**

** ###################################################################*/

/*!

** @file main.c

** @version 01.01

** @brief

**         Main module.

**         This module contains user's application code.

*/

/*!

**  @addtogroup main_module main module documentation

**  @{

*/

/* MODULE main */

/* Including needed modules to compile this module/procedure */

#include "Cpu.h"

#include "Events.h"

#include "I2C0.h"

#include "PTA.h"

#include "SysTick.h"

/* Including shared modules, which are used for whole project */

#include "PE_Types.h"

#include "PE_Error.h"

#include "PE_Const.h"

#include "IO_Map.h"

/* User includes (#include below this line is not maintained by Processor Expert) */

#include "I2C.h"

unsigned int _1_ms_ctr = 0;

unsigned int dr_status;

int mag3310_x = 0;

int mag3310_y = 0;

int mag3310_z = 0;

void main_loop(void)

{

    static volatile unsigned char sysmod = 0;

    I2C_WriteRegister(MAG3110_addr, MAG3110_CTRL_REG2, 0x80);

    I2C_WriteRegister(MAG3110_addr, MAG3110_CTRL_REG1, 0x79);

    while (1)

    {

        sysmod = I2C_ReadRegister(MAG3110_addr, MAG3110_SYSMOD);

        if (sysmod == 2)

        {

            dr_status = I2C_ReadRegister(MAG3110_addr, MAG3110_DR_STATUS);

        }

        if (dr_status > 7)

        {

            mag3310_x = I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_X_MSB);

            mag3310_x <<= 8;

            mag3310_x += I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_X_LSB);

            mag3310_y = I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_Y_MSB);

            mag3310_y <<= 8;

            mag3310_y += I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_Y_LSB);

            mag3310_z = I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_Z_MSB);

            mag3310_z <<= 8;

            mag3310_z += I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_Z_LSB);

        }

    }

}

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

    /* Write your local variable definition here */

    /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    PE_low_level_init();

    /*** End of Processor Expert internal initialization.                    ***/

    /* Write your code here */

    /* For example: for(;;) { } */

    main_loop();

    /*** Don't write any code pass this line, or it will be deleted during code generation. ***/

  /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/

  #ifdef PEX_RTOS_START

    PEX_RTOS_START();                  /* Startup of the selected RTOS. Macro is defined by the RTOS component. */

  #endif

  /*** End of RTOS startup code.  ***/

  /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/

  for(;;){}

  /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/

} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/

/* END main */

/*!

** @}

*/

/*

** ###################################################################

**

**     This file was created by Processor Expert 10.3 [05.09]

**     for the Freescale Kinetis series of microcontrollers.

**

** ###################################################################

*/

/*

* I2C.h

*

*  Created on: Jan 10, 2015

*      Author: Abdullah

*/

#ifndef I2C_H_

#define I2C_H_

#define I2C_DisableAck()       I2C0_C1 |= I2C_C1_TXAK_MASK

#define I2C_EnableAck()        I2C0_C1 &= ~I2C_C1_TXAK_MASK

#define I2C_RepeatedStart()    I2C0_C1 |= I2C_C1_RSTA_MASK

#define I2C_EnterRxMode()      I2C0_C1 &= ~I2C_C1_TX_MASK

#define I2C_write_byte(data)   I2C0_D = data

#define I2C_Start()            I2C0_C1 |= I2C_C1_TX_MASK;\

                               I2C0_C1 |= I2C_C1_MST_MASK

#define I2C_Stop()             I2C0_C1 &= ~I2C_C1_MST_MASK;\

                               I2C0_C1 &= ~I2C_C1_TX_MASK

#define I2C_Wait()             while((I2C0_S & I2C_S_IICIF_MASK)==0) {} \

                               I2C0_S |= I2C_S_IICIF_MASK;

#define MAG3110_addr        0x0E

#define MAG3110_DR_STATUS    0x00

#define MAG3110_OUT_X_MSB    0x01

#define MAG3110_OUT_X_LSB    0x02

#define MAG3110_OUT_Y_MSB    0x03

#define MAG3110_OUT_Y_LSB    0x04

#define MAG3110_OUT_Z_MSB    0x05

#define MAG3110_OUT_Z_LSB    0x06

#define MAG3110_WHO_AM_I    0x07

#define MAG3110_SYSMOD        0x08

#define MAG3110_OFF_X_MSB    0x09

#define MAG3110_OFF_X_LSB    0x0A

#define MAG3110_OFF_Y_MSB    0x0B

#define MAG3110_OFF_Y_LSB    0x0C

#define MAG3110_OFF_Z_MSB    0x0D

#define MAG3110_OFF_Z_LSB    0x0E

#define MAG3110_DIE_TEMP    0x0F

#define MAG3110_CTRL_REG1    0x10

#define MAG3110_CTRL_REG2    0x11

void I2C_WriteRegister(unsigned char u8SlaveAddress,

        unsigned char u8RegisterAddress, /*unsigned*/char u8Data);

unsigned char I2C_ReadRegister(unsigned char u8SlaveAddress,

        unsigned char u8RegisterAddress);

void I2C_ReadMultiRegisters(unsigned char u8SlaveAddress,

        unsigned char u8RegisterAddress, unsigned char n, unsigned char *r);

void Pause(int number);

#endif /* I2C_H_ */

/*

* I2C.c

*

*  Created on: Jan 10, 2015

*      Author: Abdullah

*/

#include "Cpu.h"

#include "I2C.h"

unsigned int time_buffer;

extern unsigned int _1_ms_ctr;

void I2C_WriteRegister(unsigned char u8SlaveAddress, unsigned char u8RegisterAddress, char u8Data)

{

    I2C_Start();           

    I2C0_D = u8SlaveAddress << 1;                                    /* Send I2C device address with W/R bit = 0 */

    I2C_Wait();

    I2C0_D = u8RegisterAddress;                                        /* Send register address */

    I2C_Wait();

    I2C0_D = u8Data;                                                /* Send the data */

    I2C_Wait();

    I2C_Stop();

    Pause(500);

}

unsigned char I2C_ReadRegister(unsigned char u8SlaveAddress, unsigned char u8RegisterAddress)

{

    unsigned char result;

   

    I2C_Start();           

    I2C0_D = u8SlaveAddress << 1;                                    /* Send I2C device address with W/R bit = 0 */

    I2C_Wait();                                     

    I2C0_D = u8RegisterAddress;                                        /* Send register address */

    I2C_Wait();

    I2C_RepeatedStart();

 

    I2C0_D = (u8SlaveAddress << 1) | 0x01;                            /* Send I2C device address this time with W/R bit = 1 */

    I2C_Wait(); 

    I2C_EnterRxMode();

    I2C_DisableAck();

    result = I2C0_D;                                             

    I2C_Wait();

    I2C_Stop();

    result = I2C0_D;

    Pause(500);

    return result;

}

void I2C_ReadMultiRegisters(unsigned char u8SlaveAddress, unsigned char u8RegisterAddress, unsigned char n, unsigned char *r)

{

    char i;

 

    I2C_Start();           

    I2C0_D = u8SlaveAddress << 1;                                    /* Send I2C device address with W/R bit = 0 */

    I2C_Wait();                                     

    I2C0_D = u8RegisterAddress;                                        /* Send register address */

    I2C_Wait();

    I2C_RepeatedStart();

     

    I2C0_D = (u8SlaveAddress << 1) | 0x01;                            /* Send I2C device address this time with W/R bit = 1 */

    I2C_Wait(); 

    I2C_EnterRxMode();

    I2C_EnableAck();

 

    i = I2C0_D;

    I2C_Wait();

 

    for(i=0; i<n-2; i++)

    {

        *r = I2C0_D;

        r++;

        I2C_Wait();

    }

 

    I2C_DisableAck();

    *r = I2C0_D;

    r++;

    I2C_Wait();

    I2C_Stop();

    *r = I2C0_D;

    Pause(500);     

}

void Pause(int number)

{

    int cnt;

    for(cnt=0; cnt<number; cnt++)

    {

        asm("nop");

    };

}

/* ###################################################################

**     Filename    : Events.c

**     Project     : MAG3110-Breakout

**     Processor   : MKL25Z128VLK4

**     Component   : Events

**     Version     : Driver 01.00

**     Compiler    : GNU C Compiler

**     Date/Time   : 2015-01-10, 19:02, # CodeGen: 0

**     Abstract    :

**         This is user's event module.

**         Put your event handler code here.

**     Settings    :

**     Contents    :

**         Cpu_OnNMIINT - void Cpu_OnNMIINT(void);

**

** ###################################################################*/

/*!

** @file Events.c

** @version 01.00

** @brief

**         This is user's event module.

**         Put your event handler code here.

*/       

/*!

**  @addtogroup Events_module Events module documentation

**  @{

*/       

/* MODULE Events */

#include "Cpu.h"

#include "Events.h"

#include "I2C.h"

#ifdef __cplusplus

extern "C" {

#endif

extern unsigned int _1_ms_ctr;

/* User includes (#include below this line is not maintained by Processor Expert) */

/*

** ===================================================================

**     Event       :  Cpu_OnNMIINT (module Events)

**

**     Component   :  Cpu [MKL25Z128LK4]

*/

/*!

**     @brief

**         This event is called when the Non maskable interrupt had

**         occurred. This event is automatically enabled when the [NMI

**         interrupt] property is set to 'Enabled'.

*/

/* ===================================================================*/

void Cpu_OnNMIINT(void)

{

  static volatile unsigned char result = 0;

  result = I2C_ReadRegister(MAG3110_addr, MAG3110_OUT_X_MSB);

}

void SysTick_Interrupt(void)

{

    _1_ms_ctr++;

}

void I2C0_Interrupt(void)

{

  

}

/* END Events */

#ifdef __cplusplus

}  /* extern "C" */

#endif

/*!

** @}

*/

/*

** ###################################################################

**

**     This file was created by Processor Expert 10.3 [05.09]

**     for the Freescale Kinetis series of microcontrollers.

**

** ###################################################################

*/

Labels (1)
Tags (3)
1 Solution
1,376 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Abdullah,

After reviewing your layout and looking at your board, I guess I found where the problem is. It looks like you accidentally swapped both INT1 and VDDIO pins, having the INT1 pin (#9) connected to VDD and VDDIO pin (#8) to INT1. You will have to modify your layout or cut the traces at those pins and use wires to connect them properly.


I hope this helps.


Regards,

Tomas

View solution in original post

7 Replies
1,376 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Abdullah,

Could you please try using my simple example code I have just created to illustrate the INT1 pin behavior? I am also using the FRDM-KL25Z board in conjunction with the FRDM-FXS-MULTI-B board.

Attached you can also find a datalog file (MAG3110FC INT1_SCL_SDA pins.logicdata) with all INT1, SCL and SDA lines. I am using a Saleae Logic16 logic analyzer, so you will need to download their software to look at my datalog file.

As you can notice, the first tiny interrupt (~500ns wide) happens after POR which indicates completion of ASIC initialization (wakeup, fuse read, sensor reset etc.) and other interrupts, wider than the first one , indicate data is ready for read and get cleared after reading the data (OUT_X_MSB register).

I hope it helps.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

1,376 Views
abdullahkahrama
Contributor IV

As you can see, my code is basically yours, already. I have copied your routines and such :smileyhappy:

I have downloaded your project files and changed it to use I2C0 instead of I2C1 and still, the result is the same. I cannot see any LOW level on interrupt pin after power up. When I check it with the oscilloscope, it just jumps to 3.3V and stays like that. Then, after about 4ms, KL25Z  starts the data transfer and successfully communicates, but still, nothing changes on the interrupt pin.

According to what you say about the behavior of MAG3110, even if there is no MCU controlling it, there should be a low pulse of 500ns after POR. But I can see no change at all.

0 Kudos
1,376 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Abdullah,

It is strange, I have not heard of such a problem before. Are you using your own board or one of our boards with the MAG3110FC? If you are using your own board, could you please share here its schematic? How many parts have you tested so far?

Regards,

Tomas

1,376 Views
abdullahkahrama
Contributor IV

I am using my own homemade board and I will try to change the part now. Maybe I was not able to solder it properly. Below is my schematic.

sch.png

0 Kudos
1,376 Views
abdullahkahrama
Contributor IV

I have changed the PCB and the MAG3110 with new ones, and this time INT pin goes down to only about 3 volts. Below is a photo of the PCB and a screenshot of the oscilloscope. CH1 (red) is I2C_CLK and CH2 (yellow) is INT pin while it is floating. When I connect INT pin to KL25Z's pin that is configured as input and NMI, the peak to peak value of the squarish wave gets reduced by about 100 times, so it basically almost 3.3V with little fluctuations on top.

20150114_552450.png

Untitleda.png

IMG_20150114_181451.JPG.jpg

0 Kudos
1,377 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Abdullah,

After reviewing your layout and looking at your board, I guess I found where the problem is. It looks like you accidentally swapped both INT1 and VDDIO pins, having the INT1 pin (#9) connected to VDD and VDDIO pin (#8) to INT1. You will have to modify your layout or cut the traces at those pins and use wires to connect them properly.


I hope this helps.


Regards,

Tomas

1,376 Views
abdullahkahrama
Contributor IV

Hi Tomas,

Oh, wow, that is very shame of me :smileysad:

Thank you for your very kind help.

0 Kudos