cancel
Showing results for 
Search instead for 
Did you mean: 

SPI1 and DMA

ceska
Associate
Posted on September 18, 2009 at 09:26

SPI1 and DMA

3 REPLIES 3
ceska
Associate
Posted on May 17, 2011 at 13:08

Hello all!

I have a buffer SPI1_Buffer_Tx[] that I want transfer in SPI1 by using DMA and then transfer it into an external device. Buffer SPI1_Buffer_Rx[] receive data using DMA. SPI work in full-duplex mode.

But i can only do the transfer when i active the DMA_Cmd in the first time (DMA and SPI do it automtically). I like transfer data one more times, but no circular. I like trigger transfer by software.

void DMA1_Channel2_IRQHandler(void)

{

if(DMA_GetITStatus(DMA1_IT_TC2))

{

DMA_ClearITPendingBit(DMA1_IT_TC2);

GPIO_SetBits(GPIO_CS, GPIO_Pin_CS);

}

}

void SPI1_DMA1_Init (void)

{

SPI_InitTypeDef SPI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // Enable SPI1

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // Enable GPIO clocks

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // DMA

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure); // Configure SPI1 pins: SCK, MISO and MOSI

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CS;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIO_CS, &GPIO_InitStructure); // Configure I/O for Chip select

GPIO_SetBits(GPIO_CS, GPIO_Pin_CS);

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(SPI1, &SPI_InitStructure); // SPI1 configuration

DMA_DeInit(DMA1_Channel2); // DMA1 Channel2 configuration

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI1_DR_Address;

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI1_Buffer_Rx;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = SPI1_BufferSize;

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_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel2, &DMA_InitStructure);

DMA_DeInit(DMA1_Channel3); // DMA1 Channel3 configuration

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)SPI1_DR_Address;

DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SPI1_Buffer_Tx;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

DMA_InitStructure.DMA_Priority = DMA_Priority_Low;

DMA_Init(DMA1_Channel3, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); // Enable Channel2 Transfer complete interrupt

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // Configure none bit for preemption priority

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_IRQChannel;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 10;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure); // Enable the DMA1 Channel 2 Interrupt

SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); // Enable SPI1 DMA Tx request

SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); // Enable SPI1 DMA Rx request

SPI_Cmd(SPI1, ENABLE); // Enable SPI1

GPIO_ResetBits(GPIO_CS, GPIO_Pin_CS);

DMA_Cmd(DMA1_Channel2, ENABLE); // Enable DMA1 channel2

DMA_Cmd(DMA1_Channel3, ENABLE); // Enable DMA1 channel3

}

void SPI_Send_Packet ()

{

\\ ???

}

What must by written in ''SPI_Send_Packet()'' function for send SPI1_Buffer_Tx[] buffer?

Can me anybody help, please?

Thanks

jjyeh1976
Associate II
Posted on May 17, 2011 at 13:08

Hi,

Try this

void SPI_Send_Packet ()

{

// disable the dma1 channel3 (spi1 tx)

DMA_Cmd(DMA1_Channel3,DISABLE);

// reset the counter

DMA1_Channel3->CNTR = SPI1_BufferSize;

// restart DMA

DMA_Cmd(DMA1_Channel3,ENABLE);

}

panchal_jayesh_m
Associate II
Posted on May 17, 2011 at 13:08

Dear use this it is working.

i had tested and found ok.

{

GPIO_SetBits(GPIOC, GPIO_Pin_12);

DMA_Cmd(DMA1_Channel3, DISABLE);

DMA_Cmd(DMA1_Channel2, DISABLE);

DMA1_Channel2->CNDTR = 3;

DMA1_Channel3->CNDTR = 3;

GPIO_ResetBits(GPIOC, GPIO_Pin_12); //CS (chip Select)

DMA_Cmd(DMA1_Channel2, ENABLE); //Enable DMA1 channel2 (SPI1 Rx)

DMA_Cmd(DMA1_Channel3, ENABLE); //Enable DMA1 channel3 (SPI1 Tx)

while(!DMA_GetFlagStatus(DMA1_FLAG_TC2));//Check transfer completed

while(!DMA_GetFlagStatus(DMA1_FLAG_TC3));//Check transfer completed

}