cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Nucleo board TIM1 stays high after DMA is finished

DAbdi.1
Associate II

I'm using DMA with TIM1 to drive a string of WS2812B LEDs. I am closely following a tutorial called Controlling Neopixels with STM32 on Digikey (I cannot add links due to the age of my account) with some adjustments, with my ARR being 89, my clock being 72MHz, and my code is adjusted to reflect these changes. All of the LEDs in the chain work correctly, except for the first one. The first one is acting as a "passthrough", where all changes I make to it are sent to the next one in sequence and it remains off. For example, when I change LED[0] to fully red, LED[1] receives that change instead and LED[0] remains off. I can confirm that LED[0] is fully functional, as when I connect an Arduino instead of the STM32 the entire chain works perfectly.

 

Using a logic analyzer and looking at the signal, I can see that unlike with the Arduino, the STM32 keeps the pin responsible for the timer high after the DMA is finished, most likely causing the first LED in the sequence to think it's getting a signal and causing it to pass through all data it receives. I have tried activating pull-downs in STM32CUBEIDE, setting the PWM to mode 2, changing the PWM polarity, the PWM idle state, writing the GPIO pin low manually, and some other settings that I do not entirely remember. Unfortunately I cannot get the line to stay low after the DMA is finished. I've attached an image of what I am seeing on the logic analyzer vs what is expected (done with Arduino). How can I set the MCU to set this line low when it's finished transmitting?

 

Apologies for any formatting issues or anything. I am quite new to STM32 and embedded systems in general. Please let me know what I can change to set this line low after the DMA is finished.

 

Thank you


_legacyfs_online_stmicro_images_0693W00000binXoQAI.png

^STM32 signal, please note how the signal remains high after completion.

0693W00000binZQQAY_image.png

^Arduino signal

13 REPLIES 13

https://forum.digikey.com/t/controlling-neopixels-with-stm32/20527 ?

It appears that it finishes with HAL_TIM_PWM_Stop_DMA which disables the timer output, and that goes effectively to high impedance. Now if that pin has a pullup, internal or external, it will remain high.

Read out and post TIM and relevant GPIO registers content after the pulse train ends.

JW

Kamil Duljas
Senior III

Try changing CH POLARITY in timer settings​

Dudo

That is the correct link, yes. There is no pullup configured on the pin internally or externally. Apologies, are you able to direct me to which registers would be relevant in this scenario?

Thank you

DAbdi.1
Associate II

I have tried this and unfortunately it has not changed anything.

Thank you

> are you able to direct me to which registers would be relevant in this scenario

TIM1 registers, and registers of the GPIO module where the TIM1_CHx pin, you are using, is.

JW

SR: 0000001F
CR1: 00000000
CR2: 00000100
SMCR: 00000000
EGR: 00000000
CCMR1: 00000078
CCMR2: 00000000
CCER: 00000002
CNT: 00000004
PSC: 00000000
ARR: 00000059
CCR1: 0000001D
CCR2: 00000000
CCR3: 00000000
CCR4: 00000000
DCR: 00000000
DMAR: 00000000
GPIOA_MODER: A81201A0
GPIOA_OTYPER: 00000000
GPIOA_OSPEEDR: 0C0300F0
GPIOA_PUPDR: 64020000
GPIOA_IDR: 0000A11C
GPIOA_ODR: 00000010
GPIOA_BSRR: 00000000
GPIOA_LCKR: 00000000
GPIOA_AFRL: 40020020

I've read the registers and attached them. This is directly after the call to HAL_TIM_PWM_Stop_DMA. Please let me know if I've missed anything.

Thank you

So, it's PA8 on this board , correct?

You omitted GPIOA_AFRH and TIM1_BDTR... but unless there's something surprising in GPIOA_AFRH (i.e. other than xxxxxxx1), the pin should be not driven from the mcu at this moment. I see in GPIOA_IDR that bit 8 is indeed 1, but that is probably driven from outside, i.e. from your LED string or anything else attached to that pin.

JW

The board I am using is the STM32 F411RE Nucleo board (Not the one imaged, and due to my account being new I am unable to add a link unfortunately). The AFRL that I showed in the post is actually just the entire AFR register, I made a typo and added the L at the end by mistake. I am unable to add the TIM1_BDTR at the moment but will do so tomorrow when I am able. I don't think that anything from outside is driving GPIOA_IDR, as I don't think the WS2812B is capable of outputting any voltage on the DIN pin. Do you have any guidance as to what I should do to drive PA8 low after the DMA transfer is complete?

Thank you

> The AFRL that I showed in the post is actually just the entire AFR register

AFR consists of *two* 32-bit registers, sometimes marked as AFRL and AFRH.

> F411RE Nucleo

Okay, that was partially my confusion, sorry.

> TIM1_BDTR

That shouldn't change anything.

I have no more ideas, sorry.

JW