I will analyse later your code, but I can already see weird things:
Lines 265 and 266:
Timer Counter 0 Channel 2 triggers DAC conversions (you are no more in free running mode !) thru TIOA2 internally . However, you set TC_CPRD to timerperiod = 0 ? and TC_CDTY to timerperiod (?) = 0 ? CDTY range should be: 0 < CDTY < CPRD and obviously timerperdiod not equal to 0.
TC_CPRD and TC_CDTY are not 0 they are defined in the setup, taking in account the sample rate of the wav file, before tc_setup() is called, anyway I’ve changed the default value.
It seems like enabling NVIC interrupts for DACC are disabling all the other interrupts like the SPI (SD) and the USART (Serial). Is it normal?
One solution to keeping the SD selected is to use a serial port as dedicated SPI bus as mentioned above but still write whole blocks at a time. The SD card has a controller with a wear map of the flash and it can take a little extra time addressing a block so extra buffer space for incoming data is a good idea.
Nick Gammon has serial port as master mode SPI and slave mode SPI for AVR’s on his blog pages, maybe by now he’s done ARM as well.
I don’t understand, which serial port are you refering? The USART?
I don’t have a Due but I do wonder about some things,
Does the Due have an SD or SDFat library like the AVR-duinos? It uses a buffer to write to SD in burst mode.
The Due has SD and SDFat libraries like the other AVR based arduinos.
GoForSmoke is right, there are faster SD libraries for DUE (SDFAT) or (more tricky) you can use High Speed Multimedia Interface peripheral (HSMCI). It has been rarely used for some reason, but IMO this is super fast reading/Writing to an SD card.
I have to check if the reading and writing functions are similar, otherwise, I’ll have to rewrite the reading code. Improving the SD reading speed could be helpful.
Since you are not using Free Running mode, to debug, I would first try to read the SD card then output the result at a relatively slow frequency (e.g. 44.1 KHz) far from 1 MHz and see what happens with higher frequencies.
I need to read the whole wav file and not a few samples, it’s very hard to tell if the signal is ok, with 100 or 200 ms of samples (I can’t save more time in the Due’s RAM). I need to be reading the file from the SD and feed samples to DAC.
Edit: TurboSpi is by far the best way to go to speed up SPI (42 MHz)
I don’t need to go that fast, I think somewhere between 10 MHz and 20 MHz is ok.
Anyway, my goal is to make something similar to the Audio library, that can read wav files, but with a recording feature added.
The code should:
- Read an wav file sampled at up to 44.1 kHz or 48 kHz and feed samples to the DAC (preferrably external) because a resolution of at least 16 bits is desirable. Both DAC and SD card communicate thru SPI
- Record an wav file to the SD sampled using the same frequency, 44.1 kHz or 48 kHz, with samples from an ADC (also SPI and external with at least 16 bit resolution)
The circuit is supposed to be used with ECG frontends to perform closed loop tests. For example introducing some noises to the ECG signal on a wav file to preform noise rejection tests to ECG frontends. The result is saved on the SD card using the wav format.
The circuit is made of:
SD Card <->Arduino Due → DAC → signal conditioning circuits → ECG frontend → ADC
For now I’m trying only to make the first step, reading a wav file sampled at 44.1 kHz or 48 kHz, but it’s very difficult.
DumpAudioFile5_optimized_dma.ino (23.5 KB)