Jump to content
43oh

USI I2C without interrupts


Recommended Posts

I need to perform I2C communication (with the msp430 as the master) without using interrupts. I have scanned the internet, but could not find any example on how to do it. The main challenge for me is to determine the (N)Acks. How can I see if an acknowledgement is received without using interrupts? Polling?

 

Could anyone point me in the right direction on this?

 

 

Link to post
Share on other sites

You can use the USI for either SPI or I2C, but not both simultaneously. You might mimic the behaviour you want by alternating between both modes, but that would probably make things overly complex.

Better to do one of them (SPI seems easier) in software with timing based on a hardware timer.

Link to post
Share on other sites

My "i2c explorer" code uses the usi without interrupts. Code checks for the ack/nack, returns it as a int, and let's you decide what to do with it at that point (do a logic and with 0x01, if 0 its an ack, if its 1 its a nack). You want the i2c.c and i2c.h out of it. The shell.c has examples on how I do it with bus_i2c_write. Google it and it will take you to the forum post here that has it. Ill add a link in when I get home.

Link to post
Share on other sites

Thank you for showing me this. I actually worked out a bit-baning I2C using this guide

 

I am trying to control the MSP430 using an SPI interface. So basically what I thought of doing was to have my SPI master (an Arduino) send commands telling the MSP430 what to do. In the USI interrupt vector I think I will have a case-statement responding to different 8-bit values received from the arduino. If 0x01 is sent from the Arduino, the MSP430 will perform an ADC read through I2C bit banging. That's the idea anyway.

 

So what I need to figure out now is what to enable and what to disable when switching from SPI to I2C and vice versa, so that the I2C calls will not trigger an USI interrupt and so forth.

 

Is there a command enable and disable USI interrupts?

Link to post
Share on other sites

Not that I'm aware of (as in I just don't know, but all it takes is disabling the interrupt bit. ill check), Check below but you could use the chip select pin as a two way signal pin. Have the arduino check the cs pin status. If's its low, wait, check again, before attempting spi. If it's high, pull the pin low for the interrupt.

 

The msp on the other hand, have the pin act like you normally would in slave spi mode. When the spi transmission is over, and you need to do the i2c stuff, pull the Chip Select low. Since the arduino checks the pin state before starting spi, it effectively makes it stop.

 

Or you could use a separate pin on each to do the same.

 

Here's some considerations on using i2c and spi on the same bus http://www.i2cchip.com/mix_spi_i2c.html

 

From the family guide:

14.2.3.4 SPI Interrupts
There is one interrupt vector associated with the USI module, and one interrupt flag, USIIFG, relevant for SPI operation. When USIIE and the GIE bit are set, the interrupt flag will generate an interrupt request.
USIIFG is set when USICNTx becomes zero, either by counting or by directly writing 0 to the USICNTx bits. USIIFG is cleared by writing a value > 0 to the USICNTx bits when USIIFGCC = 0, or directly by software.

14.2.4.9 I2C Interrupts
There is one interrupt vector associated with the USI module with two interrupt flags relevant for I2C operation, USIIFG and USISTTIFG. Each interrupt flag has its own interrupt enable bit, USIIE and USISTTIE. When an interrupt is enabled, and the GIE bit is set, a set interrupt flag will generate an interrupt request.
USIIFG is set when USICNTx becomes zero, either by counting or by directly writing 0 to the USICNTx bits. USIIFG is cleared by writing a value > 0 to the USICNTx bits when USIIFGCC = 0, or directly by software.
USISTTIFG is set when a START condition is detected. The USISTTIFG flag must be cleared by software.
The reception of a STOP condition is indicated with the USISTP flag but there is no interrupt function associated with the USISTP flag. USISTP is cleared by writing a value > 0 to the USICNTx bits when USIIFGCC = 0 or directly by software.

 Each of the interrupts has a separate enable bit in the USICTL1 register. Simply clearing them (set as 0) will disable the interrupt.

Link to post
Share on other sites

Very informative, CDE. Thank you!

 

After trying to initiate the above, I found that my I2C routine was not working together with my SPI program. They both work separately. So I tried running I2C without implementing SPI, but still hooked up to the Arduino. Then, the I2C-routine wold not work either. So I hooked up an oscilloscope to the MISO/SCL and MOSI/SDA lines. The clock signal worked just fine, clocking 8 cycles + acknowledge cycle. The SDA line however was looking a little strange. Where the SDA should read 10010010 there was a long pulse at about 1/3 of the expected amplitude, lasting for the duration of the 8 clock cycles. I will post some images tomorrow. When I unhooked the line from the Arduino and probed it with the scope it was working again. 

 

So the MISO line (pin11) is doing something strange to my signal. I tried setting this pin as input, output with and without pullups, but to no avail. It only changes the amplitude a little bit. Both MISO/SCL and MOSI/SDA are pulled high by 10k resistors on the PCB.

Link to post
Share on other sites

I think I have found the cause. It was not the Arduino but the voltage dividers I had used to drive the logic level from the Arduino from 5 V to 3 V. I changed the SDA line voltage divider with a 3.3 Zener diode to ground, and now I get the correct pulses, but about half the amplitude that should be expected.

 

Here is a capture:

i2chalfworking.png
Link to post
Share on other sites

Not that I'm aware of (as in I just don't know, but all it takes is disabling the interrupt bit. ill check), Check below but you could use the chip select pin as a two way signal pin. Have the arduino check the cs pin status. If's its low, wait, check again, before attempting spi. If it's high, pull the pin low for the interrupt.

 

The msp on the other hand, have the pin act like you normally would in slave spi mode. When the spi transmission is over, and you need to do the i2c stuff, pull the Chip Select low. Since the arduino checks the pin state before starting spi, it effectively makes it stop.

 

By this you mean that the chip select is controlled by the slave?

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...