ADC and TZXduino
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
ADC and TZXduino
I've purchased a TZXduino from eBay; it is working fine with real hardware, except for some issues with file formats. However, with the MiSTer I am having a more serious problem. When trying to load tapes with the Spectrum core, it seems that the audio comes too late quite often.
For example, when loading a normal program, normally you first hear ~5 seconds of lead tone, then the header itself, then there's a one second pause and then a second lead tone, which lasts about 2 seconds. But with the TZXduino, the pause seems to last longer and the lead tone starts being heard almost when it's about to finish, often even being missed by the loader, which keeps showing the blue/red flashing border.
When plugging the TZXduino directly to the speakers, the audio is clearly right.
Does anyone know what may be going on? I suspect that the issue is caused by the lack of a fast enough DC offset removal filter; it seems that there's a very slow one (maybe 1 Hz?) and that the offsetting of the signal during the silence is causing the issue. Is that a plausible explanation?
It's worth noting that when the header block is almost immediately followed by the next tone (with about a 100 ms pause instead of the default 1s), the second block is caught properly and the problem doesn't happen.
Assuming that the problem is the lack of a HPF, can I just add a simple passive RC filter with a 100nF capacitor and a 10K resistor, in the cable to the ADC? That gives me a cutoff frequency of 159 Hz which I believe can be adequate, but are there any other considerations that make such a filter not be a good idea? Take into account that I have very little knowledge of analog electronics.
For example, when loading a normal program, normally you first hear ~5 seconds of lead tone, then the header itself, then there's a one second pause and then a second lead tone, which lasts about 2 seconds. But with the TZXduino, the pause seems to last longer and the lead tone starts being heard almost when it's about to finish, often even being missed by the loader, which keeps showing the blue/red flashing border.
When plugging the TZXduino directly to the speakers, the audio is clearly right.
Does anyone know what may be going on? I suspect that the issue is caused by the lack of a fast enough DC offset removal filter; it seems that there's a very slow one (maybe 1 Hz?) and that the offsetting of the signal during the silence is causing the issue. Is that a plausible explanation?
It's worth noting that when the header block is almost immediately followed by the next tone (with about a 100 ms pause instead of the default 1s), the second block is caught properly and the problem doesn't happen.
Assuming that the problem is the lack of a HPF, can I just add a simple passive RC filter with a 100nF capacitor and a 10K resistor, in the cable to the ADC? That gives me a cutoff frequency of 159 Hz which I believe can be adequate, but are there any other considerations that make such a filter not be a good idea? Take into account that I have very little knowledge of analog electronics.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
If you mean the one with the scope, yes, and that's what gave me the idea of the DC offset removal. Here's a video with an example standard load block:
http://www.formauri.es/personal/pgimeno ... c-test.mp4
I don't know how to interpret it properly, but if the zero is on the left and max volume is on the right, it seems that the second block starts above the default threshold in the framework.
https://github.com/MiSTer-devel/Templat ... 08.sv#L105
If I'm interpreting it right, the sum of the last four values sampled is compared against 16 low and 64 high, for hysteresis, and the sum has 14 bits, i.e. the maximum is 16380. The core doesn't modify these parameters. From visual inspection it seems clear that when the second leading tone starts, it's above zero for a while; from a bit of GIMP it seems to be about 3% above zero, which multiplied by 16380 gives 523. That's clearly above the 16/64 threshold used in the framework.
I'm guessing that the MiSTer expects the input to be symmetrical, so it uses a value close to zero as threshold, because the ADC does not measure negative values.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
-
- Core Developer
- Posts: 547
- Joined: Sun May 24, 2020 9:30 pm
- Has thanked: 20 times
- Been thanked: 145 times
Re: ADC and TZXduino
Is that the ADCTest core ?
If so, that volume level is way too loud - the yellow lines are the limits of the analog-to-digital converter, about 3.3V...
The level which should be played would be "line level" which is closer to 0.8V peak-to-peak. At the lower level, the system has a chance to modelling the waveform properly.
Note that ADC's input range is 0V - 3.3V; a DC-coupled source would be producing both positive voltages (detectable) and negative (out of range and thus undetectable). For this reason, I use a 10uF capacitor in series to the audio signal to AC-couple it. When AC coupled, the input voltage drifts into the centre of the ADC's range (at the end of the video, it looks like you are doing this). Old analog electronics (i.e. cassette deck) would be AC-coupled from the beginning.
In my ADC usage, I don't pay attention to the 16 or 64 values, and I use 12 bits - which gives a range of 0 - 4096. Which means each "point" of delta is roughly 0.001 volts.
ADC_RATE is the sample rate of the analog signal, and CLK_RATE is the rate of SPI data transmission from the ADC chip (these values should be fine as-is for tape).
Having said all this, I can't speak for the Spectrum core...
However, to simulate an actual cassette deck's output level:
If you use the ADCTest core, you should set the "scale" to "line level", and adjust the volume so that the waveform doesn't go far into the red areas on either side - and especially that it shouldn't hit the yellow limit lines.
If so, that volume level is way too loud - the yellow lines are the limits of the analog-to-digital converter, about 3.3V...
The level which should be played would be "line level" which is closer to 0.8V peak-to-peak. At the lower level, the system has a chance to modelling the waveform properly.
Note that ADC's input range is 0V - 3.3V; a DC-coupled source would be producing both positive voltages (detectable) and negative (out of range and thus undetectable). For this reason, I use a 10uF capacitor in series to the audio signal to AC-couple it. When AC coupled, the input voltage drifts into the centre of the ADC's range (at the end of the video, it looks like you are doing this). Old analog electronics (i.e. cassette deck) would be AC-coupled from the beginning.
In my ADC usage, I don't pay attention to the 16 or 64 values, and I use 12 bits - which gives a range of 0 - 4096. Which means each "point" of delta is roughly 0.001 volts.
ADC_RATE is the sample rate of the analog signal, and CLK_RATE is the rate of SPI data transmission from the ADC chip (these values should be fine as-is for tape).
Having said all this, I can't speak for the Spectrum core...
However, to simulate an actual cassette deck's output level:
If you use the ADCTest core, you should set the "scale" to "line level", and adjust the volume so that the waveform doesn't go far into the red areas on either side - and especially that it shouldn't hit the yellow limit lines.
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
Well, there's something wrong in all this.
I have checked with a scope; the signal from the TZXduino is fixed at 5V (it has a trimmer for adjusting the output signal intensity, but it doesn't seem to do anything - maybe because there's no load). It's not symmetric; it goes from +2V to -3V or vice versa, depending on polarity. During silences it rests on one of both values, at +2 while nothing is playing and at -3 during pauses between blocks. There doesn't seem to be any HPF or coupling capacitor in the device.
However, in the ADCTest you can clearly see that the signal drifts, albeit very slowly. The most confusing part is that it drifts towards the centre, not towards zero, and this is even predicted by the ADCTest core's README; I tried to find a schematic of the MiSTer ADC input to find out if there's an internal capacitor or the like, and how it's connected and where the centre is, but I couldn't find any. All I found is a board with two connectors.
Drifting towards the centre means that the expected central value is around 2048(?) (if it admits higher signals it's probably lower), not 16 or 64 as the ltc2308_tape component expects, so at least that is a bug. The Spectrum core uses a ltc2308_tape module from the framework verbatim; the output is directly sent to the Z80's input port.
About the signal intensity, if levels as low as you mentioned were expected then the ADC in the Spectrum core would not work at all, because the decoupler would keep the signal centred around 2048 and never get to the 16/64 level expected by the framework's component. If it works for people, it means that they are using a loud signal level.
I've tried raising the threshold numbers in the Spectrum core to 800 and 880, and that fixed things. I can use it unfiltered now.
By the way, MSX computers typically used a high pass filter of about 50-200 Hz cutoff for DC offset removal. I believe most other computers used something similar.
I have checked with a scope; the signal from the TZXduino is fixed at 5V (it has a trimmer for adjusting the output signal intensity, but it doesn't seem to do anything - maybe because there's no load). It's not symmetric; it goes from +2V to -3V or vice versa, depending on polarity. During silences it rests on one of both values, at +2 while nothing is playing and at -3 during pauses between blocks. There doesn't seem to be any HPF or coupling capacitor in the device.
However, in the ADCTest you can clearly see that the signal drifts, albeit very slowly. The most confusing part is that it drifts towards the centre, not towards zero, and this is even predicted by the ADCTest core's README; I tried to find a schematic of the MiSTer ADC input to find out if there's an internal capacitor or the like, and how it's connected and where the centre is, but I couldn't find any. All I found is a board with two connectors.
Drifting towards the centre means that the expected central value is around 2048(?) (if it admits higher signals it's probably lower), not 16 or 64 as the ltc2308_tape component expects, so at least that is a bug. The Spectrum core uses a ltc2308_tape module from the framework verbatim; the output is directly sent to the Z80's input port.
About the signal intensity, if levels as low as you mentioned were expected then the ADC in the Spectrum core would not work at all, because the decoupler would keep the signal centred around 2048 and never get to the 16/64 level expected by the framework's component. If it works for people, it means that they are using a loud signal level.
I've tried raising the threshold numbers in the Spectrum core to 800 and 880, and that fixed things. I can use it unfiltered now.
By the way, MSX computers typically used a high pass filter of about 50-200 Hz cutoff for DC offset removal. I believe most other computers used something similar.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
-
- Core Developer
- Posts: 547
- Joined: Sun May 24, 2020 9:30 pm
- Has thanked: 20 times
- Been thanked: 145 times
Re: ADC and TZXduino
The 16/64 numbers almost certainly mean something compketely different than what you think. Without looking at the code, I would assume that they are related to reduction of spurious change, and so are measutres of delta change in signal (probably a minimum change required to be accepted as good data). I believe that there is no bug; just a misunderstanding of the meanings of these values.
If the TZXDuino is producing 5V peak to peak, it is potentially dangerous for the ADC on the DE10, and should not be used until the signal can be brought to within the expected input limits. I would question whether it could also damage original hardware… Unless original hardware had an explicit low impedance (effectively a resistor across input and ground, reducing the level). The ADC on DE10 is high impedance, and is direct-sampling: you could use it as a voltmeter or to accept some other DC input like a volume control; the AC coupling is intended to be on the signal provider (as it had been on cassette players back in the day). The ADC is a general-purpose input, not a tape-specific input, so the signal provided needs to be in such a format. There is probably value in somebody creating a plug-socket adapter with the inline capacitor and a bridge resistor (to fix an impedance/load), but it hasn’t been discussed until now.
If the signal drifts toward zero, then there would seem to be at least some amount of capacitance, although the decoupling is not sufficient.
If the TZXDuino is producing 5V peak to peak, it is potentially dangerous for the ADC on the DE10, and should not be used until the signal can be brought to within the expected input limits. I would question whether it could also damage original hardware… Unless original hardware had an explicit low impedance (effectively a resistor across input and ground, reducing the level). The ADC on DE10 is high impedance, and is direct-sampling: you could use it as a voltmeter or to accept some other DC input like a volume control; the AC coupling is intended to be on the signal provider (as it had been on cassette players back in the day). The ADC is a general-purpose input, not a tape-specific input, so the signal provided needs to be in such a format. There is probably value in somebody creating a plug-socket adapter with the inline capacitor and a bridge resistor (to fix an impedance/load), but it hasn’t been discussed until now.
If the signal drifts toward zero, then there would seem to be at least some amount of capacitance, although the decoupling is not sufficient.
-
- Core Developer
- Posts: 459
- Joined: Wed May 26, 2021 9:35 pm
- Has thanked: 59 times
- Been thanked: 383 times
Re: ADC and TZXduino
The 16/64 numbers that you see is to flip the "cassette bit" when the incoming signal from the ADC is lower then 16 of the AVERAGE or 64 above it and not the low/high values of the sample.
The ltc2308_tape module constantly calculates an average sample value when a sample is lower then the average by 16 or more, it flips the bit in one direction, if it's 64 or more higher then the average it flips it the other way. This acts as a filter for things like ground/line noise.
Most issues with tape input is the incoming volume. You just have to play with the volume of the device until you find that sweet spot.
The ltc2308_tape module constantly calculates an average sample value when a sample is lower then the average by 16 or more, it flips the bit in one direction, if it's 64 or more higher then the average it flips it the other way. This acts as a filter for things like ground/line noise.
Most issues with tape input is the incoming volume. You just have to play with the volume of the device until you find that sweet spot.
-
- Core Developer
- Posts: 547
- Joined: Sun May 24, 2020 9:30 pm
- Has thanked: 20 times
- Been thanked: 145 times
Re: ADC and TZXduino
...Which is actually one of the reasons I wrote the ADCTest core... so that one has visibility to the level. I recall from the old days that volume levels were always an issue, and being blind to them made tape use painful, even when the real computer and the real tape player were "made for each other" and tested to be compatible.
(I later found out that the DC or AC coupling is an even more important use)
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
There's still something wrong in all this.
When the ADC is not connected, the signal is at about 1.7 or 1.8V (slightly off-centre) judging by the ADCtest image, and very stable; no signs of noise. That's not what I'd expect from high-Z, which would be a somewhat unstable signal due to ambient noise.
I've made an experiment. I've made a cable and shorted the input, and the signal does go all the way to the left, which means 0V is at the left. It also doesn't drift back to the centre at any time, therefore if there's a capacitor, it's definitely not on the MiSTer side. Then I've connected a 1.5V battery, which I measured with a tester to give 1.48V, and it was at about 1.45 or so in the ADCTest core (always approximate due to the low resolution and lack of reference marks); also constant with no signs of drift, but a little bit more unstable than the signal when unconnected. That may also be due to some noise with the simple handmade cable, because with the cable connected to the MiSTer but unconnected on the other side, the signal does contain a bit of noise.
That makes me think that there's no capacitor on the MiSTer, but it's also not high-Z, at least not negligible-Z, and there must be something like a couple of resistors in a voltage divisor configuration giving the default measure in absence of input.
The results I'm getting seem to be somewhat consistent with a capacitor with no resistor in the TZXduino side, and non-negligible impedance in the input, giving ~1.7V, on the MiSTer side. To test this, I've measured with the oscilloscope the voltage in the ADC input with a cable connected to nowhere but the scope, and indeed I got slightly under 1.8V, pretty flat with no discernible noise.
The consequence for the TZXduino is that a decoupling capacitor with no resistor will be charged (through the ADC connector) to ~1.7V in the presence of a symmetric signal, and that's where the problem I'm having seems to be rooted. The pause between blocks gives a -3V signal which causes the capacitor to charge to 1.7V - (-3V) = 4.7V, and when the actual signal comes the capacitor is too high for a while; high enough for the signal not to cross zero for too long, as seen in the video, thus missing the next block.
The TZXduino unit I bought has no external volume control; there's an internal trimmer to adjust the voltage, but even at the minimum it saturates the MiSTer. My suspicion is that it's not configured as a voltage divisor, but as a variable resistor in series with the output, because when I measured with the scope, I saw no difference in voltage when moving the trimmer, which I can only explain if there's no load (as was the case).
5V will not cause damage to most old computers. The ZX81 has three jack connectors, one for power, one for ear and one for mic, all together; you can imagine how many times every ZX81 user will have connected the power to the wrong socket, and fed 5V 9V through the ear connector.
Here's the schematic of a tape input circuit for a Panasonic MSX machine:
The capacitor is really low, and there's a non-negligible impedance of ~20K to the 2.5V reference given by the voltage divider formed by R13 and R14. The feedback via R9 confuses me, though. I don't know what kind exactly is a µPC311, maybe a comparator, and I've forgotten most of what I knew about opamps and feedback and all that. Anyway, it seems clear that C6 will charge very rapidly and therefore quickly remove any offset in the input.
So, my thought is that a high pass RC filter will surely help with centring the signal around zero instead of 1.7V, and depending on the actual impedance of the MiSTer, which I don't know, a 10K resistor might be too high; it probably won't but it's something to consider. And that filter should IMO be part of the standard MiSTer equipment.
With that in mind, @dshadoff is probably right that there's no bug in the framework, but now I believe that there *is* a bug in the hardware.
When the ADC is not connected, the signal is at about 1.7 or 1.8V (slightly off-centre) judging by the ADCtest image, and very stable; no signs of noise. That's not what I'd expect from high-Z, which would be a somewhat unstable signal due to ambient noise.
I've made an experiment. I've made a cable and shorted the input, and the signal does go all the way to the left, which means 0V is at the left. It also doesn't drift back to the centre at any time, therefore if there's a capacitor, it's definitely not on the MiSTer side. Then I've connected a 1.5V battery, which I measured with a tester to give 1.48V, and it was at about 1.45 or so in the ADCTest core (always approximate due to the low resolution and lack of reference marks); also constant with no signs of drift, but a little bit more unstable than the signal when unconnected. That may also be due to some noise with the simple handmade cable, because with the cable connected to the MiSTer but unconnected on the other side, the signal does contain a bit of noise.
That makes me think that there's no capacitor on the MiSTer, but it's also not high-Z, at least not negligible-Z, and there must be something like a couple of resistors in a voltage divisor configuration giving the default measure in absence of input.
The results I'm getting seem to be somewhat consistent with a capacitor with no resistor in the TZXduino side, and non-negligible impedance in the input, giving ~1.7V, on the MiSTer side. To test this, I've measured with the oscilloscope the voltage in the ADC input with a cable connected to nowhere but the scope, and indeed I got slightly under 1.8V, pretty flat with no discernible noise.
The consequence for the TZXduino is that a decoupling capacitor with no resistor will be charged (through the ADC connector) to ~1.7V in the presence of a symmetric signal, and that's where the problem I'm having seems to be rooted. The pause between blocks gives a -3V signal which causes the capacitor to charge to 1.7V - (-3V) = 4.7V, and when the actual signal comes the capacitor is too high for a while; high enough for the signal not to cross zero for too long, as seen in the video, thus missing the next block.
The TZXduino unit I bought has no external volume control; there's an internal trimmer to adjust the voltage, but even at the minimum it saturates the MiSTer. My suspicion is that it's not configured as a voltage divisor, but as a variable resistor in series with the output, because when I measured with the scope, I saw no difference in voltage when moving the trimmer, which I can only explain if there's no load (as was the case).
5V will not cause damage to most old computers. The ZX81 has three jack connectors, one for power, one for ear and one for mic, all together; you can imagine how many times every ZX81 user will have connected the power to the wrong socket, and fed 5V 9V through the ear connector.
Here's the schematic of a tape input circuit for a Panasonic MSX machine:
The capacitor is really low, and there's a non-negligible impedance of ~20K to the 2.5V reference given by the voltage divider formed by R13 and R14. The feedback via R9 confuses me, though. I don't know what kind exactly is a µPC311, maybe a comparator, and I've forgotten most of what I knew about opamps and feedback and all that. Anyway, it seems clear that C6 will charge very rapidly and therefore quickly remove any offset in the input.
So, my thought is that a high pass RC filter will surely help with centring the signal around zero instead of 1.7V, and depending on the actual impedance of the MiSTer, which I don't know, a 10K resistor might be too high; it probably won't but it's something to consider. And that filter should IMO be part of the standard MiSTer equipment.
With that in mind, @dshadoff is probably right that there's no bug in the framework, but now I believe that there *is* a bug in the hardware.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
I'm pretty sure I'm right, you can look for yourself, the .sv code is very straightforward. When the sum of the last 4 samples (which are numbers between 0 and 2047) is less than 16, i.e. when the average of the last 4 samples is less than 4, the output register is cleared, and when it's more than 64 (i.e. the average is greater than 16), it is set. It's not about the hysteresis, which is clear (even in the name), but about the fact that the level under consideration is pretty close to zero, and not to the default value of almost 1.8V, whatever the sample value of that is (maybe 2048, maybe less). Remember it's handling unsigned values.dshadoff wrote: ↑Sat Feb 12, 2022 12:38 pm The 16/64 numbers almost certainly mean something compketely different than what you think. Without looking at the code, I would assume that they are related to reduction of spurious change, and so are measutres of delta change in signal (probably a minimum change required to be accepted as good data). I believe that there is no bug; just a misunderstanding of the meanings of these values.
If the input signal is centred around 1.8V (which isn't happening with the TZXduino I bought), it means that in order to trigger that hysteresis comparator, the signal must saturate.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
-
- Core Developer
- Posts: 547
- Joined: Sun May 24, 2020 9:30 pm
- Has thanked: 20 times
- Been thanked: 145 times
Re: ADC and TZXduino
In your schematic, C6 isolates the DC drive and the next few steps of the circuit then proceed to apply a DC bias and send it into a comparator (or possibly op-amp). As the comparator has a 5V supply, a 5V input is not expected to damage the device, though a supply greater than 5V might. This looks to be a type of “zero-crossing” detection circuit which is one form of tape input electrical implementation. I am not familiar with the tape sections of many machines, so I can’t speak to your particular use case, be just keep in mind that this input conditioning is not a part of MiSTer’s ADC, and therefore the signal provided to ADC must be within a set of electrical norms for the core to make sense of it.
Perhaps the author of the core in question can add a comment about what type of signal they are expecting.
I know that for CoCo2, I am expecting an AC coupled input at line level (0.7V peak to peak, more or less), and I track the average signal level on a roughly 60Hz interval (to deal with varying DC bias), max/min levels in the same time period, and average deviation from this average, on a per-cycle basis for the incoming signal. Zero-crossing is detected as the signal crosses the running average signal level.
For TRS-80, as the input signal conditioning is different on original hardware, I have essentially the same expectations of input signal, but it is not a zero-crossing system; it is a threshold-crossing system with a latch. This makes it a more sensitive system, and the threshold needs to be calculated realistically.
Note: The reference voltage on the ADC of the MiSTer appears to be between 3.5V and 4V, so a 5V input may cause damage (check the datasheet of the device).
Whatever is going on here, you will need to do something with that signal to ensure that it doesn’t “drive” a negative voltage into the ADC, and the range of voltages doesn’t exceed the range of the ADC.
1) Series capacitor, as shown in your circuit, will give it an AC coupling.
2) resistor across the output (after the capacitor) will reduce the overall range. This will form a filter, so choose your capacitor value wisely in order to let enough of the signal’s important frequencies through.
3) you shouldn’t need to add any additional bias to the signal due to the ADC’s natural bias to tend toward center, but you want to try.
Perhaps the author of the core in question can add a comment about what type of signal they are expecting.
I know that for CoCo2, I am expecting an AC coupled input at line level (0.7V peak to peak, more or less), and I track the average signal level on a roughly 60Hz interval (to deal with varying DC bias), max/min levels in the same time period, and average deviation from this average, on a per-cycle basis for the incoming signal. Zero-crossing is detected as the signal crosses the running average signal level.
For TRS-80, as the input signal conditioning is different on original hardware, I have essentially the same expectations of input signal, but it is not a zero-crossing system; it is a threshold-crossing system with a latch. This makes it a more sensitive system, and the threshold needs to be calculated realistically.
Note: The reference voltage on the ADC of the MiSTer appears to be between 3.5V and 4V, so a 5V input may cause damage (check the datasheet of the device).
Whatever is going on here, you will need to do something with that signal to ensure that it doesn’t “drive” a negative voltage into the ADC, and the range of voltages doesn’t exceed the range of the ADC.
1) Series capacitor, as shown in your circuit, will give it an AC coupling.
2) resistor across the output (after the capacitor) will reduce the overall range. This will form a filter, so choose your capacitor value wisely in order to let enough of the signal’s important frequencies through.
3) you shouldn’t need to add any additional bias to the signal due to the ADC’s natural bias to tend toward center, but you want to try.
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
Spectrum machines are prepared to work with typical cassette players, connected via the earphones jack. Lacking any directions in the core, I'd expect the MiSTer to accept the same. Edit: They detect zero crossings.
I've taken a look at the LTC2308 datasheet. In the Absolute maximum ratings section it says: "Analog Input Voltage (Note 3) CH0-CH7, COM, REF, REFCOMP....................(GND - 0.3V) to (AVDD + 0.3V)". Note 3 says: "When these pin voltages are taken below ground or above VDD, they will be clamped by internal diodes. These products can handle input currents greater than 100mA below ground or above VDD without latchup."
Is it likely that the TZXduino can supply more than 100mA through that output? I guess that adding a resistor to limit the current would be wise to play safe.
Where the BLEEP is the ADC chip, by the way? Is it part of the DE10-Nano?
Well, that's confusing. If I add a resistor across the output after the capacitor, the effect of the AC coupling will be nullified. But on the other hand the Spectrum core won't work if the signal doesn't reach zero (zero as in, the left bar of the ADCTest core), so even if I add the capacitor after the filter with the signal attenuated, I won't get anything in the core. Also, without knowing the real impedance of the MiSTer's ADC, that capacitor's value is a mystery. Remember that there's already one and it's causing trouble because it drifts too slowly.dshadoff wrote: ↑Sat Feb 12, 2022 9:59 pm Whatever is going on here, you will need to do something with that signal to ensure that it doesn’t “drive” a negative voltage into the ADC, and the range of voltages doesn’t exceed the range of the ADC.
1) Series capacitor, as shown in your circuit, will give it an AC coupling.
2) resistor across the output (after the capacitor) will reduce the overall range. This will form a filter, so choose your capacitor value wisely in order to let enough of the signal’s important frequencies through.
3) you shouldn’t need to add any additional bias to the signal due to the ADC’s natural bias to tend toward center, but you want to try.
I'm leaning towards this: But if the 16/64 values are finally considered a bug, and after this discussion I believe it's likely, the capacitor should be put on the MiSTer side and be lower, but hard to know how much without info on the actual impedance of the ADC circuit. I guess I'll need some trial-and-error.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
-
- Core Developer
- Posts: 547
- Joined: Sun May 24, 2020 9:30 pm
- Has thanked: 20 times
- Been thanked: 145 times
Re: ADC and TZXduino
But this is my point - the TZXduino is not a typical cassette player, and I don't believe that it's behaving like one.
Have you tried using a typical cassette player from the 80's on this core ? (Walkman from the 90s would be equivalent - should be analog tech though).
I used my old Walkman on all my cores, which is how I understood what the signal was supposed to look like. I also learned through this experience that 1980s/90s analog devices are pretty much all AC-coupled, whereas modern digital devices (computer sound card output, cellphone output, etc.) are pretty much all DC-coupled. ...Either way would be fine if the ADC were tuned to accept negative voltages... but as its lower reference is zero, the input needs to fit within the range of the inputs.
Yes it is. And it's a general-purpose input, which means that it would be wrong to put an AC coupling on it directly, as it would no longer be able to measure DC voltages, only AC - and even then, there would be a frequency range that it is "tuned" to.
Note that the "ADC Board" for MiSTer also does not have any components on it - only connectors.
...As a follow-up to the earlier questions, I double-checked my code, and I have been using the ltc2308 module, NOT the ltc2308_tape module, so that's why I don't recall those other parameters being important.
I think the author of this portion of the Spectrum core should be the one to comment from here, especially what their expectations of the input signal should be, and how the ADC input is used.
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
It's not, but only because of the lack of volume control, and the high capacitance of the capacitor together with the high impedance of the input. The earphone output of cassette players can easily reach 5V, and in my experience most of the times you had to turn the volume to the maximum or very close to the maximum for optimal loading.
I tried with my cassette player. It works, but it has problems. It appears to have a capacitor, but an ever slower one than the TZXduino; surprisingly this works somewhat to its advantage because it doesn't charge enough during silences like the TZXduino does, but I didn't make full sense of what I saw when looking at the behaviour so I'm not sure of this. The signal is centred higher than by default with MiSTer, at maybe 2.5V. It's not a normal player, it's a computer-specific tape player by Panasonic (it even includes an option to invert the phase), so that might have something to do with it.
As predicted, if I don't saturate the signal so it touches the zero, then the Spectrum core doesn't read anything at all. Apparently the core outputs the pulse to the audio as it reads it, not the analogue value, so you can hear no sound at all when the level does not trigger the input. The prediction that the level needs to reach the zero on the left (of the ADCTest core) is therefore accurate.
So we're finally getting somewhere. The MiSTer is using a generic ADC with a range of 0-3.3V, high(ish) impedance and no support for negative values, and is advertising that as being usable for generic tape input. Can you see the wrongness in that?dshadoff wrote: ↑Sun Feb 13, 2022 1:59 am Yes it is. And it's a general-purpose input, which means that it would be wrong to put an AC coupling on it directly, as it would no longer be able to measure DC voltages, only AC - and even then, there would be a frequency range that it is "tuned" to.
Note that the "ADC Board" for MiSTer also does not have any components on it - only connectors.
Let me help. With infinite impedance, an AC coupling capacitor is useless. It will remain charged with the initial charge (typically 0V) it had all the time, with nothing altering its charge. It is simply the same as not having a capacitor at all. My oscilloscope, for example, has a high enough impedance for the TZXduino signal not to move, even though there seems to be a coupling capacitor. In the MiSTer there seems to be some discernible impedance, because the capacitor does move, but it's still too high because it moves too slowly.
And with no ability to properly remove the DC offset in the incoming signal, the input is not suitable for audio use.
For audio input use, a circuit is necessary to define the zero reference (to compensate for the lack of negative voltage) and give a low enough impedance for coupling capacitors to do their work properly. Such a circuit can only be inside the MiSTer because it has the 3.3V voltage that will define the zero reference, which I presume should be 1.6V. Here's how I picture it (again, with my limited knowledge):
[Edit: There are spare inputs in the ADC chip; it's possible to use an extra input for audio and leave the current ADC as is.]
In the specific case of this core, a workaround is possible using an external circuit: a high pass filter, which will centre the signal around 0. That was my initial plan; since the Spectrum only cares about zero crossings, and the framework expects values around zero, going negative should not be a problem.
As I said, the Spectrum core uses the framework module verbatim; therefore the problem is in the framework module, not in the core (other than not redefining the parameters to something that makes sense).
Edit: A git blame shows that it's been like this since the first commit by Sorgelig in 2017, and in the Spectrum core since the addition of tape loading in 2019 also by him.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV
- pgimeno
- Top Contributor
- Posts: 709
- Joined: Thu Jun 11, 2020 9:44 am
- Has thanked: 277 times
- Been thanked: 226 times
Re: ADC and TZXduino
In the end, all I needed was a resistor to compensate for the MiSTer ADC's high-ish impedance, to allow the TZXduino's internal capacitor to do its work more quickly. Since I was there, I also lowered the signal strength a bit, with a voltage divisor - 1K and 2K2, so a total impedance of 3K2 (10K would also have worked, but this way recovery is even faster) and an attenuation of ~68% of the voltage for a maximum of 3.43V peak to peak. [Edit: As a side effect, and just as I imagined, the internal volume trimmer now also works.] [Edit2: It still loads everything perfectly with under 1 volt peak to peak. In the ADCTest core the signal is now centred on zero, as expected.]
I am now sure that this input is not suitable for audio without additional circuitry.
I am now sure that this input is not suitable for audio without additional circuitry.
Converters I've written: Floppy DIM/FDI/FDD/HDM to D88, D88 to XDF, Tape SVI 318/328 CAS to WAV