From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

High-Speed Digitizers

cancel
Showing results for 
Search instead for 
Did you mean: 

Operating on 5772-01 Data

Solved!
Go to solution

Hi,

 

For my application, I need to integrate the 5772-01 analog input over time, so I need to extend the 5772 input to 32-bits before integrating.  My attempts to implement the sum are obviously incorrect, and I think it's because I don't correctly understand the format of 5772 data.

 

Page 19 of the 5772 manual states the digital data resolution is 12-bit, signed, binary data, accessed using an I16 data type left-justified.

Page 32 of the ADC12D800RF datasheet shows the output code vs. analog input voltage:

Untitled.png

 

They're not lining up in my mind, I guess because the CLIP's in between?  Can someone help me understand how to extend the 5772-01 input to 32 bits and operate on it?  How about converting the I16 to a voltage?  Thanks in advance for any help.

-Steve K

 

0 Kudos
Message 1 of 11
(6,396 Views)

I assume by "extend the 5772 input to 32-bits" you mean convert the I16 into an I32. Do you want to operate on the ADC codes or the converted voltage values?

 

If you want to operate on the voltage values you can look at the getting started example for the 5772 to see how to convert the ADC codes into its corresponding voltage value. The converted voltage values are presented as a double floating precision number which should be easy to convert into an I32. This assumes you are integrating on the host. If you are integrating on the FPGA you'll probably want to operate on the ADC codes. 

 

If you want to operate on the ADC codes you'll need to shift the bit values to the right 4 times so that the I16 data is right justified. Once you've done that converting it from an I16 into an I32 should make more sense. 

 

I16_right_justify_convert_I32.png

0 Kudos
Message 2 of 11
(6,391 Views)

Thanks for your reply David.

 

I do want to integrate on the FPGA.  If the ADC code is signed, like the NI manual states, and I shifted the code 4 bits to the right, I'd expect the sign bit to get mixed up with the data.  I can take care of the sign bit if needed, if I know exactly where it is.  Is it 12-bits plus a sign bit?

 

After looking at the example you pointed me to, I'm still confused on the conversion.  The conversion takes "range (Vpp)".  The TI manual says this range is -0.5V to 2.5V, up to 7.5V.  I don't know the range of my input signal.  What value goes into the range control?

 

Thanks,

 

-Steve K

0 Kudos
Message 3 of 11
(6,382 Views)

Its just 12 bits so I think you're right, you would have to mind the signed bit. I haven't tried it though.

 

Range is stated in the user manual as 2Vpp unless you have TIS enabled without multiplexing, then it goes up to 4Vpp. 

0 Kudos
Message 4 of 11
(6,377 Views)

Hi David,

 

I'm sorry to belabor this question, but I've already tried unsuccessfully to get this working.  The link in my first post points to the ADC datasheet.  Unless I'm reading it wrong, the 12-bit ADC does not return signed data, it returns codes from 0 to 4095 across the full-scale input.  Maybe you add a sign bit in the CLIP?  Is it like this [Sddd dddd dddd dxxx]?  I.e. I should strip bit 15, right-shift four bits, convert to I32, then reapply the sign bit?  If I go by the ADC datasheet, I'd treat it like this [(!S)ddd dddd dddd xxxx] because bit 11 is actually a data bit that's like a "not sign".  I have far too fast and tight an integration window to perform this operation on the host.

 

I appreciate your help,

 

Steve K

0 Kudos
Message 5 of 11
(6,336 Views)

Steve,

 

I wouldn't expect anything with a sign to act as [Sddd dddd dddd xxxx].  The most common way to use signed data is 2's complement.  In this case, you would want to do something called sign extension.  As an example, 1001 and 1000 0001 are two entirely different numbers rather than both being negative 1.  The relationship between an integer and it's opposite is found by using a bitwise NOT on the entire value and then adding 1.  If 1 is 0001, then the NOT would be 1110, add 1 and you get 1111.  In any number of bits, 1111, 1111 1111, 1111 1111 1111 all represent -1. 

 

In this case, we have a 16 bit data type where only 12 bits have any value.  We look at it as [dddd dddd dddd xxxx].  I'd suspect any conversion you're doing is going to expect that to be an actual number.

 

Try doing a bit-shift to get the 12 MSB into the LSB positions.  Once you do that, conversion from I16 to I32 should be rather easy.

 

MSB_Bitshift.png

Is this what you implemented and you're having trouble getting it to work?  If so, I suspect the data you're working with isn't in 2s complement, but is being sign extended (negative numbers will leave leading 1s while positive will leave leading 0s).  In this case, I would expect we'd see 4 extra 1's in this situation.  That can be fixed pretty easily too.

leading0.png

With this code, we perform the same initial task.  We convert the I16 into an array of booleans.  We only want the 12 MSB so we split the array into the first 4 elements and the last 12.  (Be aware, the convert to boolean array orders the array with LSB at index 0).  After this, we concatenate an array of 4 falses. (Again, MSB is the last bit in the array and we want leading zeros).  From here, we convert it back to a number and then convert that number into the I32 data type we desire.  With this, we force any sign extension to extend the 0s regardless of what the first bit would be.

 

Do either of these methods provide you with results you'd expect?  I tested them using 16 as an input.  I would expect 16 to show up as 0000 0000 0001 0000.  After shifting the 12 MSB into the LSB positions, that would result in 0000 0000 0000 0001 or 1.  That's the result I'm seeing.  See if it plays well with your data.

0 Kudos
Message 6 of 11
(6,279 Views)

Hi Jeff,


I perceive a fundamental discrepancy between NI's FAM documentation (12-bit, signed, binary data, accessed using an I16 data type left-justified) and the ADC datasheet referenced in NI's FAM documentation (0 to 4059 from -VIN/2 to +VIN/2).  The interface to the ADC is NI's CLIP.  So, in my opinion, NI's responsible for the format of the I16 coming out of the IO node.  I'd like a definitive answer from NI before I change my FPGA VI, recompile, schedule the laser lab, schedule the laser operator, travel to the site, enable the lab interlocks and try it out.  If someone at NI could tell me definitively, "it's either THIS or THIS", then I could make two FPGA VIs and try them both.  However, I don't perceive a definitive answer.  I'm sorry if I'm missing something obvious or missed the answer somewhere.

 

Thanks for your reply,

 

Steve

0 Kudos
Message 7 of 11
(6,266 Views)

Steve,

 

I can try to gather some hardware and test those two snippets out to get exact values.  But, that will take some time.

 

Here's where we seem to be stuck.  You've perused the ADC and the FAM's documentation.  The ADC is one component of the FAM and its value is exposed to you through the CLIP.  The FAM documentation claims it is a signed 16 bit value, left justified to only worry about the 12 bits.  If this is the case, we can bitshift 4 bits to the right and convert this I16 directly to the I32.  Let's look at how that would work with the numbers 1 and -1.  In 12 bits, those values are:

 

1111 1111 1111 xxxx

0000 0000 0001 xxxx

 

In each case, we'd have 4 trailing bits that aren't important. If I were to shift these 4 bits to the right (as the first code example shows you), I would get the following results:

 

1111 1111 1111 1111

0000 0000 0000 0001

 

This is a result of what is known as "sign extension."  As the FAM documentation is written, this should solve the problem you're seeing.  This will shift the 12 bits to the right by 4 and place them where you'd want them to be.  If we read those two values, we now see a 16 bit representation of -1 and 1, respectively.  I would expect this is the answer you seek.

 

As you've focused on the ADC's manual and are relatively sure the value is unsigned, the second solution takes a look at that.  If the values are unsigned, the logical conclusion is the first half of those values are the negative range and the last half are the positive range.  In that case, anything starting with a 1 is positive (which is contrary to 2s complement).  If we sign extend (which happens as a result of the I16), we would extend the 1s and 0s in a way that's not interpreted correctly.  To prevent this, the second snippet of code adds 4 0s to the beginning of those 12 bits to ensure both of the prior values would move forward as such:

 

0000 1111 1111 1111

0000 0000 0000 0001

 

With this code, we preserve the value exactly.  This would fall more in line with what you're seeing in the ADCs documentation.

 

It's either the FAM documentation is correct and the first snippet is the way I'd shift the bits or the ADC's documentation is where we need to focus and the second snippet is the way I'd shift the bits.

 

It sounds like your questions aren't so much related to which of these are correct as they are "how do you make signed data in an integer?"  This is using the 2s complement method.  It's the most common way to perform this task.  There seems to be a fundamental misunderstanding with this topic.  I'll try to explain this in more detail.

 

While the first bit of a 2s complement number does SHOW the sign, it is not THE sign.  What I mean by that is that all values that start with 1 are negative while all that start with 0 are non-negative (all 0s is still 0).  It's not as simple as 1 is a negative and then compute the remainder of the value.  Let's look at a 4 bit representation of 1 and -1.  With 1, we know that to be 0001 in binary.  I showed you the two functions used to find the negative value using 2s complement (NOT and ADD 1) to get 1110 and then 1111.  If the value was 8 bits to start, we'd have 0000 0001, NOT would give us 1111 1110.  ADD 1 would give us 1111 1111.  This pattern follows for all values.  2 would  be 0010.  NOT would be 1101.  ADD 1 is 1110.  With 8 bits, 0000 0010.  NOT is 1111 1101.  ADD 1 is 1111 1110.  When you convert the 4 bit number to the 8 bit number, you extend the sign.  By that, I mean each new bit becomes the same value as the sign.  For negative values, we add 1s to the front.  For positive values, we add 0s to the start.  That's why the first code handles the signed piece.  The sign extension is inherent to the design.  Your first post references a "sum."  We don't want to work with a sum.  We want to work with a bitshift.  We want to ensure we extend the sign correctly. 

0 Kudos
Message 8 of 11
(6,259 Views)

I don't know if anyone else (besides NI) is chewing on this, but here's where I'm at so far.  Bit shifting right does not work. Arithmetic shifting right does not work.  Converting directly to an I32 gets me close...

Operating_On_5772_01_Data.png

-Steve

0 Kudos
Message 9 of 11
(6,201 Views)

Steve,

 

I'm not sure if you'll catch this or my email first.  I've attached the test I've ran to verify the arithmetic shift.  My test creates an array with all possible values of I12 (-2048 through 2047).  It uses the same rotate you use to move the bits 4 digits to the left.  From there, you have the same three ways to convert the left-justified I12 into the I32.  After that, the two arrays are compared element by element.  And finally, the compared results are put through an AND to determine if all the elements match.

 

All of the extra calculations you're doing are introducing error at some point.  Ultimately, the 12 bit integer can only have 4092 possible values.  It doesn't matter how these values were originally calculated by the ADC.  We know the entire range of the I12.  We're fortunate that the I12 is a small range.  As a result, it's not computationally intensive to verify every possible value.  With the attached test, you have the result of every single I12 value compared against the expected value to determine if they match.

0 Kudos
Message 10 of 11
(6,171 Views)