예제 #1
0
static void dma_irq(DMAName name, int id, SerialIrq txrxirq)
{

  if (serial_irq_ids[id] != 0) {
    if (txrxirq == RxIrq) {
      if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
            irq_handler(serial_irq_ids[id], RxIrq);
            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF2_6);
        }
    } else {
      if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
            irq_handler(serial_irq_ids[id], TxIrq);
            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF0_4);
        }
    }    
  }
    DmaHandle.Instance = (DMA_Stream_TypeDef *)name;
    if (serial_irq_ids[id] != 0) {
        if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
            irq_handler(serial_irq_ids[id], TxIrq);
            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF0_4);
        }
        if (__HAL_DMA_GET_TC_FLAG_INDEX(&DmaHandle) != RESET) {
            irq_handler(serial_irq_ids[id], RxIrq);
            __HAL_DMA_CLEAR_FLAG(&DmaHandle, DMA_FLAG_TCIF2_6);
        }
    }
}
예제 #2
0
/**
  * @brief  DeInitializes the DMA peripheral
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Stream.
  * @retval HAL status
  */
static HAL_StatusTypeDef _HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
{
  /* Check the DMA peripheral state */
  if(hdma == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the DMA peripheral state */
  if(hdma->State == HAL_DMA_STATE_BUSY)
  {
     return HAL_ERROR;
  }

  /* Disable the selected DMA Streamx */
  __HAL_DMA_DISABLE(hdma);

  /* Reset DMA Streamx control register */
  hdma->Instance->CR   = 0;

  /* Reset DMA Streamx number of data to transfer register */
  hdma->Instance->NDTR = 0;

  /* Reset DMA Streamx peripheral address register */
  hdma->Instance->PAR  = 0;

  /* Reset DMA Streamx memory 0 address register */
  hdma->Instance->M0AR = 0;

  /* Reset DMA Streamx memory 1 address register */
  hdma->Instance->M1AR = 0;

  /* Reset DMA Streamx FIFO control register */
  hdma->Instance->FCR  = (uint32_t)0x00000021;

  /* Clear all flags */
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

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

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

  /* Release Lock */
  __HAL_UNLOCK(hdma);

  return HAL_OK;
}
예제 #3
0
/**
  * @brief  DeInitializes the DMA peripheral 
  * @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_DeInit(DMA_HandleTypeDef *hdma)
{
  /* Check the DMA handle allocation */
  if(hdma == NULL)
  {
    return HAL_ERROR;
  }
  
  /* Check the parameters */
  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));

  /* Check the DMA peripheral state */
  if(hdma->State == HAL_DMA_STATE_BUSY)
  {
     return HAL_ERROR;
  }

  /* Disable the selected DMA Channelx */
  __HAL_DMA_DISABLE(hdma);
  
  /* Reset DMA Channel control register */
  hdma->Instance->CCR  = 0;
  
  /* Reset DMA Channel Number of Data to Transfer register */
  hdma->Instance->CNDTR = 0;
  
  /* Reset DMA Channel peripheral address register */
  hdma->Instance->CPAR  = 0;
  
  /* Reset DMA Channel memory address register */
  hdma->Instance->CMAR = 0;

  /* Clear all flags */
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
  
  /* Initialize the error code */
  hdma->ErrorCode = HAL_DMA_ERROR_NONE;

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

  /* Release Lock */
  __HAL_UNLOCK(hdma);

  return HAL_OK;
}
예제 #4
0
/**
* @brief  串口 DMA 发送接口
* @param  huart      : 串口句柄
* @param  pData      : 数据指针
* @param  Size       : 数据长度
* @param  tx_tc_flag : 发送完成 flag 偏移
* @retval None
*/
HAL_StatusTypeDef USER_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, u32 tx_tc_flag)
{
    if(__HAL_DMA_GET_FLAG(huart->hdmatx, tx_tc_flag))
    {
        if(huart->State == HAL_UART_STATE_BUSY_TX_RX)
        {
            huart->State = HAL_UART_STATE_BUSY_TX;
        }
        else
        {
            huart->State = HAL_UART_STATE_READY;
        }
        
        __HAL_UNLOCK(huart->hdmatx);
        __HAL_DMA_CLEAR_FLAG(huart->hdmatx, tx_tc_flag);
    }
    return HAL_UART_Transmit_DMA(huart, pData, Size);
}
/**
 * @brief  Manage the SPI transmit
 * @param  TransmitRequest: the transmit request
 * @retval None
 */
static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest)
{
  /*
   *  Disable both DMA
   */
  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
  __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
  
  __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Disable Receive packet notification */
  
  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); /**< Clear flag in DMA */
	HAL_NVIC_ClearPendingIRQ(BNRG_SPI_DMA_TX_IRQn); /**< Clear DMA pending bit in NVIC */
  __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC);	/**< Enable Transmit packet notification */
  
  __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
  
  switch (TransmitRequest)
  {
  case SPI_HEADER_TRANSMIT:
    SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_HEADER_TRANSMITTED;
    
#ifdef ENABLE_SPI_FIX
    set_irq_as_input();
#endif
    
    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.header_size); /**< Set counter in DMA TX */
    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.header_data); /**< Set memory address in DMA TX */
    break;
    
  case SPI_PAYLOAD_TRANSMIT:
    SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_PAYLOAD_TRANSMITTED;
    
    __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.payload_size_to_transmit); /**< Set counter in DMA TX */
    __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.payload_data); /**< Set memory address in DMA TX */
    break;
    
  default:
    break;
  }
  
  __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); /**< Enable DMA TX */
  
}
/**
  * @brief  Aborts the DMA Transfer in Interrupt mode.
  * @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_Abort_IT(DMA_HandleTypeDef *hdma)
{  
  HAL_StatusTypeDef status = HAL_OK;
  
  if(HAL_DMA_STATE_BUSY != hdma->State)
  {
    /* no transfer ongoing */
    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
        
    status = HAL_ERROR;
  }
  else
  { 
    /* Disable DMA IT */
    __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));

    /* Disable the channel */
    __HAL_DMA_DISABLE(hdma);

    /* Clear all flags */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));

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

    /* Process Unlocked */
    __HAL_UNLOCK(hdma);

    /* Call User Abort callback */
    if(hdma->XferAbortCallback != NULL)
    {
      hdma->XferAbortCallback(hdma);
    } 
  }
  return status;
}
/**
 * @brief  Tx and Rx Transfer completed callbacks
 * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
 *               the configuration information for SPI module.
 * @retval None
 */
void BlueNRG_DMA_TxCallback(void)
{
  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
  
  switch (SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event)
  {
  case SPI_HEADER_TRANSMITTED:
    if(SPI_Context.SPI_Transmit_Context.payload_size_to_transmit != 0)
    {
      SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
    }
    else
    {
      TransmitClosure();
    }
    break;
    
  case SPI_PAYLOAD_TRANSMITTED:
    if( (SPI_Context.SPI_Transmit_Context.packet_cont == TRUE) && (SPI_Context.SPI_Transmit_Context.payload_size != 0))
    {
      SPI_Context.SPI_Transmit_Context.payload_data += SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
      DisableEnable_SPI_CS();
      SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);
    }
    else
    {
      TransmitClosure();
    }
    break;
    
  default:
    break;
  }
  
  return;
}
/**
  * @brief  Handles DMA interrupt request.
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Channel.  
  * @retval None
  */
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
  uint32_t flag_it = hdma->DmaBaseAddress->ISR;
  uint32_t source_it = hdma->Instance->CCR;
  
  /* Half Transfer Complete Interrupt management ******************************/
  if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
  {
    /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
    if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
    {
      /* Disable the half transfer interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
    }
    /* Clear the half transfer complete flag */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

    /* DMA peripheral state is not updated in Half Transfer */
    /* but in Transfer Complete case */

    if(hdma->XferHalfCpltCallback != NULL)
    {
      /* Half transfer callback */
      hdma->XferHalfCpltCallback(hdma);
    }
  }

  /* Transfer Complete Interrupt management ***********************************/
  else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
  {
    if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
    {
      /* Disable the transfer complete and error interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);  

      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_READY;
    }
    /* Clear the transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

    /* Process Unlocked */
    __HAL_UNLOCK(hdma);

    if(hdma->XferCpltCallback != NULL)
    {
      /* Transfer complete callback */
      hdma->XferCpltCallback(hdma);
    }
  }

  /* Transfer Error Interrupt management **************************************/
  else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
  {
    /* When a DMA transfer error occurs */
    /* A hardware clear of its EN bits is performed */
    /* Disable ALL DMA IT */
    __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));

    /* Clear all flags */
    hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);

    /* Update error code */
    hdma->ErrorCode = HAL_DMA_ERROR_TE;

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

    /* Process Unlocked */
    __HAL_UNLOCK(hdma);

    if (hdma->XferErrorCallback != NULL)
    {
      /* Transfer error callback */
      hdma->XferErrorCallback(hdma);
    }
  }
  return;
}
/**
  * @brief  Polling for transfer complete.
  * @param  hdma:    pointer to a DMA_HandleTypeDef structure that contains
  *                  the configuration information for the specified DMA Channel.
  * @param  CompleteLevel: Specifies the DMA level complete.
  * @param  Timeout:       Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
{
  uint32_t temp;
  uint32_t tickstart = 0U;

  if(HAL_DMA_STATE_BUSY != hdma->State)
  {
    /* no transfer ongoing */
    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
    __HAL_UNLOCK(hdma);
    return HAL_ERROR;
  }

  /* Polling mode not supported in circular mode */
  if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
  {
    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
    return HAL_ERROR;
  }
  
  /* Get the level transfer complete flag */
  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Transfer Complete flag */
    temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
  }
  else
  {
    /* Half Transfer Complete flag */
    temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
  }

  /* Get tick */
  tickstart = HAL_GetTick();

  while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
  {
    if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
    {
      /* When a DMA transfer error occurs */
      /* A hardware clear of its EN bits is performed */
      /* Clear all flags */
      hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);

      /* Update error code */
      SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);

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

      /* Process Unlocked */
      __HAL_UNLOCK(hdma);

      return HAL_ERROR;
    }
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
      {
        /* Update error code */
        SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);

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

        /* Process Unlocked */
        __HAL_UNLOCK(hdma);

        return HAL_ERROR;
      }
    }
  }

  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Clear the transfer complete flag */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

    /* The selected Channelx EN bit is cleared (DMA is disabled and
    all transfers are complete) */
    hdma->State = HAL_DMA_STATE_READY;
  }
  else
  {
    /* Clear the half transfer complete flag */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdma);

  return HAL_OK;
}
예제 #10
0
/**
  * @brief  Handles DMA interrupt request.
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Channel.  
  * @retval None
  */
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
  /* Transfer Error Interrupt management ***************************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
    {
      /* Disable the transfer error interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
      
      /* Clear the transfer error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
      
      /* Update error code */
      SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
      
      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_ERROR;
      
      /* Process Unlocked */
      __HAL_UNLOCK(hdma); 
      
      if (hdma->XferErrorCallback != NULL)
      {
        /* Transfer error callback */
        hdma->XferErrorCallback(hdma);
      }
    }
  }

  /* Half Transfer Complete Interrupt management ******************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
    { 
      /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
      if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
      {
        /* Disable the half transfer interrupt */
        __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
      }
      /* Clear the half transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

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

      if(hdma->XferHalfCpltCallback != NULL)
      {
        /* Half transfer callback */
        hdma->XferHalfCpltCallback(hdma);
      }
    }
  }
  
  /* Transfer Complete Interrupt management ***********************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
    {
      if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
      {
        /* Disable the transfer complete interrupt */
        __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
      }
      /* Clear the transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
    
      /* Update error code */
      SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE);

      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_READY;
    
      /* Process Unlocked */
      __HAL_UNLOCK(hdma);
    
      if(hdma->XferCpltCallback != NULL)
      {       
        /* Transfer complete callback */
        hdma->XferCpltCallback(hdma);
      }
    }
  }
}
예제 #11
0
/**
  * @brief  Polling for transfer complete.
  * @param  hdma:    pointer to a DMA_HandleTypeDef structure that contains
  *                  the configuration information for the specified DMA Channel.
  * @param  CompleteLevel: Specifies the DMA level complete.  
  * @param  Timeout:       Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
{
  uint32_t temp;
  uint32_t tickstart = 0x00;
  
  /* Get the level transfer complete flag */
  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Transfer Complete flag */
    temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
  }
  else
  {
    /* Half Transfer Complete flag */
    temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
  }

  /* Get tick */
  tickstart = HAL_GetTick();

  while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
  {
    if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
    {      
      /* Clear the transfer error flags */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
      
      /* Update error code */
      SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);

      /* Change the DMA state */
      hdma->State= HAL_DMA_STATE_ERROR;
      
      /* Process Unlocked */
      __HAL_UNLOCK(hdma);
      
      return HAL_ERROR;
    }
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
      {
        /* Update error code */
        SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
        
        /* Change the DMA state */
        hdma->State = HAL_DMA_STATE_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hdma);
        
        return HAL_TIMEOUT;
      }
    }
  }

  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Clear the transfer complete flag */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

    /* The selected Channelx EN bit is cleared (DMA is disabled and 
    all transfers are complete) */
    hdma->State = HAL_DMA_STATE_READY;

  }
  else
  { 
    /* Clear the half transfer complete flag */
    __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
  
    /* The selected Channelx EN bit is cleared (DMA is disabled and 
    all transfers of half buffer are complete) */
    hdma->State = HAL_DMA_STATE_READY_HALF;
  }
  
  /* Process unlocked */
  __HAL_UNLOCK(hdma);

  return HAL_OK;
}
예제 #12
0
/**
  * @brief  Starts the multi_buffer DMA Transfer with interrupt enabled.
  * @param  hdma       pointer to a DMA_HandleTypeDef structure that contains
  *                     the configuration information for the specified DMA Stream.
  * @param  SrcAddress The source memory Buffer address
  * @param  DstAddress The destination memory Buffer address
  * @param  SecondMemAddress The second memory Buffer address in case of multi buffer Transfer
  * @param  DataLength The length of data to be transferred from source to destination
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMAEx_MultiBufferStart_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the parameters */
  assert_param(IS_DMA_BUFFER_SIZE(DataLength));

  /* Memory-to-memory transfer not supported in double buffering mode */
  if (hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
  {
    hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
    return HAL_ERROR;
  }

  /* Check callback functions */
  if ((NULL == hdma->XferCpltCallback) || (NULL == hdma->XferM1CpltCallback) || (NULL == hdma->XferErrorCallback))
  {
    hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
    return HAL_ERROR;
  }

  /* Process locked */
  __HAL_LOCK(hdma);

  if(HAL_DMA_STATE_READY == hdma->State)
  {
    /* Change DMA peripheral state */
    hdma->State = HAL_DMA_STATE_BUSY;

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

    /* Enable the Double buffer mode */
    hdma->Instance->CR |= (uint32_t)DMA_SxCR_DBM;

    /* Configure DMA Stream destination address */
    hdma->Instance->M1AR = SecondMemAddress;

    /* Configure the source, destination address and the data length */
    DMA_MultiBufferSetConfig(hdma, SrcAddress, DstAddress, DataLength);

    /* Clear all flags */
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
    __HAL_DMA_CLEAR_FLAG (hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));

    /* Enable Common interrupts*/
    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;
    hdma->Instance->FCR |= DMA_IT_FE;

    if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
    {
      hdma->Instance->CR  |= DMA_IT_HT;
    }

    /* Enable the peripheral */
    __HAL_DMA_ENABLE(hdma);
  }
  else
  {
    /* Process unlocked */
    __HAL_UNLOCK(hdma);	

    /* Return error status */
    status = HAL_BUSY;
  }
  return status;
}
예제 #13
0
/**
  * @brief  Handles DMA interrupt request.
  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
  *               the configuration information for the specified DMA Stream.  
  * @retval None
  */
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
  /* Transfer Error Interrupt management ***************************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
    {
      /* Disable the transfer error interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);

      /* Clear the transfer error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));

      /* Update error code */
      hdma->ErrorCode |= HAL_DMA_ERROR_TE;

      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_ERROR;

      /* Process Unlocked */
      __HAL_UNLOCK(hdma); 

      if(hdma->XferErrorCallback != NULL)
      {
        /* Transfer error callback */
        hdma->XferErrorCallback(hdma);
      }
    }
  }
  /* FIFO Error Interrupt management ******************************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
    {
      /* Disable the FIFO Error interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);

      /* Clear the FIFO error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));

      /* Update error code */
      hdma->ErrorCode |= HAL_DMA_ERROR_FE;

      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_ERROR;

      /* Process Unlocked */
      __HAL_UNLOCK(hdma);

      if(hdma->XferErrorCallback != NULL)
      {
        /* Transfer error callback */
        hdma->XferErrorCallback(hdma);
      }
    }
  }
  /* Direct Mode Error Interrupt management ***********************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
    {
      /* Disable the direct mode Error interrupt */
      __HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);

      /* Clear the direct mode error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));

      /* Update error code */
      hdma->ErrorCode |= HAL_DMA_ERROR_DME;

      /* Change the DMA state */
      hdma->State = HAL_DMA_STATE_ERROR;

      /* Process Unlocked */
      __HAL_UNLOCK(hdma);

      if(hdma->XferErrorCallback != NULL)
      {
        /* Transfer error callback */
        hdma->XferErrorCallback(hdma);
      }
    }
  }
  /* Half Transfer Complete Interrupt management ******************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
    { 
      /* Multi_Buffering mode enabled */
      if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
      {
        /* Clear the half transfer complete flag */
        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

        /* Current memory buffer used is Memory 0 */
        if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
        {
          /* Change DMA peripheral state */
          hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
        }
        /* Current memory buffer used is Memory 1 */
        else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
        {
          /* Change DMA peripheral state */
          hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
        }
      }
      else
      {
        /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
        if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
        {
          /* Disable the half transfer interrupt */
          __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
        }
        /* Clear the half transfer complete flag */
        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

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

      if(hdma->XferHalfCpltCallback != NULL)
      {
        /* Half transfer callback */
        hdma->XferHalfCpltCallback(hdma);
      }
    }
  }
  /* Transfer Complete Interrupt management ***********************************/
  if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
  {
    if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
    {
      if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
      {
        /* Clear the transfer complete flag */
        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

        /* Current memory buffer used is Memory 1 */
        if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
        {
          if(hdma->XferM1CpltCallback != NULL)
          {
            /* Transfer complete Callback for memory1 */
            hdma->XferM1CpltCallback(hdma);
          }
        }
        /* Current memory buffer used is Memory 0 */
        else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) 
        {
          if(hdma->XferCpltCallback != NULL)
          {
            /* Transfer complete Callback for memory0 */
            hdma->XferCpltCallback(hdma);
          }
        }
      }
      /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
      else
      {
        if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
        {
          /* Disable the transfer complete interrupt */
          __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
        }
        /* Clear the transfer complete flag */
        __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

        /* Update error code */
        hdma->ErrorCode |= HAL_DMA_ERROR_NONE;

        /* Change the DMA state */
        hdma->State = HAL_DMA_STATE_READY_MEM0;

        /* Process Unlocked */
        __HAL_UNLOCK(hdma);      

        if(hdma->XferCpltCallback != NULL)
        {
          /* Transfer complete callback */
          hdma->XferCpltCallback(hdma);
        }
      }
    }
  }
}
예제 #14
0
/**
  * @brief  Polling for transfer complete.
  * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains
  *                        the configuration information for the specified DMA Stream.
  * @param  CompleteLevel: Specifies the DMA level complete.  
  * @param  Timeout:       Timeout duration.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
{
  uint32_t temp, tmp, tmp1, tmp2;
  uint32_t timeout = 0x00; 

  /* Get the level transfer complete flag */
  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Transfer Complete flag */
    temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
  }
  else
  {
    /* Half Transfer Complete flag */
    temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
  }

  /* Get timeout */
  timeout = HAL_GetTick() + Timeout;

  while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
  {
    tmp  = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
    tmp1 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
    tmp2 = __HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
    if((tmp != RESET) || (tmp1 != RESET) || (tmp2 != RESET))
    {
      /* Clear the transfer error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
      /* Clear the FIFO error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
      /* Clear the DIrect Mode error flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));

      /* Change the DMA state */
      hdma->State= HAL_DMA_STATE_ERROR;
      
      /* Process Unlocked */
      __HAL_UNLOCK(hdma);

      return HAL_ERROR;
    }  
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if(HAL_GetTick() >= timeout)
      {
        /* Update error code */
        hdma->ErrorCode |= HAL_DMA_ERROR_TIMEOUT;

        /* Process Unlocked */
        __HAL_UNLOCK(hdma);

        /* Change the DMA state */
        hdma->State = HAL_DMA_STATE_TIMEOUT;

        return HAL_TIMEOUT;
      }
    }
  }
  /* Clear the half transfer complete flag */
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

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

  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
  {
    /* Multi_Buffering mode enabled */
    if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
    {
      /* Clear the transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));

      /* Current memory buffer used is Memory 0 */
      if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
      {
        /* Change DMA peripheral state */
        hdma->State = HAL_DMA_STATE_READY_MEM0;
      }
      /* Current memory buffer used is Memory 1 */
      else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
      {
        /* Change DMA peripheral state */
        hdma->State = HAL_DMA_STATE_READY_MEM1;
      }
    }
    else
    {
      /* Clear the transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)); 

      /* The selected Streamx EN bit is cleared (DMA is disabled and all transfers
         are complete) */
      hdma->State = HAL_DMA_STATE_READY_MEM0;
    }
    /* Process Unlocked */
    __HAL_UNLOCK(hdma);
  }
  else
  { 
    /* Multi_Buffering mode enabled */
    if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
    {
      /* Clear the half transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

      /* Current memory buffer used is Memory 0 */
      if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
      {
        /* Change DMA peripheral state */
        hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
      }
      /* Current memory buffer used is Memory 1 */
      else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
      {
        /* Change DMA peripheral state */
        hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
      }
    }
    else
    {
      /* Clear the half transfer complete flag */
      __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));

      /* Change DMA peripheral state */
      hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
    }
  }
  return HAL_OK;
}
예제 #15
0
/**
  * @brief  DeInitializes the DMA peripheral 
  * @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_DeInit(DMA_HandleTypeDef *hdma)
{
  /* Check the DMA peripheral state */
  if(hdma->State == HAL_DMA_STATE_BUSY)
  {
     return HAL_ERROR;
  }

  /* Disable the selected DMA Channelx */
  __HAL_DMA_DISABLE(hdma);
  
  /* Reset DMA Channel control register */
  hdma->Instance->CCR  = 0;
  
  /* Reset DMA Channel Number of Data to Transfer register */
  hdma->Instance->CNDTR = 0;
  
  /* Reset DMA Channel peripheral address register */
  hdma->Instance->CPAR  = 0;
  
  /* Reset DMA Channel memory address register */
  hdma->Instance->CMAR = 0;

  /* Clear all flags */
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
  __HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
  
  /* Reset DMA channel selection register */
  if (hdma->Instance == DMA1_Channel1)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C1S;
  }
  else if (hdma->Instance == DMA1_Channel2)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C2S;
  }
  else if (hdma->Instance == DMA1_Channel3)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C3S;
  }
  else if (hdma->Instance == DMA1_Channel4)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C4S;
  }
  else if (hdma->Instance == DMA1_Channel5)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C5S;
  }
  else if (hdma->Instance == DMA1_Channel6)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C6S;
  }
  else if (hdma->Instance == DMA1_Channel7)
  {
    /*Reset DMA request*/
    DMA1_CSELR->CSELR &= ~DMA_CSELR_C7S;
  }
  
  /* Initialise the error code */
  hdma->ErrorCode = HAL_DMA_ERROR_NONE;

  /* Initialize the DMA state */
  hdma->State = HAL_DMA_STATE_RESET;
  
  /* Release Lock */
  __HAL_UNLOCK(hdma);

  return HAL_OK;
}
/**
 * @brief Tx and Rx Transfer completed callbacks
 * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
 *              the configuration information for SPI module.
 * @retval None
 */
void BlueNRG_DMA_RxCallback(void)
{
  uint16_t byte_count;
  uint8_t ready_state;
  
  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmarx, BNRG_SPI_RX_DMA_TC_FLAG);
  
  /**
   * The TCIF shall be cleared to be able to start a new DMA transmission later on when required.
   * When receiving data, the TCIE is not set as there is no need to handle the interrupt
   * handler of the DMA_Tx.
   * The TCIF clearing is mandatory on STM32F4 but not on STM32L0.
   * In order to keep code identical across platform, the TCIF clearing may be kept as well on
   * the STM32L0 and all other MCUs.
   */
  __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
  switch (SPI_Context.SPI_Receive_Context.Spi_Receive_Event)
  {
  case SPI_CHECK_RECEIVED_HEADER_FOR_RX:
    byte_count = (Received_Header[4]<<8)|Received_Header[3];
    ready_state = Received_Header[0];
    
    if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
    {
      if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_RESET)
      {
        /**
         * This USE CASE shall never happen as this may break the IRQ/CS specification
         * The IRQ line shall never be low when CS is low to avoid BlueNRG race condition when
         * entering low power mode
         * the SPI_END_RECEIVE_FIX has been implemented to make sure this USE CASE never occurs
         * However, even when the behavior is not compliant to the specification, the BlueNRG
         * may not fail so it is increasing robustness by adding this checking just in case the
         * timeout define in the workaround is too short which will end up to marginally brake
         * the specification.
         * This checking will poping BluenRG for a dummy even
         */
        
        /* Release CS line */
        Disable_SPI_CS();
        
        LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
        
        ReceiveClosure();
      }
      else
      {
        DisableEnable_SPI_CS();
        SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); /**< BlueNRG not ready for reading */
      }
    }
    else
    {
      SPI_Receive_Manager(SPI_REQUEST_PAYLOAD);	/**< BlueNRG is ready for reading */
    }
    break;
    
  case SPI_RECEIVE_END:
    /* Release CS line */
    Disable_SPI_CS();
    
    LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
    
#if (SPI_END_RECEIVE_FIX == 1)
    pTimerTxRxCallback = ProcessEndOfReceive;
    TIMER_Start(TxRxTimerId, SPI_END_RECEIVE_FIX_TIMEOUT);
#else
    ProcessEndOfReceive();
#endif
    break;
    
  case SPI_CHECK_RECEIVED_HEADER_FOR_TX:
    byte_count = (Received_Header[2]<<8)|Received_Header[1];
    ready_state = Received_Header[0];
    
    if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
    {
      DisableEnable_SPI_CS();
      SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);	/**< BlueNRG not ready for writing */
    }
    else
    {
#if (TEST_TX_BUFFER_LIMITATION == 1)
      if(byte_count > MAX_TX_BUFFER_SIZE)
      {
        byte_count = MAX_TX_BUFFER_SIZE;
      }
#endif
      
      if(SPI_Context.SPI_Transmit_Context.packet_cont != TRUE)
      {
        if( byte_count < (SPI_Context.SPI_Transmit_Context.header_size + SPI_Context.SPI_Transmit_Context.payload_size))
        {
          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count - SPI_Context.SPI_Transmit_Context.header_size;
          SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
          SPI_Context.SPI_Transmit_Context.packet_cont = TRUE;
        }
        else
        {
          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
        }
        
        SPI_Transmit_Manager(SPI_HEADER_TRANSMIT);
      }
      else
      {
        if( byte_count < SPI_Context.SPI_Transmit_Context.payload_size)
        {
          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count;
          SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
        }
        else
        {
          SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
          SPI_Context.SPI_Transmit_Context.payload_size = 0;
        }
        
        SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
      }
    }
    
    break;
    
  default:
    break;
  }
}