This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ADS1259 Internal 2.5V reference

Other Parts Discussed in Thread: ADS1259, OPA320, OPA365, INA333, ADS1256

Hello,

I have an application using the ADS1259 24-bit ADC.   I am trying to use the ADS1259 in application where

AINP swings from 0 to 5V, while AINN is moderately fixed to a voltage signal in the system very close to 2.5V +/- dV, where dV is a small deviation around 2.5V in the order of uV to mV range, but never deviating more than say 1mV from 2.5V in either direction (+ or -).

I want to know if I use the internal reference for this part (2.5V),  and tying  AVDD to 5V,  enabling RBIAS = 1, and EXTREF = 0,  could I measure the entire swing of AINP from 0 to 5V?

I am basically substracting (5-2.5) and (0V - 2.5), so it seems I am within the boundaries of the ADC right?

Additionally,  I would like to know that if I tie VREFP to a 5V rail, could I achieve the same effect?  I am switching away from an expensive part that took AVDD and VREF as 5V.  I would like to not use an external reference if at all possible, and take advantage of the internal reference to be able to swing AINP from 0 to 5V, and keep AINN quisi-static at around 2.5V +/-1mV.


Thank you for your response in advance.

  • Hello Guys,


    Does anyone know if what I am trying to is reasonable?  I suspect it is ok, but I want to be sure since I am going to spin my board to do so. 

    Thanks

  • Hi Roberto,

    You are correct...With a 2.5V reference, the ADS1259 supports a differential signal that is +/-2.5V (AINp - AINn).

    However, you could see output code clipping when AINp = 5 V, AINn = 2.499 V, making AINp-AINn = 2.501V. The ADC output code will clip at Vref (2.5V or 7FFFFFh).

    Another thing to consider is the output impedance of your source. If your source does not have low output impedance then you may see gain errors due to a voltage division between your source and the ADC input impedance.

    Typically, we recommend buffering the ADC input with op amps (such as the OPA320 or OPA365). Usually, the op amp output should not exceed (V+ - 500V) or (V- + 500mV). As the op amp output gets closer to the supply rail you will notice additional non-linearity in your measurement (The OPA320 and OPA365 will be linear to within 100mV of the supply rails).


    Best Regards,
    Chris

  • Chris,


    Thank you for confirming I can use it the ADC in the mode I intended.  What would happen if I apply 5V to VREFP and not use the internal reference?  would it behave the same way?

    You have an excellent point about clipping.  Luckily I will not let the measurements get to 5V absolute, I will probably get scale it so that I reach from 0.2 to 4.8V maximum. 

    Yes, the input will be buffered with an instrumentation Amplifier (INA333) driving IN+ of the ADC, and another buffer to IN- at 2.5V.  So it will be a very low impedance..

    I am not using the OPA320, but the INA333 (TI Part)  Would this part be linear to within 100mV of its rail as well?  I just want to make sure I don't goof up on this.

    Best regards,

    Roberto

  • My intention is to request 16 samples of data at a time.  I imagine that just hitting the START pin will initiate a conversion.  Is there anything particular that you know of about this ADC I should know?  Is there a mode or setting up registers that should be setup prior to conversions?  I read other ADCs in the forum require special attention, and other folks make common mistakes.  What are some common mistake(s)/Issues you have seen people experience when using the ADS1259?  I hope my transition is seamless.  I am working on a high visibility project and there is no room for mistakes or wrong assumptions.  I am trying to learn as much as possible, and I am preparing for FW development as well.

  • Hi Roberto,

    Sorry for the delay.

    If you use a 5V reference the LSB size increases. The 7FFFFFh code then represents a 5V or greater input. Your 2.5V differential input signal will be represented as 3FFFFFh, with no clipping. A few things to note when doing this:

    • You've increased the full-scale input range (FSR) by increasing Vref; however, the "absolute input voltage" range remains the same - in other words, don't apply an input signal much higher than the ADC's supply voltage - not that you would.
    • By increasing the LSB size, you are using fewer ADC codes to represent your signal. Before you were using the full +/-2.5V input range, now (if you switch to a 5V reference) you would only use half of your +/-5V input range. This means you only get HALF of the resolution you previously did. Usually, you will want to match the ADC's input range to your signal (leaving some headroom near the supplies - i.e. the 0.2V to 4.8V you're planning).

    Regarding the INA333 linear performance...

    I see a specification called "Gain Linearity" in the INA333 datasheet. The test conditions for this spec are "VS = 5.5V, (V–) + 100mV ≤ VO ≤ (V+) – 100mV". Therefore, this tells you that the linearity was tested to within 100mV of either supply rail. (Note, this is VO - so we are saying the output can reach 100mV away from the supplies and the device still behaves linearly).

    Operating the INA33 such that the output spans from 0.2V to 4.8V should have excellent linearity!


    Best Regards,
    Chris

  • Roberto,

    I decided to answer your second post in a separate post of my own, so that my reply wouldn't grow too long.

    Regarding what you should know about the ADS1259:

    • There are device register that control the data rate, filter setting, calibration coefficients, and other special functions. While you can just power up the ADS1259 and use START to begin collecting data, make sure you look through the default register settings to be aware of ADS1256 modes of operation upon power up or after you reset the device
      • In the very least it may help with debugging - i.e. if you configure the ADS1259 for a faster data rate and find /DRDY pulses to have the default period of 100ms, you would know to go read the DR bits in the CONFIG2 register to see if the device is being configured correctly, or check if somehow the device is being reset.
    • The ADS1259 has a "Continuous Read" mode (or RDATAC). This mode should be assumed to be ON whenever you reset or power up the ADS1259. Therefore, before any register read or write, first send the SDATAC command. If you never send the RDATAC command after that, SDATAC will only needed the next time you reset or power-up the device.

    • Also, in the "Continuous Read" mode, you can corrupt data if you do not retrieve it fast enough. Reading data in this mode while /DRDY is signalling new data may modify the data you are trying to read.  Make sure you read data right after a /DRDY interrupt.
      • If your SPI controller is not able to handle /DRDY interrupts (and other processes you're running) then you would want to exit this mode (by SDATAC) and use the RDATA command every time you want to read data, to read out the buffered data the does not get overwritten immediately.

    I believe those are the most common problems I see on the E2E forums. I can help answer other questions or provide troubleshooting guidance if needed.

    Best Regards,
    Chris

  • Chris,

    Thank you for the responses.  I will keep the reference at 2.5V and have the option for 5V if needed in my application.  Thank you also for the common issues you have encountered from users like me. 

    Can you clarify once more the RDATAC vs SDATAC?  My intent is to send a START pulse or  signaling to get a conversion only when I request it.  I will read it after /DRDY tells me it is ready for me to fetch the data. 

    1. STEP 1 on POWER UP - Check all registers CONFIG2 and validate its state

    2. SET UP ADC for non-continuous read mode.

    3. Request conversions when I desire.

    Is this in a nutshell the steps to follow?

    Using 2's compliment number I will use a signed Int32 variable. I will be doing math in the MCU, so to get voltage is this equation sufficient.  As I said before, AIN will be held for all practical purposes at 2.5V.  To convert from Digital Code to Floating point, I intend to use the following:  Vd = Vp  - Vn at the ADC input

    Vp - Vn = Vref*{DCODE/(2^23 - 1)} to get diff voltage I am interested in.  Do you see anything wrong with this math?

  • Hi Roberto,

    Sure...

    The "RDATAC" mode puts the ADS1259 in a state where it only expects incoming SCLKs for the purpose of clocking out data. It is convenient when you want continuously sample and convert you input signal because you don't need to send any additional commands before clocking out the data.

    However, to perform other operations - such as reading or writing to the ADC registers - you need to make sure to exit the "RDATAC" mode by sending the SDATAC command.

    It sounds like you do not need to continuously sample and convert your input signal; therefore, you may want set the PULSE bit in the CONFIG2 register to "1" so that the ADS1259 only performs a conversion when you, A) toggle the START pin, or B) send the START command.

    Therefore, your order of operations would look like:

    1. Power up
    2. Send SDATAC command
    3. Write to all the device registers you wish to change (from the default value)
    4. Read back all of the registers to confirm the settings and operation modes are correct.
    5. Send a START condition (SPI command or toggle GPIO connected to ADS1259 START pin)
      1. Note the SPI timing on pg 6 or the GPIO pulse timing on pg 23 (of the ADS1259 datasheet)
    6. Wait for /DRDY to go low
    7. Send the RDATA command followed by additional SCLK's to clock out the data (and checksum if configured).
    8. Repeat steps 5-8 or (OPTIONAL) if you don't expect to request more data soon you can power down the device, but will need to allow time to reconfigure the device registers - they don't retain their values while powered down - in which case repeat steps 1-8.

    Another thing to consider is calibration. You may only calibrate your system once and never again, or you may re-calibrate it regularly. Offset calibration is simple to perform anywhere; however, gain calibration requires that you provide a known accurate full-scale signal - this is sometimes difficult out in the "field" or where ever you operate your system in it's final application. You would probably insert the calibration routine between steps 4 & 5, and read back the registers again (to make sure your calibration coefficients look reasonable) then proceed to step 5.

    Best Regards,
    Chris

  • Dear Chris,

    I finally got the hardware and I am having issues with the ADC.  I mainly don't know how to use it yet.


    Here is what I am doing

    1. powering up, and giving it 5V to the circuit

    2. Dropping CS_N low

    3. send via SPI SDATAC  0x11

    4. Send Configuration register 0 0x40

    5. send the Default delay config1 register 0x00

    6. sending config2 register 3600 sps configuration

    7 bring CS_N high

    Then to read a sample here are my steps

    1. high Start Pin

    2. wait for  DRDY_N pin to drop low

    3. Chip select comes down after DRDY is low

    4. I send 0x12 Read data command in the SPI transfer using 32 bit clock.  I am not using check sum

    5. high chip select when I finish the transfer

    6. low start pin

    7. Whatever data I get I do this Temp & 0xFFFFFF

    To convert it to voltage

    1. store temp in ADC24Val

    2. Shift right by 23 to see if the upper most bit is a one (sign bit)

    3. if it is a one, then i NOT(ADC24Val) + 1 to convert it to positive

    4. then I typecast ADC24Val into float  => (ADC24Val / 8388608.0) * 2.50 * -1.00;

    5. I get the wrong answer every time...

    I am not sure if I am missing a step, somewhere, but when I use my DMM, I can trace my analog voltage all the way from the beginning to the end, and I have an expectation of certain voltage and it is not what I get.  What am I omitting?

    I am toggling the pin rather than sending the command via spi (i.e., START PIN toggle)

    Initially I was not sending 0x12 in the read, but I noticed on the datasheet page 31 figure 61 it needs to send a read data command 0x12.  I still can't get it to work.

    What do you think I am doing wrong?  In your previous post, you never mentioned anything about Chip select dropping down, but the timing diagrams show Chip select has to come down after DRDY_N is low.
     I believe I am doing that.


    Please help me get it going!

  • Dear Chris,


    Many months since you wrote this post.  I sent a request in a previous post, and this is a follow up on this conversation.


    1. On power up it is assumed the ADS1259 is in continuous read data mode.  I have written an INIT() function where I send the SDATAC (byte 0x11).

    Attached is the image where I capture with a logic analyzer the transactions coming from the MCU to the ADS1259 and back.  I don't get what is going on.

    In the timing diagram I am doing the following:

    0. Power up the unit.  Assumed that it is in continuous mode

    1. I invoke the init function where I send the SDATAC mode byte 0x11.  I don't know if there is a way to read this back, but I assume you can't and that it went into the chip.

    2. I send a register read command opcode1 = 0x20 = starting at register 0, opcode2 = 0x00 one register, then I expect one byte back for a total of 24 clocks (3 groups of 8 clocks) cycles.  That occurs as captured by the logic analyzer.  The data read back is zero!  I expect the default mode of the chip in that register which should be around 0x85 or where abouts depending on the ID of the part.

    3. I then write opcode 0x41 =starting at register address 0x01 = config1, and opcode = 2 =0x01 2 registers. I follow that up with 0x00 for config1, and 0x17 for Config2 register.  I write 0 delay to bits Delay[2-0], and for config2 I write 0x17 bit 4 =  pulse control mode, and 14440 Sps rate.

    4.  I attempt to read back what I just wrote, so I send 0x21, 0x01, Read opcode starting at 0x01= config1 reg, and two registers.  I clock all 32 bits and I expect the last 16 bits to be read-back data.  All I get is zeros....
     I see it on the scope and I see it on the logic analyzer. 

    This tells me one of two [or more] possibilities...  The chip is damaged, something or something is wrong with the layout of this new board.  I have looked at the layout in great detail and I see the power rails up, and I see 3.3V on VDDIO, everything looks healthy and clean.  Proper terminations are there etc..

    I have attempted to see the DRDY_N signal toggling when in continuous mode, and I don't see it toggling.  when I request a sample I see it go low and then high and back low.    Something seems to be partially working, but either I am not writing to the ADC correctly, or the ADC is damaged.  I really don't know what is going on.  It should have worked by now.

    Can you think of a sequence of events to perform so that could tell you whether or not the ADC is good or bad?  I am disturbed the DRDY_N signal with default mode won't toggle whether CS_N is low or high.  It will not do what the datasheet says.

  • Dear Chris,

    I think I made some progress since this post to now.  It turns out I was reading SPI data on the rising edge of the clock, and I should be reading it on the falling edge.  I experimented since it is not called out in the datasheet, or at least I could not find it.

    There is a bit of a small problem still, and I think this is with the PIC Micro though on the SPI side.  When i call my initialization routine after power up to send SDATAC command, and update my Delay and Sampling rate in the appropriate registers, I have to call the routine twice.  It is as if the SPI is double buffered and first time the data does not read, but there after it is fine.  I will investigate this further.


    I thought I should update you the issue was with the phase of the clock when sampling on the Rising edge.  It needs to be on the falling edge.

  • Dear Chris,

    I investigated further, and I am now convinced it is not the Microcontroller or the SPI firmware routines.  I soldered a wire right at the DOUT pin, and I can confirm data is certainly going out to the ADC, but when I query it, no data returns.  If I do this several times in a loop, the ADC finally catches ON (8 times).


    Attached is my schematic and the scope capture, confirming no data comes out, unless I hit it several times, no less than 8 times.

    It feels like there is a time constant or something not quite catching on.  I had 11uF on the reference pin, and reduced it to 1uF.  I wait for more than 1sec.


    1. SPI clocks I have tried 1,4,5,6.67,10 MHz.  I am not sure if this matters.

    2. 10MHz SPI clock speed seems to read.  On the data sheet is say 1.8, but I am not sure what that is.  1.8  x 7.3728MHz?  I am not sure what that nomenclature means.

    what could be the problem?  What is preventing the ADC to pay attention to me in the first call?

    Blue trace is DOUT right at the Chip, yellow trace is the clock pulses to trigger.

  • Hi Roberto,

    Thank you for the screenshots and schematic images -  they are very helpful! I've been looking over your posts from the weekend and will try to answer most of your questions here...

    Grounding

    The one thing I noticed that could be the crux of most of your issues is the analog and digital ground connections. You have separated them on your schematic and did not show where you reference these ground potentials to each other. For layout purposes if you want to keep these grounds mostly separate it is okay, but you need to connect AVSS and DGND at the ADS1259.

    (If you intend to use isolation in your system, then you would isolate the digital signals going back to your microcontroller. The separate AVSS and DGND grounds on the ADS1259 are there to keep the digital noise out of the sensitive analog circuitry inside the ADS1259; however, they still need to be connected together at some point - preferably right at the ADS1259.)

    SPI Communication

    Once you make sure analog and digital grounds are biased to the same potential, then SPI communication should start to work. The ADS1259 does indeed use the falling edge of SCLK to read DIN data. More specifically, it uses SPI mode 1 (a good article on SPI modes can be found here: http://www.totalphase.com/support/articles/200349236).

    Next the SCLK frequency is important - its frequency is limited by the ADC clock frequency. SCLK has a minimum period of "1.8 * tclk" (another way to say this is that the maximum SCLK frequency is fclk/1.8). Therefore, since you are using the internal 7.3728 MHz clock, your SCLK is limited to 7.3728 MHz / 1.8 = 4.096 MHz (max). Using 10 MHz for SCLK will not work, even though you still see activity on the DOUT signal.

    You SPI sequence would be the last thing to check. From your logic analyzer screenshot, your SPI command sequence looks correct!

     

    Please let me know if these suggestions correct the issue!

    Best Regards,
    Chris

  • Dear Chris,


    Thank you for replying to my posts. The digital, and Analog grounds are separated in this design for the very reason you mentioned.  The analog signals are sensitive, and I don't want to introduce digital noise into them.  Thus I have separate planes returning the current back to the source.

    The system is composed of two boards connected via mezzanine connectors.  The digital and power supplies board sits below, and the analog board connects on top (both boards are about 2.5" long).  There are really two grounds running around, power ground (PGND) in the digital/pwr board  which mates to Analog ground (CCGND) on the analog board, and digital ground all connecting at a single point at the power input jack.  There is an ESD return path, but it is not part of the ADC.  In my mind the grounds are at the same potential, and I will validate this with my DMM  by measuring the voltage observed at the grounds, by measuring the resistance from PGND to CCGND and DGND TO DGND.

    The goal is to return the Digital currents back through the DGND path,  while the analog path returns the currents via analog/pwr gnd combination.  I don't think there should be an issue (at least to me), unless the issue is in the mezzanine connectors DC contact resistance.  These are tiny connectors (x2), and I have at least 2 to 3 pins dedicated for returns, which should be sufficient to lower the contact resistances.

    The images below show the ground connection/returns, and the mezzanine connections.  I believe the grounds are correct in terms of logical connections.

    Do you think on the analog board I should just have a single ground for the entire board including the ADC?  I could do that, but I am worried about failing FCC Class B if the digital signals lose its return path ground reference.  I don't want to connect the Digital ground to the analog board to avoid noise all together.

    As for the clock, I am certainly driving it too hard.  I didn't understand the datasheet 1.8 scale factor.  I can certainly drive it between 1-4MHz to avoid issues.  Is 2.8V digital logic level healthy for the digital signals coming out of the ADC?  I am seeing 2.8V, and I expected 3.3V since VDDIO is 3.3V.

    I could try shorting the two grounds at the ADC but this will create a current loop which may be a killer for FCC.

    I have one more opportunity to layout this analog board.  What would be your recommendations?

    I have

    PGND in the Digital/Power board  joining AGND on the analog board

    DGND on the digital board joining the ADC DGNG return.

    Should I have a single ground plane on the Analog board returning to which ground?  I think PGND is less noisy than DGND due to MCU and other digital parts.

    Please advise

    Robert

    DIGITAL BOARD CONNECTION SIDE

    ANALOG BOARD CONNECTION SIDE

    CCGND = PGND RETURN

    DGND = DGND RETURN

  • Hi Roberto,

    I'd highly recommend this book for you. It is very conceptual and will help you pass FCC emissions tests.

    It discusses different grounding schemes.  You are using single-point grounding, and according to Henry Ott (pg. 126), single-point grounding is only useful for signals below about 100kHz. Above this frequency the ground impedance is very inductive and no longer behaves like a single-point ground. It will be very hard to pass EMI testing using this scheme.

    If you look online for PCB grounding, you'll find many other resources. Most will recommend using split ground planes because that is how it has always been done.

    There are right and wrong ways to use split ground planes. In my opinion, if you have a good split ground plane layout you will not need the split at all; however, if your split ground plane layout is bad, the split may help.

    There is one such discussion on our wiki page here: http://e2e.ti.com/support/data_converters/precision_data_converters/w/design_notes/1393.aspx


    I typically lay out a PCB with the analog and digital circuitry "partitioned" and sharing a single ground plane (The ADC is placed right at the partition boundary).   This scheme keeps the analog and digital ground return currents separated AND it keeps the ground impedance/inductance low. I have been successful so far at doing layouts for our high resolution and low noise ADCs using this method.

    It is essentially like laying out a split ground plane, and then removing the split right before you finish the layout. The analog and digital return currents remain separated because they will follow the path of least inductance.

    Best Regards,
    Chris

  • Chris,


    Thank you for the suggestions.  It sounds like what you are suggesting is a single ground plane in the end, which I have also done in the past.  For signal integrity purposes, the currents should always return back to the source that produced it.  I was just trying to keep digital to digital and analog to analog.  What I will do then, is create a single ground  for both boards called GND and then by virtue of having a separate board (Analog board), that board will look like an island of copper upstairs connecting the main island through the connectors.

    I think that makes sense to me only if there is a single net called GND.

    Do you concur?

  • Chris,

    Thank you for the suggestions I will take that into account. I have an opportunity to spin both boards so I will use a single ground and see how that goes for FCC.  I will buy the book as well.

    Since the analog board will be on the top of the stack it will be like a plane island, connected via mezzanine connectors. Right now the digital side doesn't cross the analog anyway. 

    I will hope this change resolves the issue I am observing with unresponsiveness. 

    Thanks

    Robert

  • HI Roberto,

    Roberto Rodriguez said:
    For signal integrity purposes, the currents should always return back to the source that produced it.

    Yes! I would just add that you want this path to be as short as possible and with the smallest loop area possible.

    Ideally, all your signals would flow on the top side of your PCB, and then would have a large (uninterrupted) ground plane that would allow the returns current to flow directly below the traces them came in on.


    ...even though you may be doing this with your current PCB, you also need to keep the ADC's analog and digital grounds at the same potential. I recommend just trying an experiment.... Short these grounds at the ADC and see if it fixes your communication (ignoring the fact that you are creating a ground loop). This would also be good to allow you to test your existing board to make sure there aren't any other issues you want to correct before your next layout!

    Roberto Rodriguez said:

    What I will do then, is create a single ground  for both boards called GND and then by virtue of having a separate board (Analog board), that board will look like an island of copper upstairs connecting the main island through the connectors.

    I think that makes sense to me only if there is a single net called GND.

    You could definitely make that work! Just be careful that you don't create too big of a common ground impedance where both analog and digital return currents can couple.

    Multiple boards are not ideal because at some point you have to connect your wide ground plane to a narrow inductive pin. If you have multiple ground pins available (one for analog and one for digital), a good layout might use these pins to keep the analog and digital return currents separated while sharing a single-ground plane.

    I'm not sure how your grounding looks on your power/digital board, but you must also consider that as you layout the analog board.

    If the grounds are split on your power/digital board, you might consider finding places where you could add "stitching" capacitors (on the power/digital board). Stitching capacitors connect between the split ground planes to reduce their impedance at higher frequencies. The good thing about stitching capacitors is that you can always remove them if you find them to be a problem.

    Best Regards,
    Chris

  • Roberto,

    If you are able, you are welcome to send me your PCB files to get my feedback before you build it.

    You can send files to pa_deltasigma_apps@ti.com instead of posting them on the E2E forums.

    Best Regards,
    Chris

  • For sure would Gerbers be ok? Or do you want the pcb pads files?

  • Hi Roberto,

    I have a Gerber file viewer... I used Pads in the past, but I don't have it anymore.

    Best Regards,
    Chris

  • Sent the files in Gerber RS-274X format last night

  • Chris,


    I am still concerned about the ADC DOUT voltage level  Is it normal for it to be one diode drop below the maximum?  VDDIO is 3.3V but I am getting less than that.

    Can you comment on this?

  • Hi Roberto,

    There are two reasons why the high logic level for DOUT would only be ~2.6V (about a diode drop below DVDD):

    1. There is a large load on DOUT.
      The ADS1259 will output 0.8*DVDD (2.64V for 3.3V logic) MINIMUM when there is a 1mA load. This is a rather large load for digital circuitry and I would not think this to be the case.

    2. Ground Reference Potential Difference.
      Where do you probe DOUT and where do you probe your ground reference?
      My guess is that if you were to probe DOUT and DGND right at the ADS1259 you would most likely see nearly DVDD for logic high. If you probe elsewhere in your circuit, you are referencing the measurement to a different (higher) ground reference voltage. I think this is more likely to be your cause.

    Best Regards,
    Chris

  • I will check this out today as well.  I probably was attached on PGND or CCGND but not on DGND.  I will attach myself to the DGND and check the level again. 

    Once again, thank you for all your help thus far.  You have been very helpful in getting me to my final goal with this ADC. 

    Best,

    Roberto

  • Hi Roberto,

    Glad to help!

    May I also ask what signal conditioning circuitry you are using prior to the ADS1259?

    Best Regards,
    Chris

  • Chris, 

    I am not adding any buffer to the digital traces. The spi goes from MCU spi pins to the ADC and I have series termination resistors only for SI.

    I don't think I needed anything else do I?

    RR

  • Hi Roberto,

    There is no problem with the digital side!

    I was asking about the analog signal conditioning. Do you have an amplifier/buffer circuit prior to the analog inputs?

    Best Regards,
    Chris

  • Chris,

    The analog has a couple instrumentation amplifiers performing difference amplification and biasing across the sensors of interest.  So yes, there is amplification using the INA333 IAMPS. There is proper filtering and signal band limiting to ensure the signal bandwidth for the sensors is met.

  • Dear Chris,

    I measured the Dout of the chip reference to DGND, and it is clean now.  I guess I either didn't have a solid connection or too long wires.  I have a little cleaning up to do.

    Here is scope shot.  The signal is not ringing indicating there may be a reasonable termination from driver to load. This makes me feel better. 

    I also reduced the clock speed to 2MHz, and things look ok generally speaking.  I will now short the grounds at the ADC and see if this gives me an indication things will be happier if a single ground is laid out.

  • Dear Chris,

    I am convinced the ADC is just putting out garbage.  My expected voltages are not coming out right and it just does not seem correct.  I am spining the board again, and I will have gerbers soon.  Can I send them to you for evaluation?

  • Hi Roberto,

    We've been talking about the SPI communication being suspect due to grounding issues, so how can you conclude that the ADC data is garbage?

    I asked you to probe DOUT near the ADS1259 so that you can observe that where you probe make a difference. If you were to instead probe DOUT where it connects to your microcontroller, I bet it would tell a different story...

    In general, probing right at the digital output SHOULD look clean (You're looking a a driven/low output impedance signal). When you move your probe down the signal trace, to the device pin configured as a digital input, you are now probing a higher impedance and you are likely to see more overshoot, ringing, and phase shift.

    Try probing all of the SPI signals near the ADS1259 and try probing all of the SPI signals near your microcontroller. You're likely to find that both devices are working correctly with the information they are given - but the information is being lost in transmission.

    Best Regards,
    Chris

  • Chris,

    When I meant garbage, I meant data that doesn't make sense.  I am getting data, and I have probed it right at the ADS1259, though i have not done it at the MCU level.  I will do that today.

    Here is what I mean.  I have an non-inverting amplfier with a transfer function

    Vo = [1 + (Rx/Rr)]*1.25V . when Rx = Rr = 165 the output is 2.5V.

    Vo1 = (Vo - 1.25V)*G1.  This is the output of the first INA333.  G1 =1

    So following the same example, Vo1 = 1.25V

    Vo2 = 2*(Vo1 - 1.25)+2.5 = 2.5V

    The ADS1259 Vin- terminal is biased at 2.5V, while the V+ can swing from 0 to 4.8V

    Thus VADC = (Vo2 - 2.5V) = 0V

    So I expect my ADC to produce a number very close to zero.  I am getting -1.66V equivalent, which is not what I expect.  I can trace the voltage down the path all the way to the ADC, and I see the voltage, but when it gets to the ADC I get -1.66V (after I convert it from signed number to voltage).

    To make sure I am not doing something silly, Here is what I do:

    ADCVAL24 =  GET_ONE_SAMPLE_ADS1259()     //High level pseudocode

    //Check for the sign bit

    if((ADCVAL24 >>23) == 1)

    Temp =  (ADCVAL24 ^ 0xFFFFFF) + 1;  // One's complement + 1

    ADCVoltage = (float32)(Temp);  //typecast Temp as float 32 bits

    ADCVoltage /= 8388608.00   (2^23 )

    ADCVoltage *= 2.50   (Internal reference)

    ADCVoltage *= (-1.00)

    If voltage is positive I divide by 8388607 * 2.500  without sign bit.

    So I believe this is the way to do the conversion from signed 32bit to a voltage.


    What I meant by "garbage" was the fact I am getting the wrong or meaningless answers as if the ADC front end is not detecting the differences in voltage.  I will do a more careful tracing of the analog voltage all the way to the ADC to see why it is not seeing the correct difference.  I will do the same in the digital signals.  Agggrrrr this is driving me insane!

    Regards,

    Robert

  • Hi Robert,

    I think you're getting into trouble here...

    Roberto Rodriguez said:

    To make sure I am not doing something silly, Here is what I do:

    ADCVAL24 =  GET_ONE_SAMPLE_ADS1259()     //High level pseudocode

    //Check for the sign bit

    if((ADCVAL24 >>23) == 1)

    Temp =  (ADCVAL24 ^ 0xFFFFFF) + 1;  // One's complement + 1

    ADCVoltage = (float32)(Temp);  //typecast Temp as float 32 bits

    ADCVoltage /= 8388608.00   (2^23 )

    ADCVoltage *= 2.50   (Internal reference)

    ADCVoltage *= (-1.00)

    If voltage is positive I divide by 8388607 * 2.500  without sign bit.

    So I believe this is the way to do the conversion from signed 32bit to a voltage.

    The ADC data is already signed. However, because it is 24-bit signed you just need to do sign-extend it to 32-bits signed (assuming ADCVAL24 is a 32-bit number).

    To sign extend it all you would need to do is something like this:

    if (ADCVAL24 & 0x00800000) {     //check sign bit
         Temp = (ADCVAL24 | 0xFF000000);   //extend sign by ORing
    }
    
    //and if you really want to be safe do this...
    else {
         Temp = (ADCVAL24 & 0x00FFFFFF);     //remove any MSB garbage
    }
    

    Best Regards,
    Chris

  • Chris,


    Thank you for pointing out that flaw.  i actually thought I needed to manipulate the 24bits of data.  I will also try this today.  I will let you know by this afternoon where I stand.

  • Ok,

    So I would still do : ADC_SIGNED_32BITS/(2^23) * 2.5V right?

  • Hi Robert,

    Yes, you can do that, but to be exact use this equation:

    [ ADC_SIGNED_32BITS / ( 2^24 - 1 ) ] * 5

    With a 2.5V reference, your LSB size is:

    full-scale range / # codes = +/- 2.5V / (2^24 -1 ) = 5 / 2^24 -1

    OR you can divide top and bottom by 2 to get:

    LSB size = 2.5 / [ (2^23) - (1/2) ]     .....yes our datasheet is slightly off, I'm trying to fix it!

    The "-1" factor comes from the fact that code zero represents +/- 1 LSB on the ADC's transfer function (to avoid counting this code twice, you subtract one). However, it is a negligible error if you leave "-1" out.

    Best Regards,
    Chris

  • Chris,

    Two things:

    1. So do you want me to change my current function (see below)

    2. I will be sending you preliminary gerbers for the modified Analog board.

    if(ADC24Val & 0x800000)
    
    {
    
       Temp = (ADC24Val | 0xFF000000);
    
       ADC_Voltage = ((float32)(Temp)) /3355443;   //3355443 = (2^24-1) /5.0
    
    }
    
    else
    
    {
    
      Temp = (ADC24Val & 0x00FFFFFF);
    
      ADC_Voltage = ((float32)(Temp)) /3355443;   //3355443 = (2^24-1) /5.0
    
    }

    Here is the function as I have it.

    float32 HAL_GET_ADCVOLTAGE(unsigned char NSamplesAve)
    {
        signed int32 ADC24Val = 0, Temp = 0;
        float32 ADC_Voltage = 0.0;
    float32 D = 3355443.20; //Voltage = ADC_CODE/(2^23/Vref) = ADC_CODE/(2^23) * Vref. //D = 2^23/2.50V = 3355443.20 Bits/Volt if(NSamplesAve == 0) { NSamplesAve = 16; } //ADC24Val = ADS1259_ReadAveSample(NSamplesAve); //Collect the ADC Sample ADC24Val = ADS1259_ReadOneSample(); //Collect the ADC Sample //sign extend to 32 bits if(ADC24Val & 0x800000) { Temp = (ADC24Val | 0xFF000000); //Extend the sign bit ADC_Voltage = (float32)(Temp); //Typecast to float32 ADC_Voltage /= D; //Divide by D. } else { Temp = (ADC24Val & 0x00FFFFFF); ADC_Voltage = (float32)(ADC24Val); ADC_Voltage /= D; } return(ADC_Voltage); }

  • Hi Robert,

    1. Your function looks good to me.
    2. I'd be glad to look over your revised Gerber files!

    BR,
    Chris

  • Chris,


    Would having a 10uF at the Bypass pin be a problem?  Page 21 says: " A 1uF capacitor must be connected from the LDO output to DGND."  I added 10uF in order bypass better.

    Also on the VREFP/VREFN I have also 10uF||1uF X5R capacitors.  I would think the larger capacitance affects the start-up time, and the dielectric in the cap will have an effect on the stability of the reference.  I believe X5R is stable enough.


    RR

    PS: I sent the artwork

  • Hello Chris,

    Have you had a chance to review the artwork? I  want to get your blessing on it before I commit it.

    Rob

  • Hi Robert,

    I'm looking at it today and will have a reply to you this afternoon.

    BR,
    Chris

  • Hi Robert,

    I want to make sure I reply to your earlier questions...

    Roberto Rodriguez said:

    Would having a 10uF at the Bypass pin be a problem?  Page 21 says: " A 1uF capacitor must be connected from the LDO output to DGND."  I added 10uF in order bypass better.

    It's not a problem to put a 10uF capacitor on the BYPASS pin.

    (Unfortunately, the datasheet  is not completely consistent on this matter...pg 12 says "...1uF or larger...").

    I discussed this with a characterization engineer and found out that there is not really a difference in performance between 1uF and 10uF.

    Roberto Rodriguez said:
    Also on the VREFP/VREFN I have also 10uF||1uF X5R capacitors.  I would think the larger capacitance affects the start-up time, and the dielectric in the cap will have an effect on the stability of the reference.  I believe X5R is stable enough.

    You're correct about start-up time dependence on the VREF capacitance!

    See figure 29 in the data sheet for a graph...with a 1uF cap it took about 0.5 seconds to settle within 0.002% of the final value. It would be better to wait 1-2 seconds for the reference to settle. Using a 10uF cap (10x) would have a similar (10x) effect on the reference settling time.

    C0G is the most stable dielectric (X7R is the next best.) Try to use C0G if you can! If you cannot, try to use an X7R with a larger breakdown voltage. These dielectrics are not as "high-k"; and therefore, they require a larger package to achieve the same capacitance - these dielectrics are not available in the larger capacitor sizes due to this reason.

    I highly recommend these articles written by my colleague, John Caldwell:

    Best Regards,
    Chris

  • Dear Chris,

    I got the boards yesterday, and the first thing I did was to measure the ADC electrical noise with both inputs grounded.  According to my calculations (assuming I doing it correctly), it is yielding as low as 19.34 bits raw data, and if I apply a moving average to the data, the ENOB improves from 19 up to 24 bits for 8 and 16 sample window respectively.

    The counts I am getting is between 207 and 208 counts.  I follow the datasheet page 27 "CALIBRATION" steps to see if I could remove the offset to make the 207, 208 counts 0.

    I follow this sequence, and after several attempts I am seeing some differences. I was first initializing the ADC then doing a calibration, nothing was working, then I switched the order, same story.  I removed the initialize out of the function, and I just call calibration, then I start measurements, and I see it now doing something, but it is unstable.

    The settings I have selected in INIT function are: SINC2 filter enabled, 400sps, pulse control.  I tell it when to get a reading by toggling the START pin.

    In calibration mode do this:

    1. Chip select low

    2. Send to Register @ 02h CONFIG2 bit 4 = 0 PULSE = 0 = GATE CONTROL, Data rate 400sps

    3. Send the RDATAC command (0x10)

    4. Raise the START Pin high

    5. Send the OFSCAL Command 0x18 first and wait for DRDY_N to go low

    6. Send the GANCAL Command 0x19 and wait for DRDY_N to go low

    7. Bring down START PIN. Presumably the calibration should be golden up to this point.

    8. At this point it should be calibrated, and I don't want to operate in RDATAC mode.  So I send SDATAC command

    9. I re-write Registers CONFIG1, CONFIG2 in case something changed @ 0x01,0x02

    10. High Chip select

    Please advise if the calibration procedure I am running is flawed, or if my expectations of this calibration are incorrect.  The datasheet doesn't explicitly explain how to accomplish this, but this is my interpretation of those steps.

    Here is what the data looks like if I command calibration

    Regards,

    Robert

    void ADS1259_CalibrateADC(void)
    {
        unsigned char OpCode1 = 0, OpCode2 = 0, RegData1 = 0, RegData2;
         unsigned int32 ADS1259_DATAREG = 0;
        
        fprintf(MCU_USB,"Sending SDATAC Command\r\n");
        //Step0 - Send the Stop Data Continuous Command
        
        output_low(ADS1259_CS_N_PIN);                               //Drop CS_N
        spi_xfer(ADS1259,ADS1259_SDATAC,8);                         //Send Stop Data Control Command SDATAC     (sends 0x11)
        
        fprintf(MCU_USB,"Configure ADC for Gate Control\r\n");
        //Step1 - Set the Gate Control Mode (PULSE bit = 0)
        OpCode1 = (ADS1259_WREG | ADDR_CONFIG2);                    //Create Write Opcode 0x42 to write starting at address 0
        OpCode2 = 0x00;                                             //Write one register
        RegData1 = (CONFIG2_EXTCLK | CONFIG2_SYNCOUT | (CONFIG2_PULSE & 0x00) | CONFIG2_DR4); //Write CONFIG2_PULSE = 0x00 =  GATE CONTROL, the rest of them same.
        ADS1259_DATAREG = make32(OpCode1,Opcode2,RegData1);         //Compose the Opcode and Data command bytes: 00 42 00 04 only sends 42 00 04
        spi_xfer(ADS1259,ADS1259_DATAREG,24);                       //Write the Data to the ADS1259 (sends 0x42 00 04) 24 bits
        
        fprintf(MCU_USB,"Sending Continuous Acquisition Command\r\n");
        //Send the Receive Continuous Data
        spi_xfer(ADS1259,ADS1259_RDATAC,8);                         //Send Read Data Continous Command RDATAC     (sends 0x10)
        fprintf(MCU_USB,"START acquiring Data\r\n");
       
       //Step2 -- Start the ADS1259 Conversions
        output_high(ADS1259_START_PIN);                             //START Conversion command
        
        //Step4 -- Send OFSCAL Offset calibration Command 0x18
        fprintf(MCU_USB,"Sending OFSCAL & GANCAL Command\r\n");
        spi_xfer(ADS1259,ADS1259_OFSCAL,8);                         //Send the OFSCAL command 0x18
         while(input_state(ADS1259_DRDY_N_PIN))
        {
            //wait for DRDY_N to go low
        }
        
        spi_xfer(ADS1259,ADS1259_GANCAL,8);                        //Send the GANCAL command 0x19
        while(input_state(ADS1259_DRDY_N_PIN))
        {
            //wait for DRDY_N to go low
        }
        
    	spi_xfer(ADS1259,ADS1259_SDATAC,8);                         //Send Stop Data Control Command SDATAC     (sends 0x11)
        
        //Configure Register CONFIG1 & CONFIG2 @ Address 0x01
        OpCode1 = (ADS1259_WREG | ADDR_CONFIG1);                        //Write OpCode Stating at Address 0x01 (0x41)
        Opcode2 = 0x01;                                                 //Number of Registers to write (2)
        //NO Out-of-Range Flag, No Checksum, SINC1 Filter, Internal Reference, and 555.55usec Delay time
        RegData1 = (CONFIG1_FLAG| CONFIG1_CHKSUM | CONFIG1_SINC2 | CONFIG1_EXTREF | CONFIG1_DLY4);      //Create Data to Config1 -- See header file for defaults.
        //Internal Clock, Syncout Disabled, Pulse Control,and Data Rate 400 SPS.
        RegData2 = (CONFIG2_EXTCLK | CONFIG2_SYNCOUT | CONFIG2_PULSE | CONFIG2_DR4);                    //Create Data to Config2  -- See header file for defaults
        ADS1259_DATAREG = make32(OpCode1,Opcode2,RegData1,RegData2);    //Compose the Opcode and Data command 41 01 114 14
        spi_xfer(ADS1259,ADS1259_DATAREG,32);                           //Write the Data to the ADS1259 (sends 41 01 14 14)
      
        output_low(ADS1259_START_PIN);                              //STOP Conversion command terminated
        output_high(ADS1259_CS_N_PIN);                              //Raise CS_N
        //Calibration Done
        fprintf(MCU_USB,"Calibration Completed\r\n");
    }


    Attached is some data

  • Chris,

    I continue trying to figure out the issue, and I inserted a delay between conversions.  I am still a bit confused on the calibration because after I calibrate I want to stay in control, meaning, I want to tell the ADC when to do a conversion by me toggling the START pin.  I don't want it to be running continuously as I don't know how to use that mode and sink it to the timing I have in my loop.  If I knew how it works (RDATAC that is), I may be able to use it, but I don't know how to use this mode yet as I don't know what it would mean to my code just yet.  I want to explore it.

    After inserting a delay between ADC conversions 250msec, weird Co-tangent plots went away.  I am sure if I am requesting too fast.  I have it at 400sps, and delay 100 = 512clck cycles or 69.44usec).  I am not sure also how to use this delay.  I do have an analog mux that will be switching between 16 different sensors and I delay 10msec there to wait for settling.  So maybe this setting is not so useful since I wait longer.

    If you can set me straight how to use the Calibration and Initialization.

    In initialization I set it for SINC2 filter, and PULSE control, and SDATAC.

    In Calibration, I set it to gate control and RDATAC.  I don't put it back in SDATAC mode, so I wonder if i am requesting a sample by toggling the START and the ADC is running free.

    Can you tell me please how to set this up properly.  My goal is:

    1. Initialize it so that I have control on the conversion.

    2. be able to calibrate out the offset  in the measurements prior to sending the data to the outside world

    3. Run a moving average of 8 or 16 samples.  I got sample code running, and I have proved it on excel. But I am also having issues because I am getting co-tangent plots.The hardware is basically providing a steady 2.5 volts at the +IN, and 2.5V+ at the IN-.  The answer I expect is not zero due to offsets on the instrumentation amplifiers, and the current source etc... so it gets close to 2.5V but not zero.  This is the offset I wish to calibrate out!

    I also tried injecting values into the Offset register, but that was a disaster.  I could not zero it out, and get werid numbers.

    I am sure this just pilot cockpit errors flying the machine.  Once you point me to the correct runway, I may be able to take off, and code it correctly.  For now, I am just able to turn the engine, but I can't make it fly yet.


    Regards,

    RR

  • Hi Robert,

    Good to hear from you again!

    I assume since you're working on the calibration routine that you SPI communication is working well. When you write to the ADS1259 registers, do you read them back to make sure the settings are correct?


    Regarding the calibration routine, your sequence is correct for the most part. The one thing that looks wrong is that you seem to be using the same input signal for both offset and gain calibration.

    • For offset calibration, you want to input a 0V-differential signal
      • You did this by connecting AINP = AINN = +2.5V
    • For gain calibration, you need to connect a positive full-scale input, i.e. "+Vref" between AINP and AINN.
      • By inputting 0V, the ADC takes the ratio: "+FS / ~0V", and thinks there is a huge gain error!

    You can read back the OFC and FSC register to see what correction vales the ADC is using. Often times software will place limits on these values as a kind of sanity check, in case the calibration fails.


    I'll put together an Excel calculator to help you understand the offset and gain calibration factors...

    Best Regards,
    Chris

  • Chris,

    Thank you for your explanation.


    Yes, I am not having SPI issues now, and the digital data is clean now with the changes.  I am writing the registers, but not reading it back  to validate.  I will do that to validate.

    Regarding the calibration, the hardware connects the Negative input AINN = 2.5V (fixed), while AINP can swing up 0.1V to 4.9V. 

    To understand this a bit better, and how it pertains to the my hardware.  I can manipulate the hardware analog multiplexer to produce a 2.5V on the AINP, while AINN is always kept at +2.5V.  I am not sure how the gain calibration would work since I can only manipulate AINP's swing from 0.1 to 4.9V.  To me full scale is if AINN moves to -2.5 or 0V and AINP goes to 4.9V.  It sounds like I can't do gain calibration in the field.  Is this correct?

    OFFSET CAL: place both inputs at about the same voltage (check!)

    AINN = AINP = 2.5V  (I can do that!)

    GAIN CAL - Force AINP to swing as high as possible.  AINN has a fixed 2.5V on the pin, so I can't get 0V. (FAIL)

    Please advise.

    Thank you for the spreadsheet.  I look forward to it.

  • Hi Robert,

    Use this Excel calculator to help you preform code conversions and to clarify the significance of the OFC an FSC programmed values:

    8463.ADS1259 Calculator.xlsx

    I recommend reading back the OFC[3:0] and FSC[3:0] registers (6 register total) and plug the values into Excel to make sure they are reasonable.

    Two quick important notes:

    1. Averaging the noise will give you an improvement of "sqrt(# averages)", and for every 2x reduction in noise, ENOB will improve by 1 bit.
    2. Gain calibration is only as good as the input source you use to supply the positive full-scale voltage. Be sure that you use a precision voltage source.
      1. i.e. If the supply is +/-1% accurate, you'll have a +/-1% gain error.
      2. If you don't have a precision full-scale input voltage to the ADS1259 on your board, then skip the gain calibration. The ADS1259 has a low gain error as is (+/-0.05%) and this error has less impact on small input signals.

    Best Regards,
    Chris

  • Hi Robert,

    You can still do a gain calibration, but you will need to do some additional data manipulation in your software...

    Since gain calibration is simply multiplying the ADC's result by "1 / gain error", to correct for scaling errors in your system, you could just as easily do this in your code! The ADS1259 requires a +2.5V input signal in order to do this scaling for you - but if you can provide a known input voltage, then you can scale the result however you want.

    I recommend providing a stable input signal close to positive full scale... Trying to correct for gain error any applying a 10mV signal (with +/-1mV accuracy) will have a much bigger gain error than a 2.4V signal (with +/-1mV accuracy).

    Therefore, use AINP = 4.9V and AINN = 2.5V (as long as you trust the input signal stability at those levels).

    Perform a several conversions (8-16) and average the result.

    Say the result is 2.395V. Then the gain error is 2.395V / 2.4V = 0.997916...

    You can divide all results by this number in your code (might be slow) or set FSC[3:0] to (0x400000 / 0.997916 = 4,194,304 (dec) / 0.997916 = 4,203,060 (dec) = 0x402234 - Then the ADC will do this scaling for you)

    Remember to ALWAYS perform the offset calibration first, so that you get a good gain calibration result!


    Best Regards,
    Chris

  • Based on this latest comment, I am not sure it is a good idea to do Gain calibrations and here is why.  The ADC input will be measuring a sensor who tends to drift around its resistance.  The voltage at the AINP depends on this sensor so it will not be accurate at all. 

    On the other hand offset can be removed if I do a quick offset calibration before I start measurements.  i think this will be better.  I will try offset only since in the field the sensor will be the authority providing an unstable voltage to the ADC. 

    Alternatively, I can compute the offset and gain and hard coded to all boards, though this doesn't sound too good either since there will be variations from board to board.

    Finally I want to ensure the ADC goes back to SDATAC mode and that no CAL data will be erased.

    I will put the ADC in RDATAC mode first, and let it calibrate the offset.  As a side note, when I send RDATAC command and I monitor DRDYN it doesn't toggle as the datasheet says.  Is there any other pin I need to move other than CS_N low, and START high?

    void ADS1259_CalibrateADC(void)
    {
        unsigned char OpCode1 = 0, OpCode2 = 0, RegData1 = 0, RegData2=0;
        unsigned int32 ADS1259_DATAREG = 0;
        
        //Step0 - Send the Stop Data Continuous Command
        fprintf(MCU_USB,"Sending SDATAC Command\r\n");
        output_low(ADS1259_CS_N_PIN);                               //Drop CS_N
        spi_xfer(ADS1259,ADS1259_SDATAC,8);                         //Send Stop Data Control Command SDATAC     (sends 0x11)
        delay_ms(10);
        
        //Step1 - Set the Gate Control Mode (PULSE bit = 0)
        fprintf(MCU_USB,"Configure ADC for Gate Control\r\n");
        OpCode1 = (ADS1259_WREG | ADDR_CONFIG2);                    //Create Write Opcode 0x42 to write starting at address 0
        OpCode2 = 0x00;                                             //Write one register
        RegData1 = (CONFIG2_EXTCLK | CONFIG2_SYNCOUT | (CONFIG2_PULSE & 0x00) | CONFIG2_DR4); //Write CONFIG2_PULSE = 0x00 =  GATE CONTROL, the rest of them same.
        ADS1259_DATAREG = make32(OpCode1,Opcode2,RegData1);         //Compose the Opcode and Data command bytes: 00 42 00 04 only sends 42 00 04
        spi_xfer(ADS1259,ADS1259_DATAREG,24);                       //Write the Data to the ADS1259 (sends 0x42 00 04) 24 bits
        delay_ms(10);
        
        //Send the Receive Continuous Data
        fprintf(MCU_USB,"Sending Continuous Acquisition Command\r\n");
        spi_xfer(ADS1259,ADS1259_RDATAC,8);                         //Send Read Data Continous Command RDATAC     (sends 0x10)
        delay_ms(10);
        
        //Step2 -- Start the ADS1259 Conversions
        fprintf(MCU_USB,"START acquiring Data\r\n");
        output_high(ADS1259_START_PIN);                             //START Conversion command
        
        //Step3 -- Apply zero Input
        HAL_SELECT_SENSOR_CHANNEL(0x09);
        HAL_SELECT_REFRES_CHANNEL(0x00);                               //Select Secondary MUX Reference Resistance point to 11.1KOhms
        delay_ms(100);                                              //Wait 100 milliseconds
        
        //Step4 -- Send OFSCAL Offset calibration Command 0x18
        fprintf(MCU_USB,"Sending OFSCAL Command\r\n");
        spi_xfer(ADS1259,ADS1259_OFSCAL,8);                         //Send the OFSCAL command 0x18
         while(input_state(ADS1259_DRDY_N_PIN))
        {
            //wait for DRDY_N to go low
        }
        
        //spi_xfer(ADS1259,ADS1259_GANCAL,8);                        //Send the GANCAL command 0x19
        //while(input_state(ADS1259_DRDY_N_PIN))
        //{
            //wait for DRDY_N to go low
        //}
        //STOP ACQUISITION BY BRINGING START LOW
        output_low(ADS1259_START_PIN);                              //STOP Conversion command terminated
        
        //Step4 -- Read the OFC Register
        
        //Step5 -- Send the Stop Continuous Data Mode
        spi_xfer(ADS1259,ADS1259_SDATAC,8);                         //Send Stop Data Control Command SDATAC     (sends 0x11)
        //Configure Register CONFIG1 & CONFIG2 @ Address 0x01
        OpCode1 = (ADS1259_WREG | ADDR_CONFIG1);                        //Write OpCode Stating at Address 0x01 (0x41)
        Opcode2 = 0x01;                                                 //Number of Registers to write (2)
        //NO Out-of-Range Flag, No Checksum, SINC1 Filter, Internal Reference, and 555.55usec Delay time
        RegData1 = (CONFIG1_FLAG| CONFIG1_CHKSUM | CONFIG1_SINC2 | CONFIG1_EXTREF | CONFIG1_DLY7);      //Create Data to Config1 -- See header file for defaults.
        //Internal Clock, Syncout Disabled, Pulse Control,and Data Rate 400 SPS.
        RegData2 = (CONFIG2_EXTCLK | CONFIG2_SYNCOUT | CONFIG2_PULSE | CONFIG2_DR4);                    //Create Data to Config2  -- See header file for defaults
        ADS1259_DATAREG = make32(OpCode1,Opcode2,RegData1,RegData2);    //Compose the Opcode and Data command 41 01 114 14
        spi_xfer(ADS1259,ADS1259_DATAREG,32);                           //Write the Data to the ADS1259 (sends 41 01 14 14)
       
        output_high(ADS1259_CS_N_PIN);                              //Raise CS_N
         
        //Calibration Done
        fprintf(MCU_USB,"Calibration Completed\r\n");
        
    }


    RR