cancel
Showing results for 
Search instead for 
Did you mean: 

SPI RX DMA interrupt

Javad
Associate III
Posted on June 19, 2016 at 08:19

hi

I wanna use external ADS7816 ADC with serial (SPI) interface. I wrote the following code but it doesn't work! spi sclk pin has clock and I use PA0 to manage ADS1768 comunication as slave (SS). the problem is that I see output of ADS7816 on oscilloscope but DMA has no interrupt! where is the wrong in my code?!

&sharpdefine SPI1_RX_BUFF_SIZE 32

__IO uint8_t ExtAdcRxBuff[SPI1_RX_BUFF_SIZE];

void SPI_Config(void)

{

  SPI_InitTypeDef  SPI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

/*!< Enable GPIO clocks */

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

/*!< SPI pins configuration *************************************************/

  /*!< Connect SPI pins to AF5 */  

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1 );

  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1 );

GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1 );

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

/*!< SPI SCK pin configuration */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< SPI MOSI pin configuration */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*!< SPI MISO pin configuration */

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

/*!< Configure CS pin in output pushpull mode ********************/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

/*!< SPI configuration */

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; // APB2 / 8 = 10.5 MHz

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;

SPI_Init(SPI1, &SPI_InitStructure);

  /*!< Enable the SPI  */

  SPI_Cmd(SPI1, ENABLE);

}

void ADS1768_DMA_Init(void){

     

    DMA_InitTypeDef DMA_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

     

    /* Enable RCC clock */

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

     

    /* Disable stream if it was in use */

    DMA_DeInit(DMA2_Stream0);

    while(RESET != DMA_GetCmdStatus(DMA2_Stream0));

     

    /* Initiliaze DMA2 Channel 3 Stream 0 */

    DMA_InitStructure.DMA_Channel = DMA_Channel_3;

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

    DMA_InitStructure.DMA_PeripheralBaseAddr =  (uint32_t) &(SPI1->DR);

    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) (ExtAdcRxBuff);

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

    DMA_InitStructure.DMA_PeripheralInc = DMA_MemoryInc_Disable;

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

    DMA_InitStructure.DMA_Priority = DMA_Priority_High;

    DMA_InitStructure.DMA_BufferSize = SPI1_RX_BUFF_SIZE;

    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;

    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;

    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;

    DMA_Init(DMA2_Stream0, &DMA_InitStructure);

     

    /* Inialize NVIC for the DMA interrupt */

    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

     

    /* Connect SPI and DMA2 */

    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);

/* Enable DMA2 Channel 3 Stream 0 for the SPI1 RX */

    DMA_Cmd(DMA2_Stream0, ENABLE);

}

void SPI_PORT_DMA_RX_IRQHandler(void) // 2 Hz - for CPP use extern ''C''

{

  /* Test on DMA Stream Transfer Complete interrupt */

  if (DMA_GetITStatus(DMA2_Stream0, SPI_I2S_DMAReq_Rx))

  {

    /* Clear DMA Stream Transfer Complete interrupt pending bit */

    DMA_ClearITPendingBit(DMA2_Stream0, SPI_I2S_DMAReq_Rx);

 

    /* End of  RX */

GPIO_ToggleBits(GPIOF,GPIO_Pin_7); 

    // Add code here to process things

  }

}

#spi #stm32f4 #external-adc
5 REPLIES 5
Javad
Associate III
Posted on June 19, 2016 at 08:52

I change the last of code as follow. DAM interrupt is run but it doesn't seem to relate to the MISO pin! because I disconnect ADS7816 data out pin and the DMA has interrupt!!  

   /* Connect SPI and DMA2 */

    SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE);

/* Enable DMA transfer complete interrupt */   

    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);   //ADD THIS LINE IN NEW CODE

/* Enable DMA2 Channel 3 Stream 0 for the SPI1 RX */

    DMA_Cmd(DMA2_Stream0, ENABLE);

}

void DMA2_Stream0_IRQHandler(void)

{

  /* Test on DMA Stream Transfer Complete interrupt */

  if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))  //CHANG THIS PART IN NEW CODE

  {

    /* Clear DMA Stream Transfer Complete interrupt pending bit */

    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);

    /* Toggle LED3 : End of Transfer */

GPIO_ToggleBits(GPIOF,GPIO_Pin_7); //discovery board

    // Add code here to process things

  }

}

Posted on June 19, 2016 at 09:10

Could that be because you are still clocking the SPI interface and the STM32 just latches the voltage it sees associates with the pin regardless of what you have attached to it?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Javad
Associate III
Posted on June 19, 2016 at 10:12

I didn't understand what you mean! I disconnect the clock pin too, but interrupt is running! is my code right? I think I make some mistake in my code!

Posted on June 19, 2016 at 14:31

If the STM32 is the SPI master it is generating ALL the clocks IT is using internally. The TX and RX share the same clock, being that SPI is symetrical.

It is going to function regardless of what you attach externally, you'll just get bogus data returned in your buffer if nothing is supplying valid data.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Javad
Associate III
Posted on June 20, 2016 at 06:49

you'll just get bogus data returned in your buffer if nothing is supplying valid data

how can i fix this bug? can you please correct it?

ADS7816 is a signle chanel adc. it has just 3 pin for communication. it just send data to uc after sampling. so i don't need to send any data to it. i use spi just for receive data. I config its 3 pins as follow:

closk pin of ads7816 --> uc sck

chip seclect of ads7816 --> PA0 (when this pin is 0 adc start sampling and send it)

data out of ads7816 -->MISO of uc

I see the data that send from ads7816 when its chip select pin is 0. I don't know how can i buffer its data now! ,my code that I write it at forst post, don't work correctly, its DMA interrupt even when I power off the ads7816!!!