Skip to main content
Mikas Longbardi
Associate III
July 19, 2017
Question

F4 DMA1 FIFO to CCR1 dont work but to DAC R1 it works?

  • July 19, 2017
  • 8 replies
  • 1133 views
Posted on July 19, 2017 at 23:22

This line work:

DMA1_Stream7->PAR = (uint32_t)&(DAC->DHR8R1); //Destination DACR1

TIM1 CCR1,2,3,4 verified by simple software counter they are ok.

This line dont work:

DMA1_Stream7->PAR = (uint32_t)&(TIM1->CCR1); //Destination TIM1 CCR1

TIM1 CCR1 destination generates TEIF7 (transfer error flag).

Also strange is that FIFO status (FS) is set to 0x4 (0b100 empty) which suggest

there is no data moved into the FIFO first position which a DMA in direct mode

should do.

Can this be a HW bug? Or do i oversee something here? Is this related to the

known F4 FIFO error, if so how to cure it?

Thanks for your time and effort!

/**************** DMA1/Ch3/Stream7 trigged by TIM2 Update Event *****************/

DMA1_Stream7->NDTR = 256;  //Number of DMA transfers

DMA1_Stream7->M0AR = (uint32_t)(sine1);  //MEM0 source is sine1 table, 8bit res.

DMA1_Stream7->PAR = (uint32_t)&(TIM1->CCR1);  //Destination TIM1 CCR1, 8bit res.

DMA1_Stream7->CR |= DMA_CHANNEL_3;  //TIM2 UP or TIM2 Ch4 as DMA requests

DMA1_Stream7->CR |= DMA_SxCR_DIR_0;  //Read from memory to peripheral

DMA1_Stream7->CR |= DMA_SxCR_MINC;  //Memory increment enabled

DMA1_Stream7->CR |= DMA_SxCR_CIRC;  //Circular mode enabled

DMA1_Stream7->CR |= DMA_SxCR_PL;  //Channel Priority level is Very High

DMA1_Stream7->CR |= DMA_SxCR_EN;  //DMA1 stream7 enabled
    This topic has been closed for replies.

    8 replies

    waclawek.jan
    Super User
    July 20, 2017
    Posted on July 20, 2017 at 10:29

    DMA1's peripheral port is hardwired to APB1, thus can't serve anything else than addresses on the APB1. TIM1 is on APB2. See Fig.1 in RM0090.

    JW

    Mikas Longbardi
    Associate III
    July 20, 2017
    Posted on July 20, 2017 at 16:15

    I had' thought' per reference manual RM0390/RM0090 that peripheral DMA

    requests was tied to its specific APB bus while the 'destinations' covered the

    entire 4G adress range qoute:

    ->9.3.7-10.3.6 Source, destination and transfer modes.

    -> Both source and destination transfers can address peripherals and memories in the

    -> entire 4 GB area, at addresses comprised between 0x0000 0000 and 0xFFFF FFFF.

    So TIM2 UP signal as 'DMA request source' should not be limited my 'DMA transfer destination'

    adress e.g TIM1 CCR1 just because it's on a different APB.

    This can be proofed by why TIM8 UP (DMA2) request who is on APB2 can trigger

    a transfer to DAC DHR8R1 who is on APB1. Because im looking at a sine1 on the

    o-scope right now.

    But when i change the destination to TIM1 CCR1 it now reacts but not as it should

    instead saturates the PWM channel one bit below full PW scale!

    The whole thing is very pussling !?

    I testing this on a F446RC Rev A Nucleo who have known issues but none mentions DMA/TIM1.

    /**************** DMA2/Ch7/Stream1 trigged by TIM8 Update Event *****************/

    DMA2_Stream1->NDTR = 256;  //Number of DMA transfers

    DMA2_Stream1->M0AR = (uint32_t)(sine1);  //MEM0 source is sine1

    //DMA2_Stream1->PAR = (uint32_t)&(TIM1->CCR1);  //Destination is TIM1 CCR1, PA8 (saturates PW)

    DMA2_Stream1->PAR = (uint32_t)&(DAC->DHR8R1);  //Destination is DAC 8bit ch1 , PA4 pin

    DMA2_Stream1->CR |= DMA_CHANNEL_7;  //TIM8 UP as DMA requests

    DMA2_Stream1->CR |= DMA_SxCR_DIR_0; //Read from memory to peripheral enabled.

    DMA2_Stream1->CR |= DMA_SxCR_MINC;  //Memory increment enabled.

    DMA2_Stream1->CR |= DMA_SxCR_CIRC;  //Circular mode enabled.

    DMA2_Stream1->CR |= DMA_SxCR_PL;  //Channel Priority level is Very High.

    DMA2_Stream1->CR |= DMA_SxCR_EN;  //DMA2/Ch7/Stream2 enabled.
    waclawek.jan
    Super User
    July 20, 2017
    Posted on July 20, 2017 at 17:02

    Look again at Fig.1 in RM0090: both DMA1 and DMA2 have the memory port (i.e. addressed by DMA_SxM0AR/SxM1AR) connected to the bus matrix, i.e. that port can access all resources where it has a 'dot' on that matrix.

    The peripheral port (addressed by DMA_SxPAR) of DMA1 is connected directly to APB1 and can thus address only registers of APB1 peripherals.

    The peripheral port of DMA2 is split and it can address the whole address range - while the address is within the APB2 address range it accesses APB2 directly; and when it is outside APB2 range it goes through bus matrix.

    This limitation is regardless of the transfer direction, i.e. doesn't matter which port is source and which is destination.

    ->9.3.7-10.3.6 Source, destination and transfer modes.

    -> Both source and destination transfers can address peripherals and memories in the

    -> entire 4 GB area, at addresses comprised between 0x0000 0000 and 0xFFFF FFFF.

    I agree, this is misleading and should be rephrased to reflect the asymmetrical nature of the peripheral/memory ports, and the limitation of the DMA1's peripheral port.

    But when i change the destination to TIM1 CCR1 it now reacts but not as it should

    instead saturates the PWM channel one bit below full PW scale!

    This is probably not related to DMA as such, but to the set of values you are using to drive the PWM - have a look for example at Figure 164. Edge-aligned PWM waveforms (ARR=8) in RM0090 rev.14. Note, that the range of TIMx_CCRy values to achieve full 0 to full 1 output is 0..(TIMx_ARR+1)!

    JW