/** * @brief Resumes the Camera capture. * @param None * @retval None */ void BSP_CAMERA_Resume(void) { /* Enable the DCMI */ __HAL_DCMI_ENABLE(&hdcmi_eval); /* Enable the DMA */ __HAL_DMA_ENABLE(hdcmi_eval.DMA_Handle); }
/** * @brief Starts the multi_buffer DMA Transfer. * @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(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t SecondMemAddress, uint32_t DataLength) { /* Process Locked */ __HAL_LOCK(hdma); /* Current memory buffer used is Memory 0 */ if((hdma->Instance->CR & DMA_SxCR_CT) == 0) { hdma->State = HAL_DMA_STATE_BUSY_MEM0; } /* Current memory buffer used is Memory 1 */ else if((hdma->Instance->CR & DMA_SxCR_CT) != 0) { hdma->State = HAL_DMA_STATE_BUSY_MEM1; } /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* 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); /* Enable the peripheral */ __HAL_DMA_ENABLE(hdma); return HAL_OK; }
/** * @brief Start the DMA Transfer with interrupt enabled. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param SrcAddress: The source memory Buffer address * @param DstAddress: The destination memory Buffer address * @param DataLength: The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { /* Process locked */ __HAL_LOCK(hdma); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* Configure the source, destination address and the data length */ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Enable the transfer complete interrupt */ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC); /* Enable the Half transfer complete interrupt */ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT); /* Enable the transfer Error interrupt */ __HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE); /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); return HAL_OK; }
/** * @brief Start the DMA Transfer. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param SrcAddress: The source memory Buffer address * @param DstAddress: The destination memory Buffer address * @param DataLength: The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Process locked */ __HAL_LOCK(hdma); if(HAL_DMA_STATE_READY == hdma->State) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* Configure the source, destination address and the data length & clear flags*/ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); } else { /* Process Unlocked */ __HAL_UNLOCK(hdma); status = HAL_BUSY; } return status; }
uint32_t uart_send_bytes(uint8_t* pData, uint16_t len) { /* Wait until previous tx is done */ uint32_t tickstart = HAL_GetTick(); while ((uart_data.TxState == UART_TRANSMITTING) && ((HAL_GetTick() - tickstart) < UART_TXDATA_TIMEOUT_MS)); if (uart_data.TxState == UART_TRANSMITTING) { return 0; } __HAL_DMA_DISABLE(&DMAhandle_TX); /* Set source address and buffer length */ DMAhandle_TX.Instance->M0AR = (uint32_t) pData; DMAhandle_TX.Instance->NDTR = (uint16_t) len; /* Enable transfer complete interrupt */ __HAL_DMA_ENABLE_IT(&DMAhandle_TX, DMA_IT_TC); /* Enable UART as DMA enabled transmitter */ UARThandle.Instance->CR3 |= USART_CR3_DMAT; uart_data.TxState = UART_TRANSMITTING; __HAL_DMA_ENABLE(&DMAhandle_TX); return (uint32_t) len; }
/** * @brief Start the 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 DataLength: The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { /* Process locked */ __HAL_LOCK(hdma); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* Configure the source, destination address and the data length */ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Enable all interrupts */ hdma->Instance->CR |= DMA_IT_TC | DMA_IT_HT | DMA_IT_TE | DMA_IT_DME; hdma->Instance->FCR |= DMA_IT_FE; /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); return HAL_OK; }
/** * @brief Start the 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 DataLength: The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { HAL_StatusTypeDef status = HAL_OK; /* calculate DMA base and stream number */ DMA_Base_Registers *regs = (DMA_Base_Registers *)hdma->StreamBaseAddress; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* 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; /* Configure the source, destination address and the data length */ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Clear all interrupt flags at correct offset within the register */ regs->IFCR = 0x3FU << hdma->StreamIndex; /* 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->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; }
/** * @brief Start the DMA Transfer with interrupt enabled. * @param hdma: pointer to a DMA_HandleTypeDef structure that contains * the configuration information for the specified DMA Channel. * @param SrcAddress: The source memory Buffer address * @param DstAddress: The destination memory Buffer address * @param DataLength: The length of data to be transferred from source to destination * @retval HAL status */ HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { HAL_StatusTypeDef status = HAL_OK; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Process locked */ __HAL_LOCK(hdma); if(HAL_DMA_STATE_READY == hdma->State) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; hdma->ErrorCode = HAL_DMA_ERROR_NONE; /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* Configure the source, destination address and the data length & clear flags*/ DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength); /* Enable the transfer complete interrupt */ /* Enable the transfer Error interrupt */ if(NULL != hdma->XferHalfCpltCallback) { /* Enable the Half transfer complete interrupt as well */ __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); } else { __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT); __HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE)); } /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); } else { /* Process Unlocked */ __HAL_UNLOCK(hdma); /* Remain BUSY */ status = HAL_BUSY; } return status; }
/** * @brief Start the 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 DataLength: The length of data to be transferred from source to destination * @retval HAL status */ static HAL_StatusTypeDef MBED_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) { /* Process locked */ __HAL_LOCK(hdma); /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* Check the parameters */ assert_param(IS_DMA_BUFFER_SIZE(DataLength)); /* Disable the peripheral */ __HAL_DMA_DISABLE(hdma); /* Configure the source, destination address and the data length */ /* Clear DBM bit */ hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); /* Configure DMA Stream data length */ hdma->Instance->NDTR = DataLength; /* Peripheral to Memory */ if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH) { /* Configure DMA Stream destination address */ hdma->Instance->PAR = DstAddress; /* Configure DMA Stream source address */ hdma->Instance->M0AR = SrcAddress; } else { /* Memory to Peripheral */ /* Configure DMA Stream source address */ hdma->Instance->PAR = SrcAddress; /* Configure DMA Stream destination address */ hdma->Instance->M0AR = DstAddress; } /* Enable all interrupts EXCEPT HALF TRANSFER COMPLETE */ hdma->Instance->CR |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME; hdma->Instance->FCR |= DMA_IT_FE; /* Enable the Peripheral */ __HAL_DMA_ENABLE(hdma); return HAL_OK; }
/** * @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 Starts the multi_buffer DMA Transfer. * @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(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; status = HAL_ERROR; } else { /* Process Locked */ __HAL_LOCK(hdma); if(HAL_DMA_STATE_READY == hdma->State) { /* Change DMA peripheral state */ hdma->State = HAL_DMA_STATE_BUSY; /* 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); /* Enable the peripheral */ __HAL_DMA_ENABLE(hdma); } else { /* Return error status */ status = HAL_BUSY; } } return status; }
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size) { SPI_HandleTypeDef* hspi = &spiHandle[spiDeviceByInstance(Instance)].Handle; DMA_HandleTypeDef* hdma = &dmaHandle[spiDeviceByInstance(Instance)].Handle; hdma->Instance = Stream; hdma->Init.Channel = Channel; hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; hdma->Init.PeriphInc = DMA_PINC_DISABLE; hdma->Init.MemInc = DMA_MINC_ENABLE; hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma->Init.Mode = DMA_NORMAL; hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; hdma->Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; hdma->Init.PeriphBurst = DMA_PBURST_SINGLE; hdma->Init.MemBurst = DMA_MBURST_SINGLE; hdma->Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_DeInit(hdma); HAL_DMA_Init(hdma); __HAL_DMA_ENABLE(hdma); __HAL_SPI_ENABLE(hspi); /* Associate the initialized DMA handle to the spi handle */ __HAL_LINKDMA(hspi, hdmatx, (*hdma)); // DMA TX Interrupt dmaSetHandler(DMA2_ST1_HANDLER, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)spiDeviceByInstance(Instance)); // SCB_CleanDCache_by_Addr((uint32_t) pData, Size); HAL_SPI_Transmit_DMA(hspi, pData, Size); //HAL_DMA_Start(&hdma, (uint32_t) pData, (uint32_t) &(Instance->DR), Size); return hdma; }
DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size) { SPIDevice device = spiDeviceByInstance(Instance); spiHardwareMap[device].hdma.Instance = Stream; spiHardwareMap[device].hdma.Init.Channel = Channel; spiHardwareMap[device].hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; spiHardwareMap[device].hdma.Init.PeriphInc = DMA_PINC_DISABLE; spiHardwareMap[device].hdma.Init.MemInc = DMA_MINC_ENABLE; spiHardwareMap[device].hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; spiHardwareMap[device].hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; spiHardwareMap[device].hdma.Init.Mode = DMA_NORMAL; spiHardwareMap[device].hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; spiHardwareMap[device].hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; spiHardwareMap[device].hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; spiHardwareMap[device].hdma.Init.MemBurst = DMA_MBURST_SINGLE; spiHardwareMap[device].hdma.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_DeInit(&spiHardwareMap[device].hdma); HAL_DMA_Init(&spiHardwareMap[device].hdma); __HAL_DMA_ENABLE(&spiHardwareMap[device].hdma); __HAL_SPI_ENABLE(&spiHardwareMap[device].hspi); /* Associate the initialized DMA handle to the spi handle */ __HAL_LINKDMA(&spiHardwareMap[device].hspi, hdmatx, spiHardwareMap[device].hdma); // DMA TX Interrupt dmaSetHandler(spiHardwareMap[device].dmaIrqHandler, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)device); //HAL_CLEANCACHE(pData,Size); // And Transmit HAL_SPI_Transmit_DMA(&spiHardwareMap[device].hspi, pData, Size); return &spiHardwareMap[device].hdma; }
/** * @brief Manage the SPI receive * @param ReceiveRequest: the receive request * @retval None */ static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest) { uint16_t byte_count; uint8_t localloop; /* * Disable both DMA */ __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx); __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx); /** * Flush the Rx register or FIFO */ for (localloop = 0 ; localloop < SPI_FIFO_RX_DEPTH ; localloop++) { *(volatile uint8_t*)__HAL_BLUENRG_SPI_GET_RX_DATA_REGISTER_ADDRESS(SPI_Context.hspi); } __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Enable Receive packet notification */ __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Disable Transmit packet notification */ switch (ReceiveRequest) { case SPI_REQUEST_VALID_HEADER_FOR_RX: ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_RX, (uint8_t *)Read_Header_CMD); break; case SPI_REQUEST_VALID_HEADER_FOR_TX: ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_TX, (uint8_t *)Write_Header_CMD); break; case SPI_REQUEST_PAYLOAD: SPI_Context.SPI_Receive_Context.Spi_Receive_Event = SPI_RECEIVE_END; /* * Check data to received is not available buffer size */ byte_count = (Received_Header[4]<<8)|Received_Header[3]; if (byte_count > SPI_Context.SPI_Receive_Context.buffer_size) { byte_count = SPI_Context.SPI_Receive_Context.buffer_size; } SPI_Context.SPI_Receive_Context.payload_len = byte_count; __HAL_BLUENRG_DMA_CLEAR_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send same Byte */ /* * Set counter in both DMA */ __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, byte_count); __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, byte_count); /* * Set memory address in both DMA */ __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)SPI_Context.SPI_Receive_Context.buffer); __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)&dummy_bytes); break; default: break; } /* * Enable both DMA - Rx First */ __HAL_DMA_ENABLE(SPI_Context.hspi->hdmarx); __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); return; }
/** * @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; }
void UART_RestartDMA(void) { __HAL_DMA_DISABLE(&hdma_usart1_rx); hdma_usart1_rx.Instance->CNDTR = BUFFER_SIZE; __HAL_DMA_ENABLE(&hdma_usart1_rx); }
static int uart_init_peripheral(void) { __HAL_RCC_USART2_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); UARThandle.Instance = UART_INSTANCE; UARThandle.Init.BaudRate = UART_BAUDRATE; UARThandle.Init.WordLength = UART_WORDLENGTH_8B; UARThandle.Init.StopBits = UART_STOPBITS_1; UARThandle.Init.Parity = UART_PARITY_NONE; UARThandle.Init.HwFlowCtl = UART_HWCONTROL_NONE; UARThandle.Init.OverSampling = UART_OVERSAMPLING_8; UARThandle.Init.Mode = UART_MODE_TX_RX; DMAhandle_TX.Instance = DMA1_Stream6; DMAhandle_TX.Init.Channel = DMA_CHANNEL_4; DMAhandle_TX.Init.Direction = DMA_MEMORY_TO_PERIPH; DMAhandle_TX.Init.FIFOMode = DMA_FIFOMODE_DISABLE; DMAhandle_TX.Init.MemBurst = DMA_MBURST_SINGLE; DMAhandle_TX.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; DMAhandle_TX.Init.MemInc = DMA_MINC_ENABLE; DMAhandle_TX.Init.Mode = DMA_NORMAL; DMAhandle_TX.Init.PeriphBurst = DMA_PBURST_SINGLE; DMAhandle_TX.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; DMAhandle_TX.Init.PeriphInc = DMA_PINC_DISABLE; DMAhandle_TX.Init.Priority = DMA_PRIORITY_LOW; DMAhandle_RX = DMAhandle_TX; DMAhandle_RX.Instance = DMA1_Stream5; DMAhandle_RX.Init.Channel = DMA_CHANNEL_4; DMAhandle_RX.Init.Direction = DMA_PERIPH_TO_MEMORY; DMAhandle_RX.Init.Mode = DMA_CIRCULAR; UARThandle.hdmatx = &DMAhandle_TX; UARThandle.hdmarx = &DMAhandle_RX; HAL_UART_DeInit(&UARThandle); HAL_UART_Init(&UARThandle); UART_INSTANCE->BRR = (2u << 4u) | (5u); /* Baudrate = 2000000 with SYSCLK=168MHz, * HAL is not very good at figuring this number out... */ HAL_DMA_DeInit(&DMAhandle_TX); HAL_DMA_Init(&DMAhandle_TX); HAL_DMA_DeInit(&DMAhandle_RX); HAL_DMA_Init(&DMAhandle_RX); NVIC_SetPriority(DMA1_Stream6_IRQn, UART_DMA_TX_IRQ_PRIO); HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn); NVIC_SetPriority(DMA1_Stream5_IRQn, UART_DMA_RX_IRQ_PRIO); HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); /* Use uart data register as peripheral destination for TX */ DMAhandle_TX.Instance->PAR = (uint32_t) &(UARThandle.Instance->DR); /* Set source and destination address and buffer length */ DMAhandle_RX.Instance->NDTR = RX_BUF_LEN; DMAhandle_RX.Instance->PAR = (uint32_t) &(UARThandle.Instance->DR); DMAhandle_RX.Instance->M0AR = (uint32_t) dma_buffer_rx; /* Enable UART as DMA enabled receiver */ UARThandle.Instance->CR3 |= USART_CR3_DMAR; /* Enable transfer complete interrupt */ __HAL_DMA_ENABLE_IT(&DMAhandle_RX, DMA_IT_TC); __HAL_DMA_ENABLE(&DMAhandle_RX); return 0; }