Access multiple I2C sensors with C2000 and simulink

26 views (last 30 days)
Hello,
I am trying to use a TI C2000 microcontroller to access data from an external adc using I2C. This ADC has multiple channels so I would like to be able to retrive data from all of them. Right now I have code setup to pull data from one channel and it works great. It can communicate with the ADC, retrieve the data, and show it on a matlab scope in real time (using external mode). I can even switch between channels with a manual switch that changes the I2C TX block's data command.
However, I am lost as to how to cycle between these channels periodically and see them both simultaneously. I've seen this example which uses function calls to sequence multiple TX blocks, but it still only uses one recieve block as it seems the data from both sensors comes at the same time. In my case I need to send a seperate command to the ADC for each channel (e.g. 255 for channel 8 and 223 for channel 4) and read the value sent by the ADC after each command. I tried doing a similar approach with function calls chaining together multiple TX and RX blocks in subsystems, but I could not get data from either channel when I tried that.
If someone has an example of something like this being done or any advice on what direction to take I would very much appreciate it. I am also curious how these blocks work (I am actually surprised that the given example works.) Does each block trigger repeatedly? If so is once per the sample rate or some other speed? Does the RX block wait for the TX block to complete before it tries to read and vice versa? Also, how does this change when you put the blocks in a subsystem? Does each one go once and then move on to the next subsytem or is there more to it?
I have attached files for both of my attempts, let me know if you see what is going wrong in the sequeced function call version. When I probe the sda line I can see some action, so it is doing something, but it's not quite there.
Thanks in advance,
Kyle

Answers (3)

said bensebaa
said bensebaa on 23 Mar 2021
I wanted to know if you resolved this problem? if yes, could you please, tell me how to get data from different chanels without adding a switch and without changing Data lengh?
Thanks.
Regards,
Said B

Venkatesh Chilapur
Venkatesh Chilapur on 13 Feb 2019
Hi,
Please can you refer the example model ' c28x_i2c_eeprom_interrupt'. From this example model one can observe the use of C28x Hardware interrupt block. This block is used on the I2C Rx interrupt. Using this approach is more practical as there is a delay between I2C Tx and I2C Rx which depends on factor like I2C bus speed, number of bits to exchange and response time of the slave. So when using the Tx and Rx in back2back we need to consider this delay using a while loop before we can read the data. Otherwise, interrupts can be setup on the Rx so that we can do other work while the Master is receving the I2C data and let's know once that is complete. A few approach one can take for reading all the ADC channels using this scheme is to send the subsequent channel request from inside the ISR and capture the received data in seprate buffers. You can also the Rx FIFO to be able to read the data from all channels at onetime.
HTH,
Regards,
Venkatesh C
  2 Comments
Kyle Goodrick
Kyle Goodrick on 13 Feb 2019
Hi Venkatesh,
Thank you so much for the responses and your help. I've looked at those examples as well, but I'm still not quite sure how to change them to get what I would like. I've tried to implement the version with the hardware interupt, but I can't get the interupt to fire. I've attached a model of what I'm trying. Essentially I have a transmit block in the base of the model that has changing inputs (Address and Data) at a 1kHz frequency which should give plenty of time for all the I2C communication. I then have a interupt block that is fed the address and is triggered on the I2CA interupt. In this block I have the recieve block and also a gpio toggle that I can use to see when the interupt fires. The output of the interupt is fed into a buffer of size two. The buffer is then split into each channels data and fed into a scope.
Unfortunately this does not work, If I probe the gpio that should be toggling when the interupt fires there is no change in the output. I am able to see activity on the I2C bus, but only 9 bits worth every 1 ms. So it looks like the transmit is going when it should but for some reason the recieve interupt is not being triggered. Do you see what I am doing wrong / is this a good way to approach it?
Thanks again for your help!
Best,
Kyle
Venkatesh Chilapur
Venkatesh Chilapur on 14 Feb 2019
Hi Kyle,
Please reach to us at:
In the mean time you can consider importing the project in CCS to debug further.
Here is a link on how to import the project in CCS from MATLAB.
You may also refer the example 'c28x_i2c_eeprom_interrupt' to study the configuration for I2C under Hardware configuration pane.
HTH,
Regards,
Venkatesh C

Sign in to comment.


Venkatesh Chilapur
Venkatesh Chilapur on 13 Feb 2019
Hi,
You may also look in to the implementation of the example model 'c28x_i2c_sensor' here we are sequencing the Tx and Rx operations such that in current execution step time we read data for the data request sent in previous step time. So we read data delayed by one sample time w.r.t the request that was sent to slave device for the data read. Please ensure the sample time duration is such that it gives enough time for the incoming data to reach Master before read.
HTH,
Regards,
Venkatesh C

Categories

Find more on Simulink Coder in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!