• 0
Stefan0

Increasing I2C frequency of Pmod AD2 used with Microblaze

Question

I'm using an Arty A7-35 board with a Pmod AD2 module.

The design includes a a Microblaze running at 83MHz and the Pmod interface.

To build the system (block design in Vivado and Microblaze code in SDK) and  I've followed the guidelines in this tutorial and in this example.

The conversion works well but it's very slow (i.e. the maximum rate at which I can read samples in Microblaze is extremely low).

I've added a timer to the design and I noticed the function AD2_ReadConv() takes about to 0.00036 sec to return (an eternity!!!), while the AD7991 on the AD2 has a conversion time of only 1us. In particular I noticed that most of the time is spent into the XIic_Recv().

I suspect that the bottleneck is the I2C (I may be wrong). According to the PmodAD2_axi_iic_0_0.xci file the I2C frequency is 100 kHz (IIC_FREQ and IIC_FREQ_KHZ). I tried to change these value to 400 but I did not notice any speedup. I didn't find any setting in the xilinx iic library (xiic) to change the speed of the I2C.

I'm wondering if is possible (and how) to speed up the I2C frequency or if there's any other way to reduce the Pmod AD2 sample aquisition time.

Thanks

Stefano

 

 

 

Share this post


Link to post
Share on other sites

7 answers to this question

Recommended Posts

  • 0

Hi @Stefan0,

In the vivado block design could you please double click in the PmodAD2 IP Core and take screen shots of the configuration and add them to the thread.

thank you,

Jon

 

Share this post


Link to post
Share on other sites
  • 0

Hi @jpeyron,

thanks for your reply.

Attached there are the screenshots you requested. It seems that is not possible to change the I2C data rate from there.

In my previous post I explained that I unsuccessfully attempted to change the I2C rate by modifying the file PmodAD2_axi_iic_0_0.xci . This approach actually works, but I had to manually delete all Pmod-related sources in the project and adding the modules to the block once again again (probably resetting and generating the Vivado block diagram output products will do as well).

Now I'm running the I2C at 400 kHz and the function AD2_ReadConv() is almost 4 times faster (as expected). However, this is not yet sufficient for my application requirements. I'm wondering what would be the maximum I2C frequency I can use. In other threads I've read that the AD7991 can support a I2C data rate up to 3.5 MHz.

Stefano

Capture.PNG

Capture2.PNG

Share this post


Link to post
Share on other sites
  • 0

I managed to increase the I2C speed up to 1MHz and the data is correctly read from the ADC.

When entering values higher than 1MHz in PmodAD2_axi_iic_0_0.xci Vivado 2018.3 crashed during the design run updates (after it recognizes that the IP had been updated), and when restarted, the synthesis of the I2C uses the default speed of 100 kHz.

Share this post


Link to post
Share on other sites
  • 0

Hi @Stefan0,

Glad to hear that you were able to get the IIC IP working at 400 KHz and 1MHz. Thank you for sharing what you had to do to make it work. 

thank you,

Jon  

Share this post


Link to post
Share on other sites
  • 0

Hi @jpeyron,

here's another piece of the puzzle.

With the I2C at 1MHz and Microblaze running at 83 MHz it takes 19018 clock cycles or 0.000229 sec to bring in 4 samples from the AD2 (one per channel). This is done by calling 4 times the function AD2_ReadConv().

I modified that function to read 4 samples (1 per channel) in one shot (source code below) and the acquisition time it's reduced to 12970 clock cycles or 0.000156.

However this is still quite low (below 7 kHz sampling rate). Do you know if it's possible to further speed up the data transfer?

 

 

XStatus AD2_ReadConvFour(PmodAD2 *InstancePtr, u16 *dataPtr) {
   int Status;
   u8 buf[8];

   Status = XIic_Start(&InstancePtr->AD2Iic);
   if (Status != XST_SUCCESS) {
      return Status;
   }

   XIic_Recv(InstancePtr->AD2Iic.BaseAddress, InstancePtr->chipAddr, buf, 8,
         XIIC_STOP);

   dataPtr[0] = ((buf[0] << 8 | buf[1]) & AD2_DATA_MASK;
   dataPtr[1] = ((buf[2] << 8 | buf[3]) & AD2_DATA_MASK;
   dataPtr[2] = ((buf[4] << 8 | buf[5]) & AD2_DATA_MASK;
   dataPtr[3] = ((buf[6] << 8 | buf[7]) & AD2_DATA_MASK;

   Status = XIic_Stop(&InstancePtr->AD2Iic);
   if (Status != XST_SUCCESS) {
      return Status;
   }

   return XST_SUCCESS;
}

 

 

 

Edited by Stefan0

Share this post


Link to post
Share on other sites
  • 0

Hi @Stefan0,

I am not aware of any other ways to speed up the process. I believe you could improve your data rate by using HDL instead of microblaze and the IP core. Here is an forum thread for the PmodAD2 where the community member is using VHDL.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now