Skip to content

Programming >2M Samples/sec on DAC seems to cause Giga board to hang #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jmdodd95682 opened this issue Mar 20, 2023 · 9 comments · Fixed by #36
Closed

Programming >2M Samples/sec on DAC seems to cause Giga board to hang #32

jmdodd95682 opened this issue Mar 20, 2023 · 9 comments · Fixed by #36
Assignees
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project

Comments

@jmdodd95682
Copy link
Contributor

jmdodd95682 commented Mar 20, 2023

I've been able to reproduce this a couple of times. If I take the example program for generating a sinewave and change the frequency to 48000*lut_size (about 3M samples per second), the program compiles and uploads with no error. About two seconds later the board disconnects from the USB serial port and is no longer recognizable by my PC. I have to double-tap the reset and reload a program in order to get out of this. I see no "SOS" pattern on the LED. Just silence.

What is the maximum samples per second for the DAC outputs? Obviously for audio 2M samples per second is plenty. I was just wondering. If there is a hard limit, it might be good to either put a check in the code for values > 2M or at least something in the documentations saying "Don't do that".

I'm including the failing code below, but its just the sinewave example with the frequency increased to 48000*lut_size.

// This example outputs a 32KHz sine wave on A12/DAC1.
#include <Arduino_AdvancedAnalog.h>

AdvancedDAC dac1(A13);

uint16_t lut[] = {
    0x0800,0x08c8,0x098f,0x0a52,0x0b0f,0x0bc5,0x0c71,0x0d12,0x0da7,0x0e2e,0x0ea6,0x0f0d,0x0f63,0x0fa7,0x0fd8,0x0ff5,
    0x0fff,0x0ff5,0x0fd8,0x0fa7,0x0f63,0x0f0d,0x0ea6,0x0e2e,0x0da7,0x0d12,0x0c71,0x0bc5,0x0b0f,0x0a52,0x098f,0x08c8,
    0x0800,0x0737,0x0670,0x05ad,0x04f0,0x043a,0x038e,0x02ed,0x0258,0x01d1,0x0159,0x00f2,0x009c,0x0058,0x0027,0x000a,
    0x0000,0x000a,0x0027,0x0058,0x009c,0x00f2,0x0159,0x01d1,0x0258,0x02ed,0x038e,0x043a,0x04f0,0x05ad,0x0670,0x0737
};

static size_t lut_size = sizeof(lut) / sizeof(lut[0]);

void setup() {
    Serial.begin(9600);
    if (!dac1.begin(AN_RESOLUTION_12, 48000 * lut_size, 64, 128)) {
        Serial.println("Failed to start DAC1 !");
        while (1);
    }
}

void loop() {
    static size_t lut_offs = 0;
    if (dac1.available()) {
        // Get a free buffer for writing.
        SampleBuffer buf = dac1.dequeue();
        // Write data to buffer.
        for (size_t i=0; i<buf.size(); i++, lut_offs++) {
            buf[i] =  lut[lut_offs % lut_size];
        }
        // Write the buffer to DAC.
        dac1.write(buf);
    }
}
@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Mar 20, 2023
@aentinger
Copy link
Contributor

Hi @iabdalkader ☕ 👋 can you please perhaps take a look at this? 🙏 🙇

@iabdalkader
Copy link
Collaborator

What is the maximum samples per second for the DAC outputs?

The DAC can run pretty fast, maybe up to 40 Msps, currently it might be limited by the max frequency we can configure the timer for (timer needs to be configurable from very low frequencies to high frequencies) and possibly some other factors, but I tried up to 200KHz (~12 Msps) for example and it works fine. I'm not sure what the issue is, I can't reproduce it consistently, but yes I can confirm there seems to be some issue, will look into it.

@jmdodd95682
Copy link
Contributor Author

jmdodd95682 commented Mar 27, 2023 via email

@iabdalkader
Copy link
Collaborator

Thanks. I've noticed a number of funny behaviors playing around with it. Sometimes the DAC stops working and I have to power cycle the board to get it back. Could all be an MBED OS issue.

I think it may have something to do with the read/write queues getting corrupted when DAC stops/restarts, the higher frequency triggers that issue because it's more likely to underrun and stop the DAC. I'm still investigating but I think the queues are not thread-safe the way they are used, we switched to those queues to save some memory but seem they're causing trouble.

@jmdodd95682
Copy link
Contributor Author

jmdodd95682 commented Mar 29, 2023 via email

@jmdodd95682
Copy link
Contributor Author

One other thing that I had to realize. Even though the sample rate can be 2M samp/sec or higher on the DAC, the resulting analog signal really cannot have a higher frequency component than about 40KHz. I tried 64KHz output sinewave (I doubled the frequency of the lut[] data so that it was two periods in 64 samples) and the output is very bad. It does not look much like a sinewave. This makes sense to me since the DAC outputs are intended for audio which is only 20KHz. This is probably due to limitations on the slew-rate of the DAC analog outputs. So, 2M sample/sec is pretty much overkill. That's about 100X oversampling for a full audio spectrum. You really only need about 8X for high-quality audio reproduction. So, I'll probably keep my sample rate low. Perhaps 128KHz or 160KHz.

Its worth considering if you want to limit the sample rate in the dac.begin() routine to something like 250K Samp/sec. This might improve stability.

@jmdodd95682
Copy link
Contributor Author

I take it back. Ignore my previous comment. I found a bug in my sketch (I was not keeping the input to 12-bits). I can actually get an analog output which is 128KHz. I've stopped testing above that because that is way higher than I need. I could do full Dolby Surround with a single DAC channel. That's insanely good. Can't think how I would use that, but wow.

@iabdalkader
Copy link
Collaborator

iabdalkader commented Mar 31, 2023

@jmdodd95682 I fixed all of the memory issues, and some other edge cases, and it seems to be working fine now. I've also updated some of the examples, the waveform generator can now output 1KHz -> 128KHz, the sine wave example works up to 160KHz, it's probably possible to get 256KHz but we're not queuing buffers fast enough, maybe if the SDRAM is used to allocate large buffers it would work. I'm still testing things then will push the changes, but I'm attaching the library in its current state if you want to test it.

Arduino_AdvancedAnalog.zip

Note if you set a higher frequency, and add a very short delay maybe 1ms, and have a scope of course, you can see that the DAC outputs, stops, then restarts, this is just to confirm things are working as they should.

@jmdodd95682
Copy link
Contributor Author

jmdodd95682 commented Apr 1, 2023 via email

This was referenced Apr 3, 2023
@per1234 per1234 added conclusion: resolved Issue was resolved topic: code Related to content of the project itself labels Apr 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
conclusion: resolved Issue was resolved topic: code Related to content of the project itself type: imperfection Perceived defect in any part of project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants