void SPI_RxDma_Config(FunctionalState mode) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); SPI_DMACmd(SPI3,SPI_DMAReq_Rx,DISABLE); DMA_Cmd(DMA1_Stream0,DISABLE); DMA_DeInit(DMA1_Stream0); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = mode; NVIC_Init(&NVIC_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI3->DR); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &spi_dma_buffer[1][0]; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = SPI_RX_DMA; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream0,&DMA_InitStructure); DMA_DoubleBufferModeConfig(DMA1_Stream0, (uint32_t)&spi_dma_buffer[0][0], DMA_Memory_0); DMA_DoubleBufferModeCmd(DMA1_Stream0, mode); DMA_ITConfig(DMA1_Stream0,DMA_IT_TC,mode); DMA_Cmd(DMA1_Stream0,mode); SPI_DMACmd(SPI3,SPI_DMAReq_Rx,mode); }
/****************************************** * 函数名称:SPI2 DMA关闭 * 功能描述: * 入口参数: * 出口参数: * 返 回 值: * 全局变量: * 调用函数: * 描述 : *******************************************/ u8 SPI2_DMA_disable(void) { u16 time_out; time_out = 10000; DMA_Cmd(DMA1_Stream4,DISABLE); SPI_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,DISABLE); /*wait until DMA disable*/ while ((DMA_GetCmdStatus(DMA1_Stream4) != DISABLE) && time_out > 0) { time_out --; } /*if the DMA can not disable, return false*/ if(time_out == 0) { return FALSE; } else { return TRUE; } }
/** * @brief Configure DMA peripheral * @param None * @retval None */ static void DMA_Config(void) { /* Deinitialize DMA channels */ DMA_GlobalDeInit(); DMA_DeInit(SPI_DMAChannelRx); DMA_SetTimeOut(0x3F); /* DMA channel Rx of SPI Configuration */ DMA_Init(SPI_DMAChannelRx, (uint16_t)SPIBuffer_Rx, (uint16_t)SPI_DR_Address, \ RX_BUFFER_SIZE, DMA_DIR_PeripheralToMemory, DMA_Mode_Normal, \ DMA_MemoryIncMode_Inc, DMA_Priority_High, DMA_MemoryDataSize_Byte); /* Enable the SPI Rx DMA requests */ SPI_DMACmd(SPI1, SPI_DMAReq_RX, ENABLE); /* Enable Global DMA */ DMA_GlobalCmd(ENABLE); /* Enable the SPI RX DMA channel */ DMA_Cmd(SPI_DMAChannelRx, ENABLE); }
/****************************************** * 函数名称:SPI2 DMA使能 * 功能描述: * 入口参数: * 出口参数: * 返 回 值: * 全局变量: * 调用函数: * 描述 : *******************************************/ static u8 SPI2_DMA_Eable(void) { u16 time_out; time_out = 10000; /*Enable and configure the peripheral to be connected to the DMA*/ SPI_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE); /*Enable DMA2 stream3*/ DMA_Cmd(DMA1_Stream4, ENABLE); /*wait until DMA enable*/ while ((DMA_GetCmdStatus(DMA1_Stream4) != ENABLE) && time_out > 0) { time_out --; } /*if the DMA can not enable, return false*/ if(time_out == 0) { return FALSE; } else { return TRUE; } }
/************************************************************************* * Function Name: SPI2_DmaTransfer * Parameters: pInt8U pData,Int32U Size, SPI_TransferDir_t SPI_TransferDir * Return: none * * Description: DMA transfer * *************************************************************************/ void SPI2_DmaTransfer(pInt8U pData,Int32U Size, SPI_TransferDir_t SPI_TransferDir) { DMA_InitTypeDef DMA_InitStructure; Int32U Dummy = 0xFF; // Initialize DMA Rx channel DMA_DeInit(DMA_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (SPI_TransferDir == SPI_RECEIVE)?(Int32U)pData:(Int32U)&Dummy; DMA_InitStructure.DMA_BufferSize = Size; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = (SPI_TransferDir == SPI_RECEIVE)?DMA_MemoryInc_Enable:DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Init channel DMA_Init(DMA_Channel4, &DMA_InitStructure); // Initialize DMA Tx channel DMA_DeInit(DMA_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (SPI_TransferDir == SPI_TRANSMIT)?(Int32U)pData:(Int32U)&Dummy; DMA_InitStructure.DMA_BufferSize = Size; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = (SPI_TransferDir == SPI_TRANSMIT)?DMA_MemoryInc_Enable:DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // Init channel DMA_Init(DMA_Channel5, &DMA_InitStructure); // Enable SPI2 DMA transfer SPI_DMACmd(SPI2,SPI_DMAReq_Rx,ENABLE); SPI_DMACmd(SPI2,SPI_DMAReq_Tx,ENABLE); #ifdef DMA_ERRATA ENTR_CRT_SECTION(); // Enable channel DMA_Cmd(DMA_Channel4,ENABLE); DMA_Cmd(DMA_Channel5,ENABLE); while(1) { if ( (DMA_GetITStatus(DMA_IT_TE4) == SET) || (DMA_GetITStatus(DMA_IT_TE5) == SET)) { DMA_ClearITPendingBit(DMA_IT_GL4 | DMA_IT_GL5); DMA_Cmd(DMA_Channel5,DISABLE); DMA_Cmd(DMA_Channel4,DISABLE); break; } if ( (DMA_GetITStatus(DMA_IT_TC4) == SET) && (DMA_GetITStatus(DMA_IT_TC5) == SET)) { break; } }; EXT_CRT_SECTION(); #else // set the flag DMA Transfer in progress TransferStatus = TRUE; DMA_ITConfig(DMA_Channel4, DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_ITConfig(DMA_Channel5, DMA_IT_TE, ENABLE); // Enable SPI2 DMA transfer SPI_DMACmd(SPI2,SPI_DMAReq_Rx,ENABLE); SPI_DMACmd(SPI2,SPI_DMAReq_Tx,ENABLE); while(TransferStatus); #endif // wait until SPI transmit FIFO isn't empty while(SPI_GetFlagStatus(SPI2, SPI_FLAG_TXE)==RESET); // wait until SPI receive FIFO isn't empty while(SPI_GetFlagStatus(SPI2, SPI_FLAG_RXNE)==SET); SPI_DMACmd(SPI2,SPI_DMAReq_Tx,DISABLE); SPI_DMACmd(SPI2,SPI_DMAReq_Rx,DISABLE); }
/************************************************************************* * Function Name: MmcInit * Parameters: none * Return: none * * Description: Init SPI, Cart Present, Write Protect and Chip select pins * *************************************************************************/ void MmcInit (void) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // Enable GPIO clocks RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); // Enable SPI2 Periphery clock RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // Deinitializes the SPI2 SPI_DeInit(SPI2); // Release reset of GPIOB, GPIOC RCC_APB2PeriphResetCmd( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, DISABLE); // Configure SPI2_CLK, SPI2_MOSI, SPI2_nCS1, Card Present and Write Protect pins GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = SD_CS; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = SD_SCLK | SD_MOSI | SD_MISO; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = SD_CP | SD_WP; GPIO_Init(GPIOC, &GPIO_InitStructure); // Chip select MmcChipSelect(0); // Spi init SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI2, &SPI_InitStructure); // Enable SPI2 */ SPI_Cmd(SPI2, ENABLE); // Clock Freq. Identification Mode < 400kHz MmcSetClockFreq(IdentificationModeClock); #if SPI_DMA_ENA > 0 // Enable DMA clock RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA, ENABLE); // Clear pending interrupt DMA_ClearITPendingBit( DMA_IT_GL4 | DMA_IT_GL5); // Interrupts DMA enable SPI_DMACmd(SPI2,SPI_DMAReq_Rx,DISABLE); SPI_DMACmd(SPI2,SPI_DMAReq_Tx,DISABLE); #ifndef DMA_ERRATA NVIC_InitTypeDef NVIC_InitStructure; // VIC configuration NVIC_InitStructure.NVIC_IRQChannel = DMAChannel4_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI_DMA_INTR_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMAChannel5_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI_DMA_INTR_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #endif // SPI_DMA_ENA > 0 }
void dma_init(void) { dmaSema_ID = osMutexCreate(osMutex(dmaSema)); dmaComplete_ID = osSemaphoreCreate(osSemaphore(dmaComplete), 1); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // SPI_InitTypeDef SPI_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; DMA_Cmd(DMA2_Stream0, DISABLE); //disable receiver DMA_Cmd(DMA2_Stream3, DISABLE); //disable transmitter DMA_DeInit(DMA2_Stream0); //place default values DMA_DeInit(DMA2_Stream3); DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0); //transfer complete DMA_ClearFlag(DMA2_Stream3, DMA_FLAG_TCIF3); DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TEIF0); //transfer error DMA_ClearFlag(DMA2_Stream3, DMA_FLAG_TEIF3); DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_FEIF0); //FIFO error DMA_ClearFlag(DMA2_Stream3, DMA_FLAG_FEIF3); DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_DMEIF0); //direct mode error DMA_ClearFlag(DMA2_Stream3, DMA_FLAG_DMEIF3); /* Start DMA2 clock */ // Configure DMA streams DMA_InitStructure.DMA_Channel = DMA_Channel_3; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR); DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; //not needed DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //receiving DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_Init(DMA2_Stream0, &DMA_InitStructure); //sending DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_Init(DMA2_Stream3, &DMA_InitStructure); //enable SPI_DMACmd(SPI1, SPI_DMAReq_Rx | SPI_DMAReq_Tx, ENABLE); //Setting up interrupt NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //enable receiving DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); }
void SPIx_Init(SPI_Driver* SPIx) { SPI_InitTypeDef SPI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; #ifdef SPIx_USE_DMA DMA_InitTypeDef DMA_InitStructure; #endif // Enable SPI and GPIO clocks SPIx->SPI_CLK(SPIx->SPI_Func, ENABLE); SPIx->GPIO_CLK(SPIx->GPIO_Func, ENABLE); // Connect SPI pins to AF GPIO_PinAFConfig(SPIx->Gpio, SPIx->SCK_Src, SPIx->GPIO_AF_SPI); GPIO_PinAFConfig(SPIx->Gpio, SPIx->MISO_Src, SPIx->GPIO_AF_SPI); GPIO_PinAFConfig(SPIx->Gpio, SPIx->MOSI_Src, SPIx->GPIO_AF_SPI); // SPI SCK/MISO/MOSI pin configuration GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Pin = SPIx->SCK_Pin | SPIx->MISO_Pin | SPIx->MOSI_Pin; GPIO_Init(SPIx->Gpio, &GPIO_InitStructure); SPIx->GPIO_CS_CLK(SPIx->CS_Func, ENABLE); // Configure GPIO PIN for Chip select GPIO_InitStructure.GPIO_Pin = SPIx->CS_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SPIx->Gpio_CS, &GPIO_InitStructure); // Chip DeSelect high CHIP_DESELECT(SPIx); //SPI configuration -------------------------------------------------------*/ SPI_I2S_DeInit(SPIx->SPI); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_InitStructure.SPI_DataSize = SPIx->SPI_DataSize; SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPIx->SPI_Prescaler; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPIx->SPI, &SPI_InitStructure); SPI_CalculateCRC(SPIx->SPI, DISABLE); //Enable SPI SPI_Cmd(SPIx->SPI, ENABLE); while (SPI_I2S_GetFlagStatus(SPIx->SPI, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_ReceiveData(SPIx->SPI); #ifdef SPIx_USE_DMA // Enable DMA clock SPIx->DMA_CLK(SPIx->DMA_Func, ENABLE); //Enable the SPIx_RX_DMA_CHANNEL (SPIx_RX) Interrupt NVIC_Init(&SPIx->NVIC_DMA_TX); //Enable the SPIx_TX_DMA_CHANNEL (SPIx_TX) Interrupt NVIC_Init(&SPIx->NVIC_DMA_RX); // Deinitialize DMA Streams DMA_DeInit(SPIx->DMA_TX_Stream); while (DMA_GetCmdStatus(SPIx->DMA_TX_Stream) != DISABLE); DMA_Cmd(SPIx->DMA_TX_Stream, DISABLE); DMA_DeInit(SPIx->DMA_RX_Stream); while (DMA_GetCmdStatus(SPIx->DMA_RX_Stream) != DISABLE); DMA_Cmd(SPIx->DMA_RX_Stream, DISABLE); // Configure DMA Initialization Structure DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->SPI->DR)); DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_High; // Configure TX DMA DMA_InitStructure.DMA_Channel = SPIx->DMA_TX_CH; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)0; DMA_Init(SPIx->DMA_TX_Stream, &DMA_InitStructure); // Configure RX DMA DMA_InitStructure.DMA_Channel = SPIx->DMA_RX_CH; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; DMA_Init(SPIx->DMA_RX_Stream, &DMA_InitStructure); SPI_DMACmd(SPIx->SPI, SPI_DMAReq_Rx, ENABLE); SPI_DMACmd(SPIx->SPI, SPI_DMAReq_Tx, ENABLE); DMA_ClearFlag(SPIx->DMA_TX_Stream, SPIx->DMA_TX_Flag); DMA_ClearFlag(SPIx->DMA_RX_Stream, SPIx->DMA_RX_Flag); DMA_ITConfig(SPIx->DMA_TX_Stream, DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_ITConfig(SPIx->DMA_RX_Stream, DMA_IT_TC | DMA_IT_TE, ENABLE); DMA_Cmd(SPIx->DMA_TX_Stream, DISABLE); DMA_Cmd(SPIx->DMA_RX_Stream, DISABLE); #endif }