simple sound player: PWM audio output, with DMA, without timer interrupt

Post your cool example code here.
victor_pv
Posts: 1735
Joined: Mon Apr 27, 2015 12:12 pm

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by victor_pv » Wed Nov 01, 2017 1:14 pm

It's a different feature than the burst.
In the burst, you can update several timer registers at once, because the timer will generate several DMA requests instead of one.
The repeat feature is more like the opposite (although both can be used together), the timer will reach the reload value several times before if generates one request.
It's like this:

Memory content:
abcde

Timer actions (if set for 3 repeats for example):
Timer generates dma to load first value "a".
Timer counts until "a", does not generate DMA request, and starts counting again
Timer counts until "a" for the second time, does not generate DMA request, and starts counting again.
Timer counts until "a" for the thrid time, now generates DMA requests to load "b"
Timer counts until "b", similarly 3 times, and only in the third generates DMA event and loads "c"
Timer counts until "c" 3 times, and on the third triggers DMA to load "d"
...
All those times the timer compare events are happening, so you get your PWM signal with your duty cycle acccording to the values, but you get it 3 times before it loads the next one.

The effect is that you can set an ARR that produces 3 times your frequency )3 is just an example, ir all depends what frequency and how many bits or resolution you want to use for PWM). Frequency was 16Khz in the example, you can configure ARR to produces a 48Khz frequency, so the exact same pwm pulse will be produced 3 times, then load the next value and produce that pulse 3 times. The PWM duty is the want you wanted, since it's a relation between ARR and the Timer compare value, but the frequency is 3 times higher, so your noise is concentrated at a much higher frequency and easier to filter.

The datasheet explains it better than me, sorry I'm not too good at explaining this things. The section is called "repetition counter" in the reference manual. It's section 14.3.3, page 305.

EDIT: for reference, this is my old code before adding the DMA stuff, but it uses the same repetition register (RCR)
The value is calculated here (is precalculated above that for a few normal frequencies, but can be calculated on the fly with same results, and it does for unusual frequencies):
https://github.com/victorpv/Arduino_STM ... #L339-L344
The value is set to the register here:
https://github.com/victorpv/Arduino_STM ... cm.cpp#L94

I hope seeing the formula to calculate it and the reference manual will make it easier to understand, my code is pretty nasty, specially that file.

stevestrong
Posts: 1812
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by stevestrong » Wed Nov 01, 2017 1:54 pm

Ah, thanks, I got the point about the "repetition counter".
I couldn't find it because I was looking to the general purpose timers, they don't have this feature, only the advanced ones (TIM1 and 8).
This means that you are limited to the TIMER1 compare channel output pins (and the remapped ones). But this is not that critical.

User avatar
RogerClark
Posts: 7422
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by RogerClark » Wed Nov 01, 2017 7:55 pm

Steve

can you briefly explain how the code you posted, is supposed to work ?

From looking at ou code, I think you are using DMA to control the timer PWM.
The DMA sends the values from the array ( which is data from a WAV file)

This appears to change the PWM proportion.

However I dont seem to be getting the resulst I exoected.

If I connect an 16 ohm headphone ( ear bud) via a 330 ohm resistor, I can hear something like the word "hello", but when I look at the soeaker pin with a logic analyser, I see a very strznge waveform, where the falling edige of then output pwm appears to have a 50mhz pulse of square waves.
I think this must be ringing caused by the inductance of the speaker.

The other thing I noticed, is that the values in the wav array, dont seem to have a very wide range.
Are they 8 bit, 16 or 32 bit values ?

I initially thought they were 8 bit, but I need to doible check, as they may be 16 bit.

stevestrong
Posts: 1812
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by stevestrong » Wed Nov 01, 2017 7:59 pm

They are 8 bit values.
And congrats, you solved the quiz :) , it is indeed the hello word being said.

The timer 4 update event triggers the DMA which is writing the wav sample values to the CCR1 register. Thats all.

User avatar
RogerClark
Posts: 7422
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by RogerClark » Wed Nov 01, 2017 8:01 pm

did you normalise the wav file to get max range of 8 bit values?

stevestrong
Posts: 1812
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by stevestrong » Wed Nov 01, 2017 8:05 pm

No. I was happy with the original amplitude which had 80% peek.

User avatar
RogerClark
Posts: 7422
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by RogerClark » Wed Nov 01, 2017 8:08 pm

OK

I'll do some more tests.

User avatar
RogerClark
Posts: 7422
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by RogerClark » Wed Nov 01, 2017 8:16 pm

BTW.

Does the sine table in the code still work?


I tried to enable it, but didn't get a tone

Edit.

Sine table just clicks a bit

I don't think things are working the same for me as they do for you :-(

I'll attach my logic analyser and look at the PWM pin PB6

Edit 2.

I found my piezo was a bit faulty. I tried just using digitalWrite to make a tone and it didnt work very well.

I've found the loose connection inside the piezo and its working a little better, but I think I may need to connect the piezo between Vcc and PB6 rather than ground and PB6 as this may stop the clicking.


I think however that the direct linkage between the wav data sample and the PWM is not ideal, as it needs lots of samples to get good audio. Probably 48kHz or higher would be better.



BTW.

Did you use this to create the data

http://ccgi.cjseymour.plus.com/wavtocode/wavtocode.htm

stevestrong
Posts: 1812
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by stevestrong » Wed Nov 01, 2017 9:14 pm

The sine table should work but its length is really short, more than a click is not hearble. But it can be seen with the scope ;)

The other click is due to audio level sudden jump from steady (low or high) to middle level when it starts playing.
It can be avoided by fading the in and out portions.

Yes, that is the converter. But meanwhile i think it can be generated more easily with HxD (hex editor), open file and save as code.

The audio is of couse better quality when sampled with 48kHz. But this was a quick feasibility test to check quality of short samples which should fit in flash.

Edit
In parallel i am evaluating the tone functions, you probably observed as i pushed a pr. But that is another story.

User avatar
RogerClark
Posts: 7422
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: simple sound player: PWM audio output, with DMA, without timer interrupt

Post by RogerClark » Wed Nov 01, 2017 11:48 pm

Hi Steve

Yes. I saw your PR for the tone library, I need to test before I can merge

One thing I noticed with tone that it didn't work on the pin you are using i.e PB6

I'm not sure why that is.

I think ideally the tone library should work on all pins, even if we have to make it blocking, but thats a different matter.

Post Reply