Topic: Correct the offset of the FMC151  (Read 17328 times)

g.feu July 08, 2014, 11:27 AM

  • Member
  • *
  • Posts: 19

Hello,
I am currently working on the ADC / DAC conversion using fmc151 card, I noticed that there is an offset input and output of this card.
In fact, when I put an input signal of the ADC fmc, I notice that my signal is shifted by an offset of 75mV, so that the output is also shifted 75 mv, and it bothers me when I make conversion.
Is it possible to tell me how to correct this offset.
Thank you.

arnaudNL July 10, 2014, 04:44 AM (#1)

  • 4DSP Staff (EU)
  • Administrator
  • Member
  • *****
  • Posts: 7110
Dear Sir,


The DC offset is configured through the LTC2657 chip directly by i2c. The FMC151 user manual has some extra details on paragraph 5.6.


There are no guidelines on how to control the chip so please download and check the LTC2657 datasheet and you can look at fmc151_configure_dc_offset() in fmc15x.cpp. There are hardware writes to first the i2c master to define the number of bytes per cycles and then the LTC2657 is configured.


I expect that you should see definitions for registers 0x30, 0x31, 0x32 and 0x33.


Here is the function:


Code: [Select]

int32_t fmc151_configure_dc_offset(uint32_t AddrSipI2cMaster, uint32_t OffsetAdcA, uint32_t OffsetAdcB, uint32_t OffsetDacA, uint32_t OffsetDacB, uint32_t slaveaddress)
{
uint32_t rc;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configure DC offset of channels
uint32_t AddrSipFMC150Offset = AddrSipI2cMaster + slaveaddress;


// Transform it
OffsetAdcA = ((OffsetAdcA & 0xFF00) >> 8) + ((OffsetAdcA & 0x00FF) << 8);
OffsetAdcB = ((OffsetAdcB & 0xFF00) >> 8) + ((OffsetAdcB & 0x00FF) << 8);
OffsetDacA = ((OffsetDacA & 0xFF00) >> 8) + ((OffsetDacA & 0x00FF) << 8);
OffsetDacB = ((OffsetDacB & 0xFF00) >> 8) + ((OffsetDacB & 0x00FF) << 8);


rc = sipif_writesipreg(AddrSipI2cMaster+0x01, 0x01); Sleep(10); //Number of data bytes in I2C cycle is two
if (rc)
return rc;
rc = sipif_writesipreg(AddrSipFMC150Offset+0x30, OffsetAdcA); Sleep(10); //Write to and update offset ADC A
if (rc)
return rc;
rc = sipif_writesipreg(AddrSipFMC150Offset+0x31, OffsetAdcB); Sleep(10); //Write to and update offset ADC B
if (rc)
return rc;
rc = sipif_writesipreg(AddrSipFMC150Offset+0x32, OffsetDacA); Sleep(10); //Write to and update offset DAC A
if (rc)
return rc;
rc = sipif_writesipreg(AddrSipFMC150Offset+0x33, OffsetDacB); Sleep(10); //Write to and update offset DAC B
if (rc)
return rc;
rc = sipif_writesipreg(AddrSipI2cMaster+0x01, 0x00);  //Number of data bytes in I2C cycle is one (default)
if (rc)
return rc;
Sleep(10);


return FMC15x_ERR_OK;
}


I hope that helps,


Arnaud

g.feu July 10, 2014, 12:18 PM (#2)

  • Member
  • *
  • Posts: 19
 Dear Arnaud, we tried several things after your mail.
 
  • Modifying the offset values in the fmc151_configure_dc_offset function had not effect (we checked that we indeed entered the function !).
  • changing the address register values from 0x30, 0x31, 0x21, 0x33 (default values in the code) to values we guessed from what we read on page 16 in section 5.9 you mentioned, (0b001000->0x10, 0b0010011->0x13, 0b0100010->0x22, 0b110000-> 0x30 ) did not help either.

 We are also very concerned about the voltage we measure on the ADCs. They are supposed to be input channels (but when connecting them to a scope or a voltmeter, we measure a DC voltage of few 10s of mW) and having a DC signal without any signal generator connected is most disturbing for input channels !
 
 Finally, we don't understand why you mention a LTC2657 DAC whereas the card is supposed to have a TI3283 DAC. Anyway LTC doc did not help either.

Could you please propose us some other ideas of investigation.

arnaudNL July 15, 2014, 05:05 AM (#3)

  • 4DSP Staff (EU)
  • Administrator
  • Member
  • *****
  • Posts: 7110
Dear Sir,


I have forwarded that topic to our design team.


They will come back to you shortly.


Best Regards,
Arnaud

peter July 16, 2014, 10:42 AM (#4)

  • 4DSP Staff (US)
  • Administrator
  • Member
  • *****
  • Posts: 868
Dear Sir,


There is no need to be concerned, we use a standard differential opamp circuit to drive the ADC. One side of the opamp is driven by the input signal from the connector. The other side is driven by a small I2C DAC on the board. This is the DC offset correction. Not to confuse with the DAC3283, which is the DAC for the analog outputs. See block diagram Figure 1 in the User Manual.


If you have I2C access to the FMC151 you can use the DC offset correction feature. Please refer to section 5.6 in the User Manual to find the slave address of the offset correction DAC (LTC2657).


Best Regards,
Peter




g.feu July 17, 2014, 04:45 AM (#5)

  • Member
  • *
  • Posts: 19
 we just realized that we were using the wrong version of the code (i.e. the one provided for the FMC150).
 with the correct code for FMC151,  the function  fmc151_configure_dc_offset function has an effect but we were not able to get offset on the ADC below +50mV neither  a negative offset.
 
  • « Last Edit: July 17, 2014, 09:19 AM by g.feu »

peter July 17, 2014, 09:21 AM (#6)

  • 4DSP Staff (US)
  • Administrator
  • Member
  • *****
  • Posts: 868
Dear Sir,


I would need to know what kind of carrier platform you use and whether this carrier platform ties the signals GA0 and GA1 on the FMC connector high or low. With this information you can find the slave address from the look up table in the user manual.


Please do not change the addresses 0x30, 0x31, 0x32 and 0x33, because these are the internal addresses of the LTC2657; one address for each channel. In order to write to the LTC2657 you need to have the I2C slave address correct;


uint32_t AddrSipFMC150Offset = AddrSipI2cMaster + slaveaddress;


Have you tried to change the offset values to 0x0000 or 0xFFFF? Since the step size is small, you need to change the value significantly to see effect. 


Best Regards,
Peter

g.feu July 17, 2014, 10:14 AM (#7)

  • Member
  • *
  • Posts: 19
our board is a KC705.
 I think the function works OK with the setting of the FM151 code now but we did a loop scanning the offset values from 0x0000 to 0xFFFF.
 The smallest value is for 0x0000 and it corresponds to a 50 mV offset on the scope. The higher value is for 0xFFFF and corresponds to 100 mV while the mid value  0x7FFF correspond to 75 mV
  • « Last Edit: July 17, 2014, 11:38 AM by g.feu »

peter July 17, 2014, 12:09 PM (#8)

  • 4DSP Staff (US)
  • Administrator
  • Member
  • *****
  • Posts: 868
Hello,


Please note there is a byte swap required for the value written in the register:


OffsetAdcA = ((OffsetAdcA & 0xFF00) >> 8) + ((OffsetAdcA & 0x00FF) << 8);


This does not explain the behavior you see because the byte swap should not matter for values 0x0000 and 0xFFFF. Please make sure you change all the channels to make sure you are not changing one channel and measuring the other.


Best Regards,
Peter

arnaudNL July 21, 2014, 05:31 AM (#9)

  • 4DSP Staff (EU)
  • Administrator
  • Member
  • *****
  • Posts: 7110
Dear Sir,


Have you obtained the required information? Can I go ahead and close this topic?


Best Regards,
Arnaud

g.feu July 21, 2014, 05:59 AM (#10)

  • Member
  • *
  • Posts: 19
Not yet. please don't close the topic

g.feu July 21, 2014, 06:00 AM (#11)

  • Member
  • *
  • Posts: 19
We did as you suggested by modifying both channels A and B at the same time but the pb remains



Hello,


Please note there is a byte swap required for the value written in the register:


OffsetAdcA = ((OffsetAdcA & 0xFF00) >> 8) + ((OffsetAdcA & 0x00FF) << 8) ;


This does not explain the behavior you see because the byte swap should not matter for values 0x0000 and 0xFFFF. Please make sure you change all the channels to make sure you are not changing one channel and measuring the other.


Best Regards,
Peter

peter July 22, 2014, 01:20 PM (#12)

  • 4DSP Staff (US)
  • Administrator
  • Member
  • *****
  • Posts: 868
Dear Sir,


The last thing I can think of is that the I2C multiplexer on the KC705 is not configured properly. Is the following code used in your main.cpp?



      if( constellation_id == CONSTELLATION_ID_FMC151_KC705) {
         sipif_writesipreg(AddrSipI2cMaster+0x7400, 0x04); // Switch set to LPC      
         Sleep(10);   
      }


Best regards,
Peter

g.feu July 23, 2014, 11:55 AM (#13)

  • Member
  • *
  • Posts: 19
yes this code is used and the program go through it.

peter July 23, 2014, 12:26 PM (#14)

  • 4DSP Staff (US)
  • Administrator
  • Member
  • *****
  • Posts: 868
Hello,


Please provide me with the following information:


- serial number of your FMC151


- run the reference app with offset values set to 0xFFFF

         if (fmc151_configure_dc_offset(AddrSipI2cMaster, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, slaveaddress) != 0) {
  Please leave inputs unconnected and provide me with the files adc0.txt and adc1.txt. You find these in the application directory after running the application.



- run the reference app with offset values set to 0x0000
         if (fmc151_configure_dc_offset(AddrSipI2cMaster, 0x0000, 0x0000, 0x0000, 0x0000, slaveaddress) != 0) {
  Please leave inputs unconnected and provide me with the files adc0.txt and adc1.txt. You find these in the application directory after running the application.


Thank you,
Peter