Ouch. Retrocade ADC tester


offroad

Recommended Posts

"Ouch", because at the end of a long and painful debug process came the insight that the 2nd ADC on my board is broken. Works only when I push it down... will try resolder it tomorrow. Edit: Fixed.. the little fella had one foot off the dancefloor.

 

Anyway, one result is an ADC demo that got out of necessity a little more polished than planned.

  • Controls LED brightness with input 1 (the one closest to the SD card). The signal pin faces the edge of the board.
  • Dumps all 16 channels through USB. Set up virtual com port for the 2nd USB interface, open Teraterm and connect with default settings (9600 baud, 8 bits, 1 stop bit)
  • There is some information out there regarding control of this ADC that I find questionable, after reading the data sheet (It states explicitly that there are no timing requirements between falling edges of CS and CLK so they may change in the same cycle and the whole control logic simplifies greatly)
  • ADCs run at 50 % of maximum throughput, that is, they take turns. 8 frames are captured in one shot.
  • The data sheet shows 10 bits even though it's an 8-bit ADC. The implementation picks the correct ones, others are apparently zero (edit: no they are not - you get 10 bits of data out of the ADC)

post-36723-0-79204400-1390603661_thumb.p

Don't pay attention to values from unconnected (floating) inputs. Lower channels will "leak" over into higher, undriven channels and the terminal output gets quite noisy. Putting jumpers between signal and +5V gives clean readings (but double-check, the other position would short +5V to GND).

 

The archived project is for PlanAhead, which comes with the ISE 14.7 download.

 


This post has been promoted to an article

impl.bit

PapiliioProRetrocadeAdcDemo.pa.zip

Link to comment
Share on other sites

Maybe one comment, there's at least one "small sin" committed in the design:

 

The ADC does not get any other clock than "adcClk", which is derived from a counter.

This means that the signal stops being a conventional synchronouos signal (which carries data but no timing information within a clock period) but becomes for the ADC a clock signal (which provides the clock edge but carries no data), and which must be treated as asynchronous.

This means I must make absolutely sure that there are no "glitches" on transitions. Combinational logic that merges paths (and, or etc) is forbidden.

If I dig into the implemented schematic, I find that the signal originates from a flipflop and is inverted by a LUT. This is safe, but change the counter to some fancy FSM style and it may break.

Actually I wonder what happens if you enable LUT combining in the options.

Please don't use this code for pacemakers or thermonuclear missiles.

Link to comment
Share on other sites

That's pretty common when you have floating inputs, if you don't want the signal to "leak" over then don't allow the unused inputs to float, connect them to ground. If you connect the first unused pin to ground then that is usually enough.

 

I used to see this all the time with the Openbench Logic Analyzer, when you would want to capture a nice looking waveform to show people and the unused channels would pick up signals from the used channels. Just connecting the first unused channel to ground always cleared it up and made a pretty capture.

 

Jack.

Link to comment
Share on other sites

Hi,

 

that's true. I pointed it out because the ADC behavior isn't intuitive. The design works exactly as it should, there is nothing to fix.Sorry if this wasn't clear.

 

Also: if you have nothing connected to the inputs, why worry about the data?

 

Put some jumpers over the unused inputs, then you'll get clean 0xFF (picture. One channel is left open, put input device here).

You could solder high (say, 500 kOhms) resistors from each signal pin to +5V (with SMDs) or to GND (old-school 1/4 W radial resistors).

 

 

BTW, great news for all unemployed ADCs: My drawbar organ is making progress, slowly but steadily (2nd pic).

Curiously, the drawbar/switch matrix is more complex than the actual voice generation but it's now implemented and I'm in the middle of writing scripts to build initial parameter tables.

post-36723-0-30637400-1391208852_thumb.j

post-36723-0-51098600-1391208863_thumb.j

Link to comment
Share on other sites

simple, just connect them to 8 different pins. Run the program, open the terminal. You should see 8 columns changing independently, following one input source each.

 

There's a bit of electrical engineering involved. "Signal" means that the voltage at the pin is controlled by some external means. A wire or pin that is just floating in thin air is not controlled, it will (literally!) respond to me waving my hands nearby.

 

For example, let's say you want to connect a switch. What you do is put the switch between +5V and the ADC input pin. Then place a 10 kOhms resistor (or 100 or 1 kOhm, doesn't matter) between ADC input and ground.

Close the switch => ADC input is at a controlled 5 V level. ADC reports 0xFF.

Release the switch => ADC input is at a controlled 0 V level => ADC reports 0x00.

Unplug the circuit => input is floating, ADC will report garbage data.

Link to comment
Share on other sites

First of all, I just wanted to say that I appreciate your help guys. Secondly, I would need to read about 8 different unique signals, simultaneously. Also why have 16 pins if you can only show uniqueness to two pins (i.e. Adc1's pin 0 and adc2's pin 15)?

 

 

simple, just connect them to 8 different pins. Run the program, open the terminal. You should see 8 columns changing independently, following one input source each.

 

There's a bit of electrical engineering involved. "Signal" means that the voltage at the pin is controlled by some external means. A wire or pin that is just floating in thin air is not controlled, it will (literally!) respond to me waving my hands nearby.

 

For example, let's say you want to connect a switch. What you do is put the switch between +5V and the ADC input pin. Then place a 10 kOhms resistor (or 100 or 1 kOhm, doesn't matter) between ADC input and ground.

Close the switch => ADC input is at a controlled 5 V level. ADC reports 0xFF.

Release the switch => ADC input is at a controlled 0 V level => ADC reports 0x00.

Unplug the circuit => input is floating, ADC will report garbage data.

 

 

Thank you for that explanation offroad, I want to make sure its clear that there are indeed 16 unique analog channels on the Retrocade Synth. What we are talking about here is that when one of those 16 channels are not connected to something, ie floating, then they will show random data and that random data is often what they pick up from nearby pins. If you connect them to something then you will get unique and independent data from each channel. So it is definitely not the case that you can only use two of the 16 channels and sorry if this thread made it seem like that was so. 

 

In most cases you won't care at all what values are showing up on unused channels, you won't even read those channels anyway. But in some cases it is important which is why I felt it important to say that grounding the unused inputs will eliminate the ghost signals on unused pins. The best example I can think of is using those analog pins as an 8 channel Oscilloscope. If you have a GUI that displays all 8 channels at once but you only have something connected to pin 0 it is distracting and confusing to see the signal from pin 0 show up on all of the channels displayed. This can be avoided by simply grounding pin 1 which will usually prevent all of the rest of the floating pins from seeing the signal on pin 0. So in this special application it does matter what is happening with unused inputs, in most cases it doesn't matter at all though...

 

Another example is offroads sound bar. If he makes a 16 voice instrument and each analog channel is live and connected to a voice then he has a potential problem if he only makes an 8 channel drawbar. If the remaining 8 voices are left floating they will pickup the signals from the first 8 voices and will start sounding off with sounds that are not intended, to avoid this behavior he just needs to ground the unused analog channels.

 

Jack

Link to comment
Share on other sites

Hi,

 

no disagreement here - if my design depends on inputs that don't exist, there is indeed a problem somewhere.

 

I understand your oscilloscope example, and have to admit that it had me also quite confused (because the leakage can look very much like a genuine signal).

 

BTW, one could abuse the ADC creatively: connect one channel to +3.3 V (halfway between GND and +5V), then put an exposed wire to the 2nd one. Read channel 2 and create funny sounds from the 2nd channel voltage. If it hits either rail voltage, briefly switch back to chan 1 to center the readout. It would be a fairly sensitive electrostatic sensor, some Theremin thingy.

Link to comment
Share on other sites

This is just how a typical multi-channel single-ADC chip works.  It's basically an analog multiplexor followed by a sample-and-hold circuit followed by a ADC converter.  See attached image.

 

When channel 0 is read the sample-and-hold switch is closed and the sampling capacitor is connected to channel 0 input via the analog mux.  The switch in the sample-and-hold circuit is then opened and the ADC is converting the voltage stored in the sample-and-hold capacitor.  If channel 3 is then read then the switch is closed and the capacitor is connected to channel 3 via the analog mux etc.  However, if channel 3 input is just floating then the capacitor voltage will not change and the subsequent ADC conversion will read the same value as the previous channel had.

post-36465-0-40294200-1391298515.jpg

Link to comment
Share on other sites

Hi,

 

an updated version to my earlier code: This one runs at a global clock frequency of 96 MHz instead of 32M.

The ADC is still clocked at 16 MHz, added one divide-by-3 counter and changed the baudrate divider.

 

Project for Planahead from ISE 14.7; Papilio Pro with Retrocade ADCs; USB terminal at 9600 kBaud and default settings.

 

edit forgot to change the CLK32M port name... read it as CLK96M...

project_12_96M_adc.pa.zip

impl.bit

Link to comment
Share on other sites

  • 3 months later...

A brief follow-up: As the code switches the inputs at the maximum rate, it needs a fairly low-impedance source. A 100 kOhm poti won't do, it'll show significant crosstalk from the previous channel (I tried).

This could be worked around by reading each channel multiple times, and discarding the first result. Or use lower resistance potis - 1 kOhm draws 5 mA, it's' not like it would show up on the electricity bill...

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.