Page 1 of 1

Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 12:33 pm
by Mangy_Dog
I need a timer to trigger very regular DMA transfers for a softPWM implementation...

Which timer is safe to use, and wont conflict with other core components?

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 2:05 pm
by ag123
I think timer 2,3,5 are 'normal' ones, and Timer 1 is the 'advanced' one. They work pretty much the same though.
Timer 2,3,5 as I find are 'adequate'. If you aren't using any of them for any particular purpose, you could even just use Timer1
For STM core, messing with dma may take messing with registers or HAL, just my guess.

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 3:42 pm
by Mangy_Dog
Not quite working yet... but written this so far. the //digitalWrite(PB5, HIGH); is just for quick dirty checking to see where its getting to in the code.
Its getting into send DMA but im not seeing any led fading effect yet.

Code: Select all

#include "softPwm.h"
#include <libmaple/dma.h>

#define stepDutyCount 100

uint16_t dataA[stepDutyCount];
uint16_t dataB[stepDutyCount];
//uint16_t dataC[stepDutyCount];
uint8_t step = 0;

static HardwareTimer TimerPWM(1);

void sendDMA()
    {
//digitalWrite(PB5, HIGH);
    dma_setup_transfer(DMA1, DMA_CH0, &GPIOA->regs->ODR, DMA_SIZE_16BITS, &dataA[step], DMA_SIZE_16BITS, DMA_FROM_MEM);
    dma_setup_transfer(DMA1, DMA_CH1, &GPIOB->regs->ODR, DMA_SIZE_16BITS, &dataB[step], DMA_SIZE_16BITS, DMA_FROM_MEM);
  //  dma_setup_transfer(DMA1, DMA_CH2, &GPIOC->regs->ODR, DMA_SIZE_16BITS, &dataC[step], DMA_SIZE_16BITS, DMA_FROM_MEM);

    dma_set_priority(DMA1, DMA_CH1, DMA_PRIORITY_VERY_HIGH);
    dma_set_priority(DMA1, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
    //dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);

    dma_enable(DMA1, DMA_CH0);
    dma_enable(DMA1, DMA_CH1);
   // dma_enable(DMA1, DMA_CH2);

    step++;
    if (step >= stepDutyCount)
	step = 0;

    }

void initPWM()
    {

    TimerPWM.setPrescaleFactor(100);
    TimerPWM.setOverflow(480);
    TimerPWM.attachInterrupt(1, sendDMA);
    TimerPWM.resume();
    dma_init(DMA1);

    }

void setSoftPWM(uint8 p, uint8_t value)
    {



    for(int i = 0 ; i<100 ; i ++)
	{
	if(i<value)
	    {
	    if(p<16)
	    dataA[i] |= 1UL << p ;

	    if(p>=16 && p < 32)
	    dataB[i] |= 1UL << (p-16) ;



	    }
	else
	    {
	    if(p<16)
	    dataA[i] &= ~(1UL << p);

	    if(p>=16 && p < 32)
	    dataB[i] &= ~(1UL << p-16);



	    }
	}


    }

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 4:10 pm
by ag123
I've tried some timer and DMA stuff
(yet another) SUMP compatible logic analyzer board for STM32duino (steve's libmaple core) - stm32f401cc pill board
viewtopic.php?f=10&t=116
https://github.com/ag88/SumpSTM32F401cc
unfortunately, it is for libmaple - roger's or more correctly steve's core. on stm32f401
steeve's core with dma on stm32f401 is very fast
https://www.youtube.com/watch?v=7Ey1U36YtY0
^ note delays is inserted in this video so that you can see each test, otherwise it is simply a blur and it probably can stream videos on ILI9341

i've not really 'get hands dirty' working dma in stm core. I'd guess HAL etc is probably a way to go.

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 6:00 pm
by Mangy_Dog
I dont think my DMA is actually DMAing...

Am i triggering it wrong?

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 6:28 pm
by Bakisha
I was experiment with DMA to ODR, but with official core, and directly with registers.
From what i understand, on bluepill, you can only use DMA1 to send either PortA or PortB, not both.
In your example,

Code: Select all

    dma_setup_transfer(DMA1, DMA_CH0, &GPIOA->regs->ODR, DMA_SIZE_16BITS, &dataA[step], DMA_SIZE_16BITS, DMA_FROM_MEM);
    dma_setup_transfer(DMA1, DMA_CH1, &GPIOB->regs->ODR, DMA_SIZE_16BITS, &dataB[step], DMA_SIZE_16BITS, DMA_FROM_MEM);
bottom line will set DMA to use DMA_CH1, and use dataB[] as source. Simply because it is after first line (where you setup DMA_CH0 and dataA[]).

And, in you example, interrupt is triggered in same time as DMA is sending dataB[0] (since they are on same timer), and you keep resetting to again send dataB[0] again.

IMHO, as i don't think bluepill have DMA2, just use interrupt on any timer. It is not time critical (since interrupt is every 666.67 microseconds) and use GPIOA->regs->ODR and GPIOB->regs->ODR inside of it.

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 6:45 pm
by Mangy_Dog
I should point out its not a blue pill. A custom f103C6 board.

Re: Real quicky, Which timer is safe to use?

Posted: Thu Oct 06, 2022 7:01 pm
by Bakisha
Almoust as bluepill. Your board just don't have Timer4 compared to bluepill. But RM0008 apply to your board too.
I am not familiar wirh Roger's core DMA syntax, but i'm pritty sure there must some command to set lenght of DMA transfers ( for CNDTR register).