2024-02-26 09:37 AM - edited 2024-02-26 10:13 AM
Hi everyone,
I'm encountering a problem with PWM generation using timers and DMA on the STM32F723.
I've worked through some examples from ST and Controllerstech, such as this one:
https://controllerstech.com/pwm-with-dma-in-stm32/
I managed to get this example running, but now I need to develop something more advanced.
We want to develop a protocol called XY2-100. Here's a description of the protocol:
https://dvd.ilphotonics.com/Ray-Motion%20-%20galvanometers%20-%201D-2D-3D%20scanners/Motion%20Control%20-%20Optomechanics/Interface%20XY2-100.pdf
The protocol consists of four signals: Clock, ChannelX, ChannelY, Sync.
We would like to generate these signals as efficiently as possible. Thus, I attempted to implement these signals using the same Timer 3. Here's how the "pseudocode" looks:
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1,(uint32_t *)dataClk, 20);
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_2,(uint32_t *)dataSync, 20);
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_3,(uint32_t *)dataX, 20);
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_4,(uint32_t *)dataY, 20);
Initially, I successfully generated the clock of 2MHz with the following function:
void startScannerClk(void){
TIM3->CCR3 = 27;
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
}
Then, I attempted to try this function:
void send_Scanner_CHX(void){
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_3,(uint32_t *)chx_buf, 32);
HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_4,(uint32_t *)chy_buf, 32);
}
The chx_buf and chy_buf contain the same data and are initialized like this:
#define DMA_Scanner_BUFFER_SIZE 50
uint16_t chx_buf[DMA_Scanner_BUFFER_SIZE];
uint16_t chy_buf[DMA_Scanner_BUFFER_SIZE];
I observed these signals:: red TIM_CHANNEL_3; blue TIM_CHANNEL_4
The clock of 20 periods, which is what is stored in chx_buf, works perfectly and the channel_4 generates the same signals but it starts around 2ns later, which would be a problem.
So my questions are:
Best regards, Corsin
2024-02-26 10:21 AM
For serial protocol, why don't you use a peripheral intended for serial protocols, such as SPI and SAI?
JW
2024-02-26 11:24 AM
Yeah, No
If you want to generate complex patterns, use a pattern buffer with all the pins you want to manipulate synchronously.
Have them on the same GPIO bank, and DMA the patterns to GPIO->BSRR or GPIO->ODR (if all 16 pins on the bank). Use the clock to generate the time base, and use that to trigger the DMA (memory-to-memory)
2024-02-26 11:00 PM
Hi @waclawek.jan ,
There is no peripheral which would fit the XY2-100 protocol.
CO
2024-02-26 11:02 PM
Thank you for your response.
I've never used a pattern buffer before. Do you have an example in mind that you could share?
Best regards, Corsin
2024-02-27 03:31 AM
Hi Corsin,
> There is no peripheral which would fit the XY2-100 protocol.
Why do you think so?
You can use two SPIs clocked from a timer connected externally (wich would generate the "index" pulse) set to 10 bits.
SAI is most probably flexible enough to generate the entire set of signals itself.
The advantage of this solution is, that the SPI/SAI provides the deserialization, so there is significantly less processing needed from the processor.
The drawback is, that there's no ready-made Cube/CubeMX support for these.
JW