LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

[example] small FPGA I2C Implementation for sbRIO and other RIO devices

Hi altogether,

 

after searching many hours and not getting solved the problem with my sbRIO 9631 and the I2C whitepaper suggestion:

http://www.ni.com/white-paper/3479/en/
http://www.ni.com/example/29063/en/
http://forums.ni.com/t5/LabVIEW/I2C-Start-Condition-Implementing-I2C-Communication-Protocol-in/td-p/...

 

I've looked at the code of the "I2C Communication - sbRIO" example (from the robotics module) and adapted it to my very small needs.

I have an I2C temperature sensor from Hygrosens and it listens to the adress 0x78.

Then it sends back two bytes with the temperature value.

This code will be repeated every half second.

 

I shrinked it to about a third of it's size with having only one port and a bit more hardcoded protocol. AND I changed all numbers to the smallest size (most of them to U8)

These are my compilation results with recommended settings:

Slice Registers: 4,2% (641 out of 15360)
Slice LUTs: 12,8% (1970 out of 15360)

 

You can change it to do reading and/or writing with the state machine!

But be careful with the size limits of the numbers.

 

I am not the owner of this code, I only want to share it with you, if you have the same problem.

I will provide three Versions (2010,2013 and 2015).

 

And no further support ... This is V1.0 for me 😉

Message 1 of 8
(5,711 Views)

Hi,

 

Few sensors, like IMU I'm using, require multiple address to access different sensors inside; For example,

 

The device I have has a slave address 0x68.

The accelerometer inside listens to 0x3B, 0x3C and 0x3D for three axes readings. 

 

How do you propose I send these addresses, and read them with correspoding ACK signals?


0 Kudos
Message 2 of 8
(5,677 Views)

Hi,

 

you have to dig a bit deeper in I2C, I think...

http://i2c.info/i2c-bus-specification is a good source!

It seems, like your device has 0x68 as adress and then it expects some bytes to read registers.

 

So I would say (from what I can imagine by your post) you have to write the first register, then do a read and so on...

Because the sensor only answers the value in the register you asked for...

If all the reading bytes are the same length (e.g. two bytes), you should add a register write before the readings and you could try a state machine around mine and change the register bytes all the time (0x3B, 0x3C and 0x3D).

I don't have the sensor to check, so I cannot prove it...

 

you can set and read (or see that the code is ready) the ACK signals in the code I provided...

 

Hope it helps 🙂

0 Kudos
Message 3 of 8
(5,609 Views)

Sometimes the master needs to write some data and then read from the slave device. In such cases it must first write to the slave device, change the data transfer direction and then read the device. This means sending the I2C address with the R/W bit set to write and then sending some additional data like register address. After writing is finished the master device generates repeated start condition and sends the I2C address with the R/W bit set to read. After this the data transfer direction is changed and the master device starts reading the data.

 

This is the interesting part in the link I sent you...

0 Kudos
Message 4 of 8
(5,606 Views)

I am new to I2C. So you're saying that in your main code, I should put a sequence structure in "Address/cmd" state to write register values sequentially and then at the end generate another START, jump to "READ" state and start reading?


0 Kudos
Message 5 of 8
(5,412 Views)

If I were you, I would start with the "I2C Communication - sbRIO" and if it works, I would use the code I provided, to make it smaller on the FPGA later on!

You also could try to get the I2C communication with sth. like an arduino/raspberry and see how the device answers. Then you can compare...

I did many hours of testing (also with an arduino) to get everything working.

I think you need:

write the Adress with write bit (0); write a Register (one of the three 0x numbers);repeated Start; write the Adress with read bit (1);read as many bytes as the device Ack's the end.

Good Luck! 🙂

0 Kudos
Message 6 of 8
(5,373 Views)

Tried the example you referred to with the main RT code changed to my sensor specs. 

 

as.png

My sensor works like this:

1. I2C address of 0x68 (1101000)

2. 0x6B to wake up the IC (write)

3. 0x3C, 0x3B for a sensor register. 

 

This VI runs only once to al least give some byte. But all it gives is full 255. You can see I first write to a register with RW bit set to '0' and then read from a register with RW bit '1'. 

Not getting results. Sensors works at fast-mode 400khz


0 Kudos
Message 7 of 8
(5,345 Views)

I tried this sensor with arduino and works fine. But implementing the I2C over FPGA is getting tiresome. 


0 Kudos
Message 8 of 8
(5,343 Views)