c - Interfacing issue LPC1769 and MPU6050 -



c - Interfacing issue LPC1769 and MPU6050 -

i'm trying interface lpc1769 , mpu6050 , using mcb1700.code.bundle.lpc1769.lpcxpresso libraries. , i'm using lpcxpresso ide.

as specified in mpu6050 datasheet coded read sequence, it's working first time only, if seek read sec time, returns 0 values. ( i.e., works 1 time after reset )

i tried many possible ways, no results please give me solution prepare issue.

edited.. code i've shown below. both read , burstread code working once

i2c.c

#include "lpc17xx.h" #include "type.h" #include "i2c.h" volatile uint32_t i2cmasterstate[i2c_port_num] = {i2c_idle,i2c_idle,i2c_idle}; volatile uint32_t timeout[i2c_port_num] = {0, 0, 0}; volatile uint8_t i2cmasterbuffer[i2c_port_num][bufsize]; volatile uint8_t i2cslavebuffer[i2c_port_num][bufsize]; volatile uint32_t i2ccount[i2c_port_num] = {0, 0, 0}; volatile uint32_t i2creadlength[i2c_port_num]; volatile uint32_t i2cwritelength[i2c_port_num]; volatile uint32_t rdindex0 = 0, rdindex1 = 0, rdindex2 = 0; volatile uint32_t wrindex0 = 0, wrindex1 = 0, wrindex2 = 0; /* device device, i2c communication protocol may vary, in illustration below, protocol uses repeated start read info or write device: master read: sequence is: sta,addr(w),offset,re-sta,addr(r),data...sto master write: sequence is: sta,addr(w),offset,re-sta,addr(w),data...sto thus, in state 8, address write. in state 10, address read or write depending on i2c command. */ /***************************************************************************** ** function name: i2c_irqhandler ** ** descriptions: i2c interrupt handler, deal master mode only. ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c0_irqhandler(void) { uint8_t statvalue; timeout[0] = 0; /* handler deals master read , master write */ statvalue = lpc_i2c0->stat; switch ( statvalue ) { case 0x08: /* start status issued. */ wrindex0 = 0; lpc_i2c0->dat = i2cmasterbuffer[0][wrindex0++]; lpc_i2c0->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x10: /* repeated started issued */ rdindex0 = 0; /* send sla r bit set, */ lpc_i2c0->dat = i2cmasterbuffer[0][wrindex0++]; lpc_i2c0->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x18: /* regardless, it's ack */ if ( i2cwritelength[0] == 1 ) { lpc_i2c0->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[0] = i2c_no_data; } else { lpc_i2c0->dat = i2cmasterbuffer[0][wrindex0++]; } lpc_i2c0->conclr = i2conclr_sic; break; case 0x28: /* info byte has been transmitted, regardless ack or nack */ if ( wrindex0 < i2cwritelength[0] ) { lpc_i2c0->dat = i2cmasterbuffer[0][wrindex0++]; /* should lastly 1 */ } else { if ( i2creadlength[0] != 0 ) { lpc_i2c0->conset = i2conset_sta; /* set repeated-start flag */ } else { lpc_i2c0->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[0] = i2c_ok; } } lpc_i2c0->conclr = i2conclr_sic; break; case 0x30: lpc_i2c0->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[0] = i2c_nack_on_data; lpc_i2c0->conclr = i2conclr_sic; break; case 0x40: /* master receive, sla_r has been sent */ if ( (rdindex0 + 1) < i2creadlength[0] ) { /* go state 0x50 */ lpc_i2c0->conset = i2conset_aa; /* assert ack after info received */ } else { /* go state 0x58 */ lpc_i2c0->conclr = i2conclr_aac; /* assert nack after info received */ } lpc_i2c0->conclr = i2conclr_sic; break; case 0x50: /* info byte has been received, regardless next ack or nack */ i2cslavebuffer[0][rdindex0++] = lpc_i2c0->dat; if ( (rdindex0 + 1) < i2creadlength[0] ) { lpc_i2c0->conset = i2conset_aa; /* assert ack after info received */ } else { lpc_i2c0->conclr = i2conclr_aac; /* assert nack on lastly byte */ } lpc_i2c0->conclr = i2conclr_sic; break; case 0x58: i2cslavebuffer[0][rdindex0++] = lpc_i2c0->dat; i2cmasterstate[0] = i2c_ok; lpc_i2c0->conset = i2conset_sto; /* set stop flag */ lpc_i2c0->conclr = i2conclr_sic; /* clear si flag */ break; case 0x20: /* regardless, it's nack */ case 0x48: lpc_i2c0->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[0] = i2c_nack_on_address; lpc_i2c0->conclr = i2conclr_sic; break; case 0x38: /* arbitration lost, in example, don't deal multiple master situation */ default: i2cmasterstate[0] = i2c_arbitration_lost; lpc_i2c0->conclr = i2conclr_sic; break; } return; } /***************************************************************************** ** function name: i2c_irqhandler ** ** descriptions: i2c interrupt handler, deal master mode only. ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c1_irqhandler(void) { uint8_t statvalue; timeout[1] = 0; /* handler deals master read , master write */ statvalue = lpc_i2c1->stat; switch ( statvalue ) { case 0x08: /* start status issued. */ wrindex1 = 0; lpc_i2c1->dat = i2cmasterbuffer[1][wrindex1++]; lpc_i2c1->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x10: /* repeated started issued */ rdindex1 = 0; /* send sla r bit set, */ lpc_i2c1->dat = i2cmasterbuffer[1][wrindex1++]; lpc_i2c1->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x18: /* regardless, it's ack */ if ( i2cwritelength[1] == 1 ) { lpc_i2c1->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[1] = i2c_no_data; } else { lpc_i2c1->dat = i2cmasterbuffer[1][wrindex1++]; } lpc_i2c1->conclr = i2conclr_sic; break; case 0x28: /* info byte has been transmitted, regardless ack or nack */ if ( wrindex1 < i2cwritelength[1] ) { lpc_i2c1->dat = i2cmasterbuffer[1][wrindex1++]; /* should lastly 1 */ } else { if ( i2creadlength[1] != 0 ) { lpc_i2c1->conset = i2conset_sta; /* set repeated-start flag */ } else { lpc_i2c1->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[1] = i2c_ok; } } lpc_i2c1->conclr = i2conclr_sic; break; case 0x30: lpc_i2c1->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[1] = i2c_nack_on_data; lpc_i2c1->conclr = i2conclr_sic; break; case 0x40: /* master receive, sla_r has been sent */ if ( (rdindex1 + 1) < i2creadlength[1] ) { /* go state 0x50 */ lpc_i2c1->conset = i2conset_aa; /* assert ack after info received */ } else { /* go state 0x58 */ lpc_i2c1->conclr = i2conclr_aac; /* assert nack after info received */ } lpc_i2c1->conclr = i2conclr_sic; break; case 0x50: /* info byte has been received, regardless next ack or nack */ i2cslavebuffer[1][rdindex1++] = lpc_i2c1->dat; if ( (rdindex1 + 1) < i2creadlength[1] ) { lpc_i2c1->conset = i2conset_aa; /* assert ack after info received */ } else { lpc_i2c1->conclr = i2conclr_aac; /* assert nack on lastly byte */ } lpc_i2c1->conclr = i2conclr_sic; break; case 0x58: i2cslavebuffer[1][rdindex1++] = lpc_i2c1->dat; i2cmasterstate[1] = i2c_ok; lpc_i2c1->conset = i2conset_sto; /* set stop flag */ lpc_i2c1->conclr = i2conclr_sic; /* clear si flag */ break; case 0x20: /* regardless, it's nack */ case 0x48: lpc_i2c1->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[1] = i2c_nack_on_address; lpc_i2c1->conclr = i2conclr_sic; break; case 0x38: /* arbitration lost, in example, don't deal multiple master situation */ default: i2cmasterstate[1] = i2c_arbitration_lost; lpc_i2c1->conclr = i2conclr_sic; break; } return; } /***************************************************************************** ** function name: i2c_irqhandler ** ** descriptions: i2c interrupt handler, deal master mode only. ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c2_irqhandler(void) { uint8_t statvalue; timeout[2] = 0; /* handler deals master read , master write */ statvalue = lpc_i2c2->stat; switch ( statvalue ) { case 0x08: /* start status issued. */ wrindex2 = 0; lpc_i2c2->dat = i2cmasterbuffer[2][wrindex2++]; lpc_i2c2->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x10: /* repeated started issued */ rdindex2 = 0; /* send sla r bit set, */ lpc_i2c2->dat = i2cmasterbuffer[2][wrindex2++]; lpc_i2c2->conclr = (i2conclr_sic | i2conclr_stac); break; case 0x18: /* regardless, it's ack */ if ( i2cwritelength[2] == 1 ) { lpc_i2c2->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[2] = i2c_no_data; } else { lpc_i2c2->dat = i2cmasterbuffer[2][wrindex2++]; } lpc_i2c2->conclr = i2conclr_sic; break; case 0x28: /* info byte has been transmitted, regardless ack or nack */ if ( wrindex2 < i2cwritelength[2] ) { lpc_i2c2->dat = i2cmasterbuffer[2][wrindex2++]; /* should lastly 1 */ } else { if ( i2creadlength[2] != 0 ) { lpc_i2c2->conset = i2conset_sta; /* set repeated-start flag */ } else { lpc_i2c2->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[2] = i2c_ok; } } lpc_i2c2->conclr = i2conclr_sic; break; case 0x30: lpc_i2c2->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[2] = i2c_nack_on_data; lpc_i2c2->conclr = i2conclr_sic; break; case 0x40: /* master receive, sla_r has been sent */ if ( (rdindex2 + 1) < i2creadlength[2] ) { /* go state 0x50 */ lpc_i2c2->conset = i2conset_aa; /* assert ack after info received */ } else { /* go state 0x58 */ lpc_i2c2->conclr = i2conclr_aac; /* assert nack after info received */ } lpc_i2c2->conclr = i2conclr_sic; break; case 0x50: /* info byte has been received, regardless next ack or nack */ i2cslavebuffer[2][rdindex2++] = lpc_i2c2->dat; if ( (rdindex2 + 1) < i2creadlength[2] ) { lpc_i2c2->conset = i2conset_aa; /* assert ack after info received */ } else { lpc_i2c2->conclr = i2conclr_aac; /* assert nack on lastly byte */ } lpc_i2c2->conclr = i2conclr_sic; break; case 0x58: i2cslavebuffer[2][rdindex2++] = lpc_i2c2->dat; i2cmasterstate[2] = i2c_ok; lpc_i2c2->conset = i2conset_sto; /* set stop flag */ lpc_i2c2->conclr = i2conclr_sic; /* clear si flag */ break; case 0x20: /* regardless, it's nack */ case 0x48: lpc_i2c2->conset = i2conset_sto; /* set stop flag */ i2cmasterstate[2] = i2c_nack_on_address; lpc_i2c2->conclr = i2conclr_sic; break; case 0x38: /* arbitration lost, in example, don't deal multiple master situation */ default: i2cmasterstate[2] = i2c_arbitration_lost; lpc_i2c2->conclr = i2conclr_sic; break; } return; } /***************************************************************************** ** function name: i2cstart ** ** descriptions: create i2c start condition, timeout ** value set if i2c never gets started, ** , timed out. it's fatal error. ** ** parameters: none ** returned value: true or false, homecoming false if timed out ** *****************************************************************************/ uint32_t i2cstart( uint32_t portnum ) { uint32_t retval = false; timeout[portnum] = 0; /*--- issue start status ---*/ lpc_i2c[portnum]->conset = i2conset_sta; /* set start flag */ /*--- wait until start transmitted ---*/ while( 1 ) { if ( i2cmasterstate[portnum] == i2c_started ) { retval = true; break; } if ( timeout[portnum] >= max_timeout ) { retval = false; break; } timeout[portnum]++; } return( retval ); } /***************************************************************************** ** function name: i2cstop ** ** descriptions: set i2c stop condition, if routine ** never exit, it's fatal bus error. ** ** parameters: none ** returned value: true or never homecoming ** *****************************************************************************/ uint32_t i2cstop( uint32_t portnum ) { lpc_i2c[portnum]->conset = i2conset_sto; /* set stop flag */ lpc_i2c[portnum]->conclr = i2conclr_sic; /* clear si flag */ /*--- wait stop detected ---*/ while( lpc_i2c[portnum]->conset & i2conset_sto ); homecoming true; } /***************************************************************************** ** function name: i2cinit ** ** descriptions: initialize i2c controller master ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c0init( void ) { lpc_sc->pconp |= (1 << 7); /* set pio0.27 , pio0.28 i2c0 sda , scl */ /* function 01 on both sda , scl. */ lpc_pincon->pinsel1 &= ~((0x03<<22)|(0x03<<24)); lpc_pincon->pinsel1 |= ((0x01<<22)|(0x01<<24)); /*--- clear flags ---*/ lpc_i2c0->conclr = i2conclr_aac | i2conclr_sic | i2conclr_stac | i2conclr_i2enc; /*--- reset registers ---*/ #if fast_mode_plus lpc_pincon->i2cpadcfg |= ((0x1<<0)|(0x1<<2)); lpc_i2c0->scll = i2scll_hs_scll; lpc_i2c0->sclh = i2sclh_hs_sclh; #else lpc_pincon->i2cpadcfg &= ~((0x1<<0)|(0x1<<2)); lpc_i2c0->scll = i2scll_scll; lpc_i2c0->sclh = i2sclh_sclh; #endif /* install interrupt handler */ nvic_enableirq(i2c0_irqn); lpc_i2c0->conset = i2conset_i2en; return; } /***************************************************************************** ** function name: i2c1init ** ** descriptions: initialize i2c controller master ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c1init( void ) { lpc_sc->pconp |= (1 << 19); #if 0 /* set pio0.0 , pio0.1 i2c1 sda , scl */ /* function 11 on both sda , scl. */ lpc_pincon->pinsel0 &= ~((0x3<<0)|(0x3<<2)); lpc_pincon->pinsel0 |= ((0x3<<0)|(0x3<<2)); lpc_pincon->pinmode0 &= ~((0x3<<0)|(0x3<<2)); lpc_pincon->pinmode0 |= ((0x2<<0)|(0x2<<2)); /* no pull-up no pull-down */ lpc_pincon->pinmode_od0 |= ((0x01<<0)|(0x1<<1)); /* open drain */ #endif #if 1 /* set pio0.19 , pio0.20 i2c1 sda , scl */ /* function 11 on both sda , scl. */ lpc_pincon->pinsel1 &= ~((0x3<<6)|(0x3<<8)); lpc_pincon->pinsel1 |= ((0x3<<6)|(0x3<<8)); lpc_pincon->pinmode1 &= ~((0x3<<6)|(0x3<<8)); lpc_pincon->pinmode1 |= ((0x2<<6)|(0x2<<8)); /* no pull-up no pull-down */ lpc_pincon->pinmode_od0 |= ((0x1<<19)|(0x1<<20)); #endif /*--- clear flags ---*/ lpc_i2c1->conclr = i2conclr_aac | i2conclr_sic | i2conclr_stac | i2conclr_i2enc; /*--- reset registers ---*/ lpc_i2c1->scll = i2scll_scll; lpc_i2c1->sclh = i2sclh_sclh; /* install interrupt handler */ nvic_enableirq(i2c1_irqn); lpc_i2c1->conset = i2conset_i2en; return; } /***************************************************************************** ** function name: i2c2init ** ** descriptions: initialize i2c controller master ** ** parameters: none ** returned value: none ** *****************************************************************************/ void i2c2init( void ) { lpc_sc->pconp |= (1 << 26); /* set pio0.10 , pio0.11 i2c2 sda , scl */ /* function 10 on both sda , scl. */ lpc_pincon->pinsel0 &= ~((0x03<<20)|(0x03<<22)); lpc_pincon->pinsel0 |= ((0x02<<20)|(0x02<<22)); lpc_pincon->pinmode0 &= ~((0x03<<20)|(0x03<<22)); lpc_pincon->pinmode0 |= ((0x02<<20)|(0x2<<22)); /* no pull-up no pull-down */ lpc_pincon->pinmode_od0 |= ((0x01<<10)|(0x1<<11)); /*--- clear flags ---*/ lpc_i2c2->conclr = i2conclr_aac | i2conclr_sic | i2conclr_stac | i2conclr_i2enc; /*--- reset registers ---*/ lpc_i2c2->scll = i2scll_scll; lpc_i2c2->sclh = i2sclh_sclh; /* install interrupt handler */ nvic_enableirq(i2c2_irqn); lpc_i2c2->conset = i2conset_i2en; return; } /***************************************************************************** ** function name: i2cengine ** ** descriptions: routine finish i2c transaction ** start stop. intermitten ** steps handled in interrupt handler. ** before routine called, read ** length, write length, i2c master buffer, ** , i2c command fields need filled. ** see i2cmst.c more details. ** ** parameters: i2c port number ** returned value: master state of current i2c port. ** *****************************************************************************/ uint32_t i2cengine( uint32_t portnum ) { /*--- issue start status ---*/ lpc_i2c[portnum]->conset = i2conset_sta; /* set start flag */ i2cmasterstate[portnum] = i2c_busy; while ( i2cmasterstate[portnum] == i2c_busy ) { if ( timeout[portnum] >= max_timeout ) { i2cmasterstate[portnum] = i2c_time_out; break; } timeout[portnum]++; } lpc_i2c[portnum]->conclr = i2conclr_stac; homecoming ( i2cmasterstate[portnum] ); } /****************************************************************************** ** end of file ******************************************************************************/

mpu6050 functions

void mpu6050burstread(uint8_t startregadd, uint8_t length, uint8_t *data) { // clear buffers uint32_t i; (i = 0; < bufsize; i++) { i2cmasterbuffer[i2c_port][i] = 0x00; i2cslavebuffer[i2c_port][i] = 0x00; } i2cwritelength[i2c_port] = 2; i2creadlength[i2c_port] = 0; i2cmasterbuffer[i2c_port][0] = mpu6050_address; i2cmasterbuffer[i2c_port][1] = startregadd; i2cengine(i2c_port); (i = 0; < bufsize; i++) { i2cmasterbuffer[i2c_port][i] = 0x00; i2cslavebuffer[i2c_port][i] = 0x00; } i2cwritelength[i2c_port] = 1; i2creadlength[i2c_port] = length; i2cmasterbuffer[i2c_port][0] = mpu6050_address|mpu6050_read; i2cengine(i2c_port); memcpy(data,i2cslavebuffer,length); } void mpu6050write(uint8_t regadd,uint8_t regvalue) { // clear buffers uint32_t i; (i = 0; < bufsize; i++) { i2cmasterbuffer[i2c_port][i] = 0x00; i2cslavebuffer[i2c_port][i] = 0x00; } i2cwritelength[i2c_port] = 3; i2creadlength[i2c_port] = 0; i2cmasterbuffer[i2c_port][0] = mpu6050_address; i2cmasterbuffer[i2c_port][1] = regadd; i2cmasterbuffer[i2c_port][2] = regvalue; i2cengine(i2c_port); }

finally fixed issue.

i create variable(rdindex0) 0 in isr i2c0_irqhandler(). started working.

following correction made.

void i2c0_irqhandler(void) { ............ ............ switch ( statvalue ) { case 0x08: /* start status issued. */ ........... rdindex0 = 0; // added line ............................... ............................... break;

c embedded arm gyroscope lpc

Comments

Popular posts from this blog

formatting - SAS SQL Datepart function returning odd values -

c++ - Apple Mach-O Linker Error(Duplicate Symbols For Architecture armv7) -

php - Yii 2: Unable to find a class into the extension 'yii2-admin' -