Lode 2 Posted June 30, 2016 Share Posted June 30, 2016 Writing a small lib for an i2c ic. I got it all working, but there's room for improvement and I can't seem to figure it out nor did I find anything similiar. The chip has combined it's SCL with an INT, which triggers (INT = 0) when measurement is complete. I have currently worked around this with a 1000 cycle delay at 8Mhz. Preferably I would like to enter LPMx in between ofcourse, could (ab)use a timer, but the interrupt seems the cleanest solution. So the question is howto capture this interrupt signal? I'm using the i2c code from TI with the exception that SDA = P1.7, SCL = P1.6 Furthermore SCL/SDA are pulled high with 1.2kOhm resistors. I've tried polling at various i2c related registers during the 1000 cycles delay (IFG2, UCB0STAT, UCB0I2CIE, IE2) for a flag, but cannot see anything happening. I was hoping UCSCLLOW could be a solution. SCL is more just an output signal I guess. I've also tried to swith to GPIO type interrupt and monitor P1IFG & BIT6 without any luck, I tried various settings maybe I missed something? Maybe I need a different approach in my hardware? Maybe there are other chips that work this way and someone else figured this out? Any help greatly appreciated Be happy to post more info or code if that helps. Quote Link to post Share on other sites
Clavier 34 Posted July 1, 2016 Share Posted July 1, 2016 P1.6 is interrupt capable. If your GPIO interrupt does not work, then your code did somewthing wrong. Quote Link to post Share on other sites
terjeio 134 Posted July 1, 2016 Share Posted July 1, 2016 UCSCLLOW should reflect SCL status if I read the documentation correctly, maybe you have a timing problem? I would think the interrupt generated by the chip in question would be a pulse of some duration to allow the I2C bus to resume normal operation without code intervention. The SCL pin is open drain so can act as an input and output at the same time, it is the reason a pullup is required for correct operation. Its default state is logical high, but can be driven low by both the master and slaves... Quote Link to post Share on other sites
chicken 630 Posted July 1, 2016 Share Posted July 1, 2016 Blind guess: the interrupt might only be available when the pin is configured as GPIO. (P1SEL) Quote Link to post Share on other sites
chicken 630 Posted July 1, 2016 Share Posted July 1, 2016 In more detail, now that I looked at the MSP430G2553 datasheet: To use I2C, the TI library will set bit 5 and 6 in P1SEL and P1SEL2 to connect these pins with the USCB0 peripheral. See table 19. Looking at the schematic on the previous page, P1SEL and P1SEL2 are connected through an OR gate to the active low enable pin of the interrupt logic. I.e. if one of the two is high, there will be no interrupts. You could manually clear bit 6 in P1SEL and P1SEL2 when you are waiting for the INT signal, and set them again before start using I2C. tripwire 1 Quote Link to post Share on other sites
fatihinanc 14 Posted July 2, 2016 Share Posted July 2, 2016 @@Lode, Are you using TLV493 ? Quote Link to post Share on other sites
Lode 2 Posted July 2, 2016 Author Share Posted July 2, 2016 @@fatihinanc Out of the millions of chips out there, you guessed correctly! Working on the same? Did you figure it out... @@chicken, i2c just uses P1.6 and P1.7 I believe? void i2c_init(unsigned char addr, unsigned char prescale){ //P1.6 SCL / P1.7 SDA P1SEL |= BIT6 | BIT7; P1SEL2 |= BIT6 | BIT7; //... } Isn't P1.5 just used for SPI? I will try your suggestion. Think the whole thing stranded when I do that. As a general note I'm trying to see the Interrupt on my little DSO202 oscilloscope, but not really getting around with that thing. Maybe the problem is that the pin is pulled high with 1.2kOhm resistor? Will return with more findings, thanks for thinking with me :-) EDIT: I got it working, due to your hints/ideas. For future reference this is quite simply it... void main(void){ //setup... for(;{ //issue i2c command... //P1.6 SCL disable P1SEL &= ~BIT6; P1SEL2 &= ~BIT6; P1IE |= BIT6; // interrupt P1IES |= BIT6; // falling edge (default) P1IFG &= ~BIT6; // flag clear __bis_SR_register(LPM4_bits); // sleep //-----------------------------------------------------------/ P1IE &= ~BIT6; // !interrupt //P1.6 SCL re-enable P1SEL |= BIT6; P1SEL2 |= BIT6; //read i2c data } } #pragma vector=PORT1_VECTOR __interrupt void ISR_P1(void){ if(P1IFG & BIT6){ P1IFG &= ~BIT6; // clear flag __bic_SR_register_on_exit(LPM4_bits); // clear LPM bits, returns to main after last LPMx } } Thanks again! Now to make sense of the data chicken 1 Quote Link to post Share on other sites
yyrkoon 250 Posted July 2, 2016 Share Posted July 2, 2016 P1.5 could be: GPIO, ADC channel 5, and I have not looked at what else. But at least gpio and adc too. Quote Link to post Share on other sites
fatihinanc 14 Posted July 3, 2016 Share Posted July 3, 2016 @@fatihinanc Out of the millions of chips out there, you guessed correctly! Working on the same? Did you figure it out... @@Lode Actually the documentation of this chip is not clear enough. Quote Link to post Share on other sites
Lode 2 Posted July 3, 2016 Author Share Posted July 3, 2016 @@fatihinanc eUSCI, what mcu are you on exactly? Could be handy for the future. And what scope is that? digital only one? Furthermore I don't see your "Calculation of the magnetic flux" as described in the User manual chapter 3, page 9? This is what I got for that: signed int TLV493D_flux12Bit(unsigned int r){ signed int c = 0; //bit value c -= (r & 0x0800) ? 0x0800 : 0; //12 ~ 2048 c += (r & 0x0400) ? 0x0400 : 0; //11 ~ 1024 c += (r & 0x0200) ? 0x0200 : 0; //10 ~ 512 c += (r & 0x0100) ? 0x0100 : 0; // 9 ~ 256 c += (r & 0x0080) ? 0x0080 : 0; // 8 ~ 128 c += (r & 0x0040) ? 0x0040 : 0; // 7 ~ 64 c += (r & 0x0020) ? 0x0020 : 0; // 6 ~ 32 c += (r & 0x0010) ? 0x0010 : 0; // 5 ~ 16 c += (r & 0x0008) ? 0x0008 : 0; // 4 ~ 8 c += (r & 0x0004) ? 0x0004 : 0; // 3 ~ 4 c += (r & 0x0002) ? 0x0002 : 0; // 2 ~ 2 c += (r & 0x0001) ? 0x0001 : 0; // 1 ~ 1 return c; } signed int TLV493D_flux8Bit(unsigned int r){ signed int c = 0; //bit value c -= (r & 0x0800) ? 0x80 : 0; //12 ~ 128 c += (r & 0x0400) ? 0x40 : 0; //11 ~ 64 c += (r & 0x0200) ? 0x20 : 0; //10 ~ 32 c += (r & 0x0100) ? 0x10 : 0; // 9 ~ 16 c += (r & 0x0080) ? 0x08 : 0; // 8 ~ 8 c += (r & 0x0040) ? 0x04 : 0; // 7 ~ 4 c += (r & 0x0020) ? 0x02 : 0; // 6 ~ 2 c += (r & 0x0010) ? 0x01 : 0; // 5 ~ 1 return c; } unsigned int x=0, y=0, z=0; //later in loop.... x = (r[0] << 4) | ((r[4] >> 4) & 0x0F); // byte 0 + high nibble 4 y = (r[1] << 4) | (r[4] & 0x0F); // byte 1 + low nibble 4 z = (r[2] << 4) | (r[5] & 0x0F); // byte 2 + low nibble 5 printf("FRM: %d \n\r", ((r[3] & 0x0C) >> 2)); // frame count printf("CH: %d \n\r", (r[3] & 0x03)); // channel 0=none or x, 1=y, 2=z, 3=temp printf("PD: %d \n\r", ((r[5] & 0x10) >> 4)); // power down printf("x: %d / %d \n\r", TLV493D_flux12Bit(x), TLV493D_flux8Bit(x)); printf("y: %d / %d \n\r", TLV493D_flux12Bit(y), TLV493D_flux8Bit(y)); printf("z: %d / %d \n\r", TLV493D_flux12Bit(z), TLV493D_flux8Bit(z)); FRM should increment 0,1,2,3, 0, etc. CH should be zero meaning measurement is finalized. fatihinanc 1 Quote Link to post Share on other sites
fatihinanc 14 Posted July 4, 2016 Share Posted July 4, 2016 ... Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.