uint8_t TM_SPI_DMA_Working(SPI_TypeDef* SPIx) { /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Check if TX or RX DMA is working */ return ( Settings->RX_Stream->NDTR || Settings->TX_Stream->NDTR); }
void TM_SPI_DMA_DisableInterrupts(SPI_TypeDef* SPIx) { /* Get SPI settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Enable interrupts for TX and RX streams */ TM_DMA_DisableInterrupts(Settings->TX_Stream); TM_DMA_DisableInterrupts(Settings->RX_Stream); }
void TM_SPI_DMA_Deinit(SPI_TypeDef* SPIx) { /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Deinit DMA Streams */ DMA_DeInit(Settings->TX_Stream); DMA_DeInit(Settings->RX_Stream); }
void TM_SPI_DMA_Init(SPI_TypeDef* SPIx) { /* Init DMA TX mode */ /* Assuming SPI is already initialized and clock is enabled */ /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Init both streams */ TM_DMA_Init(Settings->TX_Stream, NULL); TM_DMA_Init(Settings->RX_Stream, NULL); }
uint8_t TM_SPI_DMA_Transmitting(SPI_TypeDef* SPIx) { /* Get SPI settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Check if TX or RX DMA are working */ return ( Settings->RX_Stream->NDTR || /*!< RX is working */ Settings->TX_Stream->NDTR || /*!< TX is working */ SPI_IS_BUSY(SPIx) /*!< SPI is busy */ ); }
void TM_SPI_DMA_InitWithStreamAndChannel(SPI_TypeDef* SPIx, DMA_Stream_TypeDef* TX_Stream, uint32_t TX_Channel, DMA_Stream_TypeDef* RX_Stream, uint32_t RX_Channel) { /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Set values */ Settings->RX_Channel = RX_Channel; Settings->RX_Stream = RX_Stream; Settings->TX_Channel = TX_Channel; Settings->TX_Stream = TX_Stream; /* Init SPI */ TM_SPI_DMA_Init(SPIx); }
uint8_t TM_SPI_DMA_SendHalfWord(SPI_TypeDef* SPIx, uint16_t value, uint16_t count) { DMA_HandleTypeDef DMA_InitStruct; /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Check if DMA available */ if (Settings->TX_Stream->NDTR) { return 0; } /* Set DMA default */ DMA_InitStruct.Instance = Settings->TX_Stream; DMA_InitStruct.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; DMA_InitStruct.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; DMA_InitStruct.Init.PeriphInc = DMA_PINC_DISABLE; DMA_InitStruct.Init.Mode = DMA_NORMAL; DMA_InitStruct.Init.Priority = DMA_PRIORITY_LOW; DMA_InitStruct.Init.FIFOMode = DMA_FIFOMODE_DISABLE; DMA_InitStruct.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; DMA_InitStruct.Init.MemBurst = DMA_MBURST_SINGLE; DMA_InitStruct.Init.PeriphBurst = DMA_PBURST_SINGLE; DMA_InitStruct.Init.MemInc = DMA_MINC_DISABLE; DMA_InitStruct.Init.Channel = Settings->TX_Channel; DMA_InitStruct.Init.Direction = DMA_MEMORY_TO_PERIPH; /* Set dummy memory to value we specify */ Settings->Dummy16 = value; /* Deinit first TX stream */ TM_DMA_ClearFlag(Settings->TX_Stream, DMA_FLAG_ALL); /* Init TX stream */ TM_DMA_Init(Settings->TX_Stream, &DMA_InitStruct); /* Start TX stream */ TM_DMA_Start(&DMA_InitStruct, (uint32_t) &Settings->Dummy16, (uint32_t) &SPIx->DR, count); /* Enable SPI TX DMA */ SPIx->CR2 |= SPI_CR2_TXDMAEN; /* Return OK */ return 1; }
void TM_SPI_DMA_Init(SPI_TypeDef* SPIx) { /* Init DMA TX mode */ /* Assuming SPI is already initialized and clock is enabled */ /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Enable DMA clock */ if (Settings->TX_Stream >= DMA2_Stream0) { /* Enable DMA2 clock */ RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; } else { /* Enable DMA1 clock */ RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; } /* Enable DMA clock */ if (Settings->RX_Stream >= DMA2_Stream0) { /* Enable DMA2 clock */ RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN; } else { /* Enable DMA1 clock */ RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; } /* Set DMA options for TX stream */ DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_Priority = DMA_Priority_Low; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; }
uint8_t TM_SPI_DMA_Transmit(SPI_TypeDef* SPIx, uint8_t* TX_Buffer, uint8_t* RX_Buffer, uint16_t count) { /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Check if DMA available */ if ( Settings->RX_Stream->NDTR || Settings->TX_Stream->NDTR || (TX_Buffer == NULL && RX_Buffer == NULL) ) { return 0; } /* Set dummy memory to default */ SPI_DMA_Dummy = 0x00; /* Set DMA peripheral address and count */ DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t) &SPIx->DR; DMA_InitStruct.DMA_BufferSize = count; /* Configure TX DMA */ DMA_InitStruct.DMA_Channel = Settings->TX_Channel; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; if (TX_Buffer != NULL) { DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) &TX_Buffer[0]; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; } else { DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) &SPI_DMA_Dummy; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; } /* Deinit first TX stream */ DMA_DeInit(Settings->TX_Stream); /* Init TX stream */ DMA_Init(Settings->TX_Stream, &DMA_InitStruct); /* Configure RX DMA */ DMA_InitStruct.DMA_Channel = Settings->RX_Channel; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; if (RX_Buffer != NULL) { DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) &RX_Buffer[0]; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; } else { DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t) &SPI_DMA_Dummy; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; } /* Deinit first RX stream */ DMA_DeInit(Settings->RX_Stream); /* Init RX stream */ DMA_Init(Settings->RX_Stream, &DMA_InitStruct); /* Enable RX stream */ Settings->RX_Stream->CR |= DMA_SxCR_EN; /* Enable TX stream */ Settings->TX_Stream->CR |= DMA_SxCR_EN; /* Enable SPI RX DMA */ SPIx->CR2 |= SPI_CR2_RXDMAEN; /* Enable SPI TX DMA */ SPIx->CR2 |= SPI_CR2_TXDMAEN; /* Return OK */ return 1; }
uint8_t TM_SPI_DMA_Transmit(SPI_TypeDef* SPIx, uint8_t* TX_Buffer, uint8_t* RX_Buffer, uint16_t count) { DMA_HandleTypeDef DMA_InitStruct; /* Get USART settings */ TM_SPI_DMA_INT_t* Settings = TM_SPI_DMA_INT_GetSettings(SPIx); /* Check if DMA available */ if ( Settings->RX_Stream->NDTR || Settings->TX_Stream->NDTR || (TX_Buffer == NULL && RX_Buffer == NULL) ) { return 0; } #if defined(STM32F7xx) CLEAR_BIT(SPIx->CR2, SPI_CR2_LDMATX); CLEAR_BIT(SPIx->CR2, SPI_CR2_LDMARX); #endif /* Set DMA default */ DMA_InitStruct.Init.PeriphInc = DMA_PINC_DISABLE; DMA_InitStruct.Init.Mode = DMA_NORMAL; DMA_InitStruct.Init.Priority = DMA_PRIORITY_LOW; DMA_InitStruct.Init.FIFOMode = DMA_FIFOMODE_DISABLE; DMA_InitStruct.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; DMA_InitStruct.Init.MemBurst = DMA_MBURST_SINGLE; DMA_InitStruct.Init.PeriphBurst = DMA_PBURST_SINGLE; /* Set dummy memory to default */ Settings->Dummy16 = 0x12; /* Set memory size */ DMA_InitStruct.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; DMA_InitStruct.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; /*******************************************************/ /* RX DMA */ /*******************************************************/ /* Set stream */ DMA_InitStruct.Instance = Settings->RX_Stream; /* Configure RX DMA */ DMA_InitStruct.Init.Channel = Settings->RX_Channel; DMA_InitStruct.Init.Direction = DMA_PERIPH_TO_MEMORY; DMA_InitStruct.Init.Priority = DMA_PRIORITY_HIGH; /* Deinit first RX stream */ TM_DMA_ClearFlag(Settings->RX_Stream, DMA_FLAG_ALL); /* Set memory increase */ if (RX_Buffer != NULL) { DMA_InitStruct.Init.MemInc = DMA_MINC_ENABLE; } else { DMA_InitStruct.Init.MemInc = DMA_MINC_DISABLE; } /* Start TX stream */ TM_DMA_Init(Settings->RX_Stream, &DMA_InitStruct); /* Start DMA */ if (RX_Buffer != NULL) { TM_DMA_Start(&DMA_InitStruct, (uint32_t) &SPIx->DR, (uint32_t) RX_Buffer, count); } else { TM_DMA_Start(&DMA_InitStruct, (uint32_t) &SPIx->DR, (uint32_t) &Settings->Dummy32, count); } /*******************************************************/ /* TX DMA */ /*******************************************************/ /* Set stream */ DMA_InitStruct.Instance = Settings->TX_Stream; /* Configure TX DMA */ DMA_InitStruct.Init.Channel = Settings->TX_Channel; DMA_InitStruct.Init.Direction = DMA_MEMORY_TO_PERIPH; /* Deinit first TX stream */ TM_DMA_ClearFlag(Settings->TX_Stream, DMA_FLAG_ALL); /* Set memory increase */ if (TX_Buffer != NULL) { DMA_InitStruct.Init.MemInc = DMA_MINC_ENABLE; } else { DMA_InitStruct.Init.MemInc = DMA_MINC_DISABLE; } /* Start TX stream */ TM_DMA_Init(Settings->TX_Stream, &DMA_InitStruct); /* Start DMA */ if (TX_Buffer != NULL) { TM_DMA_Start(&DMA_InitStruct, (uint32_t) TX_Buffer, (uint32_t) &SPIx->DR, count); } else { TM_DMA_Start(&DMA_InitStruct, (uint32_t) &Settings->Dummy32, (uint32_t) &SPIx->DR, count); } /* Start stream */ SPIx->CR2 |= SPI_CR2_RXDMAEN; SPIx->CR2 |= SPI_CR2_TXDMAEN; /* Return OK */ return 1; }
DMA_Stream_TypeDef* TM_SPI_DMA_GetStreamRX(SPI_TypeDef* SPIx) { /* Return pointer to TX stream */ return TM_SPI_DMA_INT_GetSettings(SPIx)->RX_Stream; }