2013-02-14 03:37 AM
Hello,
I'd like to know if it is possible to play sound files in DPCM with a reasonnable quality (understanding human voice is enough) with the following configuration :- with a standard low quality piezo buzzer,- with PWM (TIMER8 on channel 3) input without a low pass filter (if the frequency of the PWM is enough high perhaps ?)- by reading low resolution data (8000 Hz / 8 bits data samples) stored in flash memory, with DMA loading at 8000 Hz ?I presume I have to set a PWM frequency by a multiple of 8000 Hz + repetition counter to inform DMA it have to load a new data in TIM8->CCR3 every 1/8000 sec: but what would be the DMA event I have to configure to do that ?Is it possible to inform DMA from the number of data samples to load (sound duration) in such a configuration, in order to stop the readings at the end of the data samples ?Last question : do you know any existing software to format wave files to DPCM, or I'll need to write my own ?Thanks a lot, in advance ;)2013-02-14 03:52 AM
You should be able to use a TIM/DMA combination to pace the transfer to another timer's CCRx register, which would work in a similar fashion to one outputting to the DAC, etc.
Using non-circular DMA mode you specify the transfer length as a 16-bit transfer count (8/16/32 bit units)2013-02-14 04:28 AM
Thank you for your quick answer Clive,
So the following configuration should work as expected ?//////// my main clock is at 160 MHz, so for TIM8 : 80Mhz/250 = 320KHz (should be enough without low pass ?)
//////// 320KHz / 8000 Hz data samples = 40 (repetition counter) -> then TIM8_UP DMA event every 1/8000 sec -> new DMA transfer ? is that ok ?
TIM_TimeBaseStructure.TIM_Period = 250;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 40;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
/* PWM Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; /// TIM_OCIdleState_Set;
TIM_OC3Init(TIM8, &TIM_OCInitStructure);
TIM_ARRPreloadConfig(TIM8, ENABLE);
DMA_InitStructure.DMA_Channel = DMA_Channel_7; /// TIM8_UP
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM8->CCR3);
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /// stored in 8 bits, with maximum value at 249 (need to write my own converter I believe, with ffmepg)
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_BufferSize = Data_samples_Number; /// length of sound file
DMA_Init(DMA2_Stream1, &DMA_InitStructure); /// TIM8_UP
DMA_Cmd(DMA2_Stream1, ENABLE); /// TIM8_UP
TIM_ITConfig(TIM8, TIM_FLAG_Update, DISABLE); // DMA in charge
WithDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord because CCR3 is 16 bits long, is that what you mean ?
Tx again
2013-02-14 09:31 AM
250 - 1 for the period. Repetition might be N-1 too, not played with.
You might need to fill out the TIM and DMA structures more completely. TIM8 might need PWM Enable. TIM8_UP, DMA2, Channel 7, Stream 1. Check DMA needs increment fields, etc.2013-02-14 11:32 AM
Ok, tx for pointing the index error,
It was pseudocode, so there is still code to add, that's true.I can't test it at the moment, because I have to produce DPCM data first...But I will do it soonTx again Clive