Skip to main content
ceska
Associate
September 18, 2009
Question

SPI1 and DMA

  • September 18, 2009
  • 3 replies
  • 871 views
Posted on September 18, 2009 at 09:26

SPI1 and DMA

    This topic has been closed for replies.

    3 replies

    ceska
    ceskaAuthor
    Associate
    May 17, 2011
    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

    panchal_jayesh_m
    Associate II
    May 17, 2011
    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

    }

    jjyeh1976
    Associate III
    May 17, 2011
    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);

    }