1. 程式人生 > >【已實現】stm32 SPI DMA中斷收發

【已實現】stm32 SPI DMA中斷收發

#ifdef STM32_USE_DMA
/*-----------------------------------------------------------------------*/
/* Transmit/Receive Block using DMA (Platform dependent. STM32 here)     */
/*-----------------------------------------------------------------------*/
static
void stm32_dma_transfer(
	BOOL receive,		/* FALSE for buff->SPI, TRUE for SPI->buff               */
	const BYTE *buff,	/* receive TRUE  : 512 byte data block to be transmitted
						   receive FALSE : Data buffer to store received data    */
	UINT btr 			/* receive TRUE  : Byte count (must be multiple of 2)
						   receive FALSE : Byte count (must be 512)              */
)
{
	DMA_InitTypeDef DMA_InitStructure;
	WORD rw_workbyte[] = { 0xffff };
    u8      err;   
       
        DMA_DeInit(BSP_SD_SPI_DMA_T_CH);
	DMA_DeInit(BSP_SD_SPI_DMA_R_CH);
    
	/* shared DMA configuration values */
	DMA_InitStructure.DMA_PeripheralBaseAddr = (DWORD)(&(BSP_SD_SPI->DR));
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_BufferSize = btr;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

	if ( receive ) {

		/* DMA1 channel4 configuration SPI2 RX ---------------------------------------------*/
		DMA_InitStructure.DMA_MemoryBaseAddr = (DWORD)buff;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		DMA_Init(BSP_SD_SPI_DMA_R_CH, &DMA_InitStructure);

		/* DMA1 channel5 configuration SPI2 TX ---------------------------------------------*/
		DMA_InitStructure.DMA_MemoryBaseAddr = (DWORD)rw_workbyte;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
		DMA_Init(BSP_SD_SPI_DMA_T_CH, &DMA_InitStructure);
             
	} else {

		/* DMA1 channel4 configuration SPI2 RX ---------------------------------------------*/
		DMA_InitStructure.DMA_MemoryBaseAddr = (DWORD)rw_workbyte;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
		DMA_Init(BSP_SD_SPI_DMA_R_CH, &DMA_InitStructure);

		/* DMA1 channel5 configuration SPI2 TX ---------------------------------------------*/
		DMA_InitStructure.DMA_MemoryBaseAddr = (DWORD)buff;
		DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
		DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
		DMA_Init(BSP_SD_SPI_DMA_T_CH, &DMA_InitStructure);      
	}
    
    //預防措施
    BSP_SD_SPI->DR;   //接送前讀一次,保證緩衝區為空  
    DMA_ClearFlag(BSP_SD_SPI_DMA_R_FLAG_TC);    //清除通道標誌位    
    while((BSP_SD_SPI->SR & SPI_I2S_FLAG_TXE)==0);
    
    DMA_ITConfig(BSP_SD_SPI_DMA_R_CH, DMA_IT_TC, ENABLE); 
    
    DMA_SetCurrDataCounter(BSP_SD_SPI_DMA_R_CH, btr);
    DMA_SetCurrDataCounter(BSP_SD_SPI_DMA_T_CH, btr);
    
    DMA_Cmd(BSP_SD_SPI_DMA_R_CH, ENABLE);
    DMA_Cmd(BSP_SD_SPI_DMA_T_CH, ENABLE); 
    
    /* Enable SPI2 TX/RX request */
    SPI_I2S_DMACmd(BSP_SD_SPI, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE); 
    
    
    /* Wait until DMA1_Channel 4 Receive Complete */
    //while (DMA_GetFlagStatus(BSP_SD_SPI_DMA_R_FLAG_TC) == RESET) { ; }

    OSSemPend(SD_SPI_SemPtr,0, &err); 
}
#endif /* STM32_USE_DMA */