/**
  * @brief  Initialize the DMA according to the specified
  *         parameters in the DMA_InitTypeDef and initialize the associated handle.
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Channel.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
{
  uint32_t tmp = 0;

  /* Check the DMA handle allocation */
  if(hdma == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
  assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
  assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
  assert_param(IS_DMA_MODE(hdma->Init.Mode));
  assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
  if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
  {
    assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
  }
  
  if(hdma->State == HAL_DMA_STATE_RESET)
  {  
    /* Allocate lock resource and initialize it */
    hdma->Lock = HAL_UNLOCKED;
  }

  /* Change DMA peripheral state */
  hdma->State = HAL_DMA_STATE_BUSY;

  /* Get the CR register value */
  tmp = hdma->Instance->CCR;

  /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
  tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  | \
                      DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   | \
                      DMA_CCR_DIR));

  /* Prepare the DMA Channel configuration */
  tmp |=  hdma->Init.Direction        |
          hdma->Init.PeriphInc           | hdma->Init.MemInc           |
          hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
          hdma->Init.Mode                | hdma->Init.Priority;

  /* Write to DMA Channel CR register */
  hdma->Instance->CCR = tmp;

  /* Set request selection */
  if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
  {
    /* Write to DMA channel selection register */
    if (hdma->Instance == DMA1_Channel1)
    {
      /*Reset request selection for DMA1 Channel1*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S;

      /* Configure request selection for DMA1 Channel1 */
      DMA1_CSELR->CSELR |= hdma->Init.Request;
    }
    else if (hdma->Instance == DMA1_Channel2)
    {
      /*Reset request selection for DMA1 Channel2*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S;

      /* Configure request selection for DMA1 Channel2 */
      DMA1_CSELR->CSELR |= (uint32_t)(hdma->Init.Request << 4);
    }
    else if (hdma->Instance == DMA1_Channel3)
    {
      /*Reset request selection for DMA1 Channel3*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S;

      /* Configure request selection for DMA1 Channel3 */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 8);
    }
    else if (hdma->Instance == DMA1_Channel4)
    {
      /*Reset request selection for DMA1 Channel4*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C4S;

      /* Configure request selection for DMA1 Channel4 */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 12);
    }
    else if (hdma->Instance == DMA1_Channel5)
    {
      /*Reset request selection for DMA1 Channel5*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C5S;

      /* Configure request selection for DMA1 Channel5 */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 16);
    }
    else if (hdma->Instance == DMA1_Channel6)
    {
      /*Reset request selection for DMA1 Channel6*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C6S;

      /* Configure request selection for DMA1 Channel6 */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 20);
    }
    else if (hdma->Instance == DMA1_Channel7)
    {
      /*Reset request selection for DMA1 Channel7*/
      DMA1_CSELR->CSELR &= ~DMA_CSELR_C7S;

      /* Configure request selection for DMA1 Channel7 */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 24);
    }
    else if (hdma->Instance == DMA2_Channel1)
    {
      /*Reset request selection for DMA2 Channel1*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C1S;

      /* Configure request selection for DMA2 Channel1 */
      DMA2_CSELR->CSELR |= hdma->Init.Request;
    }
    else if (hdma->Instance == DMA2_Channel2)
    {
      /*Reset request selection for DMA2 Channel2*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C2S;

      /* Configure request selection for DMA2 Channel2 */
      DMA2_CSELR->CSELR |= (uint32_t)(hdma->Init.Request << 4);
    }
    else if (hdma->Instance == DMA2_Channel3)
    {
      /*Reset request selection for DMA2 Channel3*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C3S;

      /* Configure request selection for DMA2 Channel3 */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 8);
    }
    else if (hdma->Instance == DMA2_Channel4)
    {
      /*Reset request selection for DMA2 Channel4*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C4S;

      /* Configure request selection for DMA2 Channel4 */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 12);
    }
    else if (hdma->Instance == DMA2_Channel5)
    {
      /*Reset request selection for DMA2 Channel5*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C5S;

      /* Configure request selection for DMA2 Channel5 */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 16);
    }
    else if (hdma->Instance == DMA2_Channel6)
    {
      /*Reset request selection for DMA2 Channel6*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C6S;

      /* Configure request selection for DMA2 Channel6 */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 20);
    }
    else if (hdma->Instance == DMA2_Channel7)
    {
      /*Reset request selection for DMA2 Channel7*/
      DMA2_CSELR->CSELR &= ~DMA_CSELR_C7S;

      /* Configure request selection for DMA2 Channel7 */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << 24);
    }
  }

  /* Initialize the error code */
  hdma->ErrorCode = HAL_DMA_ERROR_NONE;

  /* Initialize the DMA state*/
  hdma->State  = HAL_DMA_STATE_READY;

  return HAL_OK;
}
Beispiel #2
0
/**
  * @brief  Initialize the DMA according to the specified
  *         parameters in the DMA_InitTypeDef and initialize the associated handle.
  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Channel.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
{
  uint32_t tmp = 0;
  
  /* Check the DMA handle allocation */
  if(hdma == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
  assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
  assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
  assert_param(IS_DMA_MODE(hdma->Init.Mode));
  assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
  if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
  {
    assert_param(IS_DMA_ALL_REQUEST(hdma->Init.Request));
  }
  
  /* calculation of the channel index */
  if ((uint32_t)(hdma->Instance) < (uint32_t)(DMA2_Channel1))
  {
    /* DMA1 */
    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
    hdma->DmaBaseAddress = DMA1;
  }
  else 
  {
    /* DMA2 */
    hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA2_Channel1) / ((uint32_t)DMA2_Channel2 - (uint32_t)DMA2_Channel1)) << 2;
    hdma->DmaBaseAddress = DMA2;
  }
    
  /* Change DMA peripheral state */
  hdma->State = HAL_DMA_STATE_BUSY;

  /* Get the CR register value */
  tmp = hdma->Instance->CCR;

  /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
  tmp &= ((uint32_t)~(DMA_CCR_PL    | DMA_CCR_MSIZE  | DMA_CCR_PSIZE  | \
                      DMA_CCR_MINC  | DMA_CCR_PINC   | DMA_CCR_CIRC   | \
                      DMA_CCR_DIR));

  /* Prepare the DMA Channel configuration */
  tmp |=  hdma->Init.Direction        |
          hdma->Init.PeriphInc           | hdma->Init.MemInc           |
          hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
          hdma->Init.Mode                | hdma->Init.Priority;

  /* Write to DMA Channel CR register */
  hdma->Instance->CCR = tmp;

  /* Set request selection */
  if(hdma->Init.Direction != DMA_MEMORY_TO_MEMORY)
  {
    /* Write to DMA channel selection register */
    if (DMA1 == hdma->DmaBaseAddress)
    {
      /* Reset request selection for DMA1 Channelx */
      DMA1_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);

      /* Configure request selection for DMA1 Channelx */
      DMA1_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex)); 
    }
    else /* DMA2 */
    {
      /* Reset request selection for DMA2 Channelx */
      DMA2_CSELR->CSELR &= ~(DMA_CSELR_C1S << hdma->ChannelIndex);
     
      /* Configure request selection for DMA2 Channelx */
      DMA2_CSELR->CSELR |= (uint32_t) (hdma->Init.Request << (hdma->ChannelIndex)); 
    }
  }

  /* Clean callbacks */
  hdma->XferCpltCallback = NULL;
  hdma->XferHalfCpltCallback = NULL;
  hdma->XferErrorCallback = NULL;
  hdma->XferAbortCallback = NULL;

  /* Initialise the error code */
  hdma->ErrorCode = HAL_DMA_ERROR_NONE;

  /* Initialize the DMA state*/
  hdma->State  = HAL_DMA_STATE_READY;

  /* Allocate lock resource and initialize it */
  hdma->Lock = HAL_UNLOCKED;
  
  return HAL_OK;
}