Now in this example, we going to configure DMAMUX to use another request to activate the DMA transaction, the multiplexer allows configuring multiple trigger requests to the DMA channel.

Using a timer configured to generate a PWM signal and DMA to change the duty cycle as the last example, now the DMAMUX is configured to trigger a DMA request when a button is pressed, this means that the DMAMUX is waiting for an external interrupt to send the request. When the button is pressed the LED intensity connected to the PWM signal must change intensity, buffer declared contain the values from 0 to 90 percent to change the brightness.

The DMAMUX is configured to detect the external interrupt in the rising edge of the signal event. HAL_DMAEx_ConfigMuxSync() function allows connection between the multiplexor and the DMA channel desired.

#include "bsp.h"
#include <stdio.h>

#define PWM_DATA 10                     /* Size of the buffer */

DMA_HandleTypeDef DMAH;                 /* Handler to config DMA                        */
HAL_DMA_MuxSyncConfigTypeDef pSyncConfig;/*DMA mux handler*/

TIM_HandleTypeDef TimHandle;            /* Handler to config timer of PWM               */
TIM_OC_InitTypeDef sConfig;             /* Handler to control PWM Channel               */
TIM_MasterConfigTypeDef sMasterConfig;  /* Handler to configure trigger to activate DMA */

/* Buffer that contain duty cycle of the PWM signal */
uint32_t PWMdata[ PWM_DATA ] = 
{
    0, 10, 20, 30, 40, 50, 60, 70, 80, 90
};

int main(void)
{
    HAL_Init();  /* Initilize HAL library */

    /*DMA and DMA Multiplexor configuration*/
    DMAH.Instance       = DMA1_Channel4;                    /* Configure DMA1 and channel 4                        */
    DMAH.Init.Request   = DMA_REQUEST_TIM2_CH4;             /* Configure request of the PWM signal                 */
    DMAH.Init.Direction = DMA_MEMORY_TO_PERIPH;             /* DMA direction from memory to peripheral (RAM to PWM)*/
    DMAH.Init.MemInc    = DMA_MINC_ENABLE;                  /* Increment mem address enable                        */
    DMAH.Init.PeriphInc = DMA_PINC_DISABLE;                 /* Increment perph address disable                     */
    DMAH.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;    /* Word size configured to transmit data               */
    DMAH.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;    /* Word size configured to transmit data               */
    DMAH.Init.Mode      = DMA_CIRCULAR;                     /* DMA in circular mode to repeat the process          */
    DMAH.Init.Priority  = DMA_PRIORITY_LOW;                 /* LOW priority selected                               */
    HAL_DMA_Init( &DMAH );

    pSyncConfig.SyncSignalID = HAL_DMAMUX1_SYNC_EXTI7;      /* Send DMA request with External Interrupt 7 (pin B7) */
    pSyncConfig.SyncPolarity = HAL_DMAMUX_SYNC_RISING;      /* Send DMA request with the rising edge of signal     */
    pSyncConfig.SyncEnable = ENABLE;                        /* Synchronization enable                              */
    pSyncConfig.EventEnable = DISABLE;                      /* Generation of event disable                         */
    pSyncConfig.RequestNumber = 1;                          /* Number of request of DMAMUX                         */
    HAL_DMAEx_ConfigMuxSync( &DMAH, &pSyncConfig );

    __HAL_LINKDMA( &TimHandle, hdma[TIM_DMA_ID_CC4], DMAH ); /* Set the link between signal of timer and DMA to the request */

    /* DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn interrupt configuration */
    HAL_NVIC_SetPriority( DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn, 2, 0 );
    HAL_NVIC_EnableIRQ( DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQn );

    /*Timer TIm2 CH4 configuration to ouput PWM signal*/
    TimHandle.Instance           = TIM2;                    /* Tim 2 selected to use as PWM signal generator */
    TimHandle.Init.Prescaler     = 615;                     /* Selection of prescaler                        */
    TimHandle.Init.Period        = 100;                     /* Selection of Period                           */
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;      /* Counter Up mode                               */
    HAL_TIM_PWM_Init( &TimHandle );

    sConfig.OCMode     = TIM_OCMODE_PWM1;                             /* Specifies Tim2 mode as PWM1       */
    sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;                         /* Set Output polarity in high       */
    sConfig.OCFastMode = TIM_OCFAST_DISABLE;                          /* Output compare disabled           */
    sConfig.Pulse      = 0;                                           /* Duty cycle by default set as 0%   */
    HAL_TIM_PWM_ConfigChannel( &TimHandle, &sConfig, TIM_CHANNEL_4 ); /* Initialize PWM channel on timer 2 */
    
    sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;                 /* Set trigger event           */
    sMasterConfig.MasterSlaveMode     = TIM_MASTERSLAVEMODE_DISABLE;    /* Master / Slave mode disable */
    HAL_TIMEx_MasterConfigSynchronization( &TimHandle, &sMasterConfig );

    /* Init transaction to periph, but this is only happens until the button has been pressed */
    HAL_TIM_PWM_Start_DMA( &TimHandle, TIM_CHANNEL_4, (uint32_t*)&PWMdata, PWM_DATA );  

    while(1)
    {
    }
}

msps.c

void HAL_MspInit( void )
{
    GPIO_InitTypeDef   GPIO_InitStruct;

    __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA1 clock enable  */
    __TIM2_CLK_ENABLE();         /* TIM2 clock enable  */
    __GPIOC_CLK_ENABLE();        /* PortC clock enable */
    __GPIOB_CLK_ENABLE();        /* PortB clock enable */

    GPIO_InitStruct.Pin = GPIO_PIN_7;               /* pin C7 selection                    */
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;         /* configure Alternate function of pin */
    GPIO_InitStruct.Pull = GPIO_PULLUP;             /* configured as Pull up               */
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;   /* GPIO speed high                     */
    GPIO_InitStruct.Alternate = GPIO_AF2_TIM2;      /* Tim2 connected to pin               */
    HAL_GPIO_Init( GPIOC, &GPIO_InitStruct );

    GPIO_InitStruct.Pin = GPIO_PIN_7;               /* pin B7 selection                    */
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;     /* configure Alternate function of pin */
    GPIO_InitStruct.Pull = GPIO_NOPULL;             /* configured as Pull up               */
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;   /* GPIO speed high                     */
    HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );

    /*We need to acivate the interrupt on Pin 7, thi IRQ will be redirected tyo DMA Mux instead of 
    the CPU, that is why you are going to see its corresponding ISR in the code*/
    HAL_NVIC_SetPriority( EXTI4_15_IRQn, 2, 0 );      /* set the priority level of interruption    */
    HAL_NVIC_EnableIRQ( EXTI4_15_IRQn );              /* enable the external interrrupt for button */
}

ints.c

extern DMA_HandleTypeDef DMAH; 

/*DM multiplexor interrupt ctivated when the button is pressed*/
void DMA1_Ch4_7_DMA2_Ch1_5_DMAMUX1_OVR_IRQHandler( void )
{
    HAL_DMAEx_MUX_IRQHandler( &DMAH );
}