mma8452 reading the device with interrupts configured

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

mma8452 reading the device with interrupts configured

Jump to solution
1,575 Views
cnanda
Contributor I

Hi,

   I am using MMA8452 in one of the projects I am working on and am facing some problem when trying to read the device configuring the interrupts. The interrupt line stays active low/ active high on the device so my interrupt never vectors to the ISR thread.

1. I am doing the following configuration setting on the device

i2c_RegRead(CTRL_REG1,SINGLE_BYTE,&tx_para[0]);

    i2c_RegWrite(CTRL_REG1, tx_para[0]& ~(ACTIVE_MASK));

    i2c_RegWrite(CTRL_REG1, DATA_RATE_1250US);

    i2c_RegWrite(XYZ_DATA_CFG_REG, FULL_SCALE_8G);

    i2c_RegWrite(CTRL_REG3, 0);

    i2c_RegWrite(CTRL_REG4, INT_EN_DRDY);

    i2c_RegWrite(CTRL_REG5, INT_CFG_DRDY); // send on pin1

    i2c_RegRead(CTRL_REG1,SINGLE_BYTE,&tx_para[0]);

    i2c_RegWrite(CTRL_REG1, tx_para[0]& (ACTIVE_MASK));

    q.num_bytes = ARRAY_SIZE;

    if (ioctl(fd, CONFIG_DEVICE, &q) == -1)

    {

        perror("query_apps ioctl set\n");

    }

    printf("configured values :\n");

    i2c_RegRead(CTRL_REG1, 1,&tx_para[0]);

    printf("value at address:0x%2X is  0x%X\n",CTRL_REG1,tx_para[0]);

    i2c_RegRead(XYZ_DATA_CFG_REG, 1,&tx_para[0]);

    printf("value at address:0x%2X is  0x%X\n",XYZ_DATA_CFG_REG,tx_para[0]);

    i2c_RegRead(CTRL_REG3, 1,&tx_para[0]);

    printf("value at address:0x%2X is  0x%X\n",CTRL_REG3,tx_para[0]);

    i2c_RegRead(CTRL_REG4, 1,&tx_para[0]);

    printf("value at address:0x%2X is  0x%X\n",CTRL_REG4,tx_para[0]);

    i2c_RegRead(CTRL_REG5, 1,&tx_para[0]); // send on pin1

    printf("value at address:0x%2X is  0x%X\n",CTRL_REG5,tx_para[0]);

// read the xyz data registers to assert the interrupt the same is assertedlater on in the module. so I expect to fire the interrupt from this point onwards

    q.buff[0] = 0x01;

    q.num_bytes = 6; //< 10 !!

   // unsigned int i = 0 ;

    if (ioctl(fd, MMA8452_IOC_READ_NBYTES, &q) == -1)

    {

        perror("query_apps ioctl get");

    }

    else

    {

        for(i = 0 ; i < q.num_bytes ; i ++)

        {

            printf("Read Data %d\n", q.buff[i]);

        }

    }

the IOCTL module is my own cosutom module , I can read from and write to the device using the same so I am confident that the module is otherwise functional.

I am configuring the interrupts on line INTR1 and reading the data registers first time after that I am reading the status and the data registers in interrupt in the module as follows:

irq_handler_t thread_fn(void)

{

    //struct timespec t;

    time_t curr_time ;   // get time now

    struct tm * now ;

    printk(KERN_ERR "in_intr...\n");

    char status,reg;

    //struct Accel_data Axis_dat_thread0[SINGLE_DATA_SET_K],Axis_dat_thread1[SINGLE_DATA_SET_K];

    //static isr_thread,current_set = 0;

// NEED TO READ THE intr source bit as well

    reg = 0x0C;

    mma8452_i2c_rx_data(reg,1,&status);

    if( status & 0x01)

    {

         reg = MMA8452_REG_DATA;

         if ( mma8452_i2c_rx_data(reg,6,&raw_axis_data[0]) < 0 ) // change

        {

            return -EFAULT;

        }

    }

the interrupt is configured as follows

status = request_threaded_irq (irq_num,NULL,(irq_handler_t)thread_fn,IRQF_TRIGGER_FALLING|IRQF_ONESHOT,"MMA8452_intr1",NULL);

Can some one kindly guide me what could be going wrong ? I am not putting the process to sleep anywhere.

Regards,

cn.

Tags (2)
0 Kudos
1 Solution
1,009 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Chinmay,

Both interrupt pins can be configured to be push-pull or open drain and can be either active high or active low. This is done in the CTRL_REG3 (0x2C). Bit 0 (PP_OD) sets the configuration of the interrupt pins to be open drain or push-pull and bit 1 (IPOL) sets the polarity, either active high or active low. The default configuration is push-pull (PP_OD = 0) and active low (IPOL = 0).

Interrupts are enabled by setting the appropriate bit in the CTRL_REG4 register (0x2D) and are mapped to either the INT1 or INT2 pin based on the contents of the CTRL_REG5 register (0x2E). When initially configuring the interrupt pins, it is recommended that the functions and interrupt mapping be done before enabling the interrupts.

If the DRDY interrupt is asserted, the selected output pin (INT1 in your case) will keep on its active level, until all the X, Y, Z output registers (0x01 – 0x06) are read. Regarding the timing of interrupt pins, the fall time is 150ns max and the rise time 210ns max.

To calculate acceleration in units of g from the digital output, just find the difference between the measured output and the zero-g offset and then divide by the selected sensitivity. Just keep in mind that the measured acceleration data is stored as 2’s complement numbers.

Regards,

Tomas

View solution in original post

0 Kudos
3 Replies
1,009 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hello Chinmay,

First, sorry for the late response, but I have been out of the office the last couple of days.

Your code looks pretty good and you correctly stated that all X, Y, Z output registers (0x01 – 0x06) need to be read to deassert the DRDY interrupt. However, I would recommend to read these registers in your main loop to keep your ISR as short as possible. In the ISR, I would just acknowledge an IRQ by writing to a specific bit of your MCU and set another variable to indicate the arrival of new data in the main loop. I have attached my simple code for your reference.

It seems that you correctly configured one of the MCU’s GPIO pins for falling edge interrupt that has been selected by writing 0 to the IPOL bit of the CTRL_REG3 register.

Would it be possible to see a part of your schematic with the MMA8452Q connection to your MCU?


Regards,

Tomas

0 Kudos
1,009 Views
cnanda
Contributor I

Hi Tomas,

           Many thanks for your reply, I could get things working. Actually I am working on Linux on Panda Board, so had to configure the pad config registers as well.

I had another important question that I could not find on the datasheet.
  1. The INTR1 line stays after it is configured to drive the interrupt ,irrespective of the state of IPOL bit. from the slave. can I consider that as a standard specification? Or am I missing some thing here.
  Also I need the transition timings for the INTR pins like the Tr and Tfall timings. i tried to use the edge triggered mode and it was not triggering interrupts on the master for some reason I could not think of so was interested to look at the Tr and Tf timings for the slave. Level trigger works too and I will probably live with that but was just curious to find out why edge triggered configuration doesnt work for me.

Another thing, just to speed up things can have a demo code for the conversion from counts to g value, or I could ofcourse look up from AN4076 and modify it for MMA8452.


Thanks & Regards,

Chinmay

0 Kudos
1,010 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi Chinmay,

Both interrupt pins can be configured to be push-pull or open drain and can be either active high or active low. This is done in the CTRL_REG3 (0x2C). Bit 0 (PP_OD) sets the configuration of the interrupt pins to be open drain or push-pull and bit 1 (IPOL) sets the polarity, either active high or active low. The default configuration is push-pull (PP_OD = 0) and active low (IPOL = 0).

Interrupts are enabled by setting the appropriate bit in the CTRL_REG4 register (0x2D) and are mapped to either the INT1 or INT2 pin based on the contents of the CTRL_REG5 register (0x2E). When initially configuring the interrupt pins, it is recommended that the functions and interrupt mapping be done before enabling the interrupts.

If the DRDY interrupt is asserted, the selected output pin (INT1 in your case) will keep on its active level, until all the X, Y, Z output registers (0x01 – 0x06) are read. Regarding the timing of interrupt pins, the fall time is 150ns max and the rise time 210ns max.

To calculate acceleration in units of g from the digital output, just find the difference between the measured output and the zero-g offset and then divide by the selected sensitivity. Just keep in mind that the measured acceleration data is stored as 2’s complement numbers.

Regards,

Tomas

0 Kudos