AnsweredAssumed Answered

SPI problem reading ADC

Question asked by JR7777 on May 18, 2015
Latest reply on May 26, 2015 by JR7777
I'am using three MAX11210 with a STM32L151VDT6 controller via SPI. I only want to read out the CTRL3 register which is by default 0x1E. If i read out the ADCs behind one another i read 0x1E, 0x1E and 0x1F... but not always, sometimes it is 0x1C, 0x1E, 0x1F, sometimes 0x1C, 0x1C, 0x1E,...
If i read out the same register of the single ADCs more than one time, i sometimes get from the first two ADCs the correct answer 0x1E each time. From the last one i get 0x1F, 0xFE, 0x1E, 0x1E, 0x1E. If i touch the CLK with an oscilloscope i get various returns from the ADCs, not only from the last ADC.
It seems to be that there is a timing issue with the STM32 and the MAX11210.

The code is the following:
void SPI_InitDriver(SPI_TypeDef* SPIx)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    SPI_InitTypeDef SPI_InitStruct;
     
    spi_On = TRUE;
     
    if (SPIx == SPI1){
        RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOEEN, ENABLE);
        GPIO_InitStructure.GPIO_Pin = MAX11210_10V_CS_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
        GPIO_HIGH(MAX11210_10V_CS_PORT, MAX11210_10V_CS_PIN); 
        GPIO_Init(MAX11210_10V_CS_PORT, &GPIO_InitStructure);
         
        RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOCEN, ENABLE);
        GPIO_InitStructure.GPIO_Pin = MAX11210_20MA_CS_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
        GPIO_HIGH(MAX11210_20MA_CS_PORT, MAX11210_20MA_CS_PIN);
        GPIO_Init(MAX11210_20MA_CS_PORT, &GPIO_InitStructure);
          
        RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOBEN, ENABLE);
        GPIO_InitStructure.GPIO_Pin = MAX11210_PT100_CS_PIN;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
        GPIO_HIGH(MAX11210_PT100_CS_PORT, MAX11210_PT100_CS_PIN); 
        GPIO_Init(MAX11210_PT100_CS_PORT, &GPIO_InitStructure);
         
        /* SPI related AF function mapping of used pins */  
        GPIO_InitStructure.GPIO_Pin = SPI1_MISO_PIN|SPI1_MOSI_PIN|SPI1_CLK_PIN;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
        GPIO_Init(SPI1_PORT, &GPIO_InitStructure);
         
        /* Select PB13/15 as SPI pins */
        GPIO_PinAFConfig(SPI1_PORT, SPI1_CLK_PINSOURCE, GPIO_AF_SPI1);
        GPIO_PinAFConfig(SPI1_PORT, SPI1_MISO_PINSOURCE, GPIO_AF_SPI1);
        GPIO_PinAFConfig(SPI1_PORT, SPI1_MOSI_PINSOURCE, GPIO_AF_SPI1);
         
        SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
        SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
        SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
        SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
        SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
        SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
 
        RCC_APB2PeriphClockCmd(RCC_APB2ENR_SPI1EN, ENABLE);
        SPI_Init(SPI1, &SPI_InitStruct);
 
        SPI_Cmd(SPI1, ENABLE);
    }
}
 
/**
  * @brief tx/rx a byte via SPI interface
  * @par byte to be tx'd
  * @retval rx'd byte
  */
uint8 SPI_TransferByte(SPI_TypeDef* SPIx, uint8 tx)
{
    uint8 rx = 0;
    while (SPI_GetFlagStatus(SPIx, SPI_FLAG_BSY) != RESET);
    SPI_SendData(SPIx, tx);
    while (SPI_I2S_GetFlagStatus(SPIx, SPI_FLAG_BSY) != RESET);
    rx = SPI_ReceiveData(SPIx);
return rx;
}


At first i send the byte to adress the CTRL3 register, after that i send dummydata 0x00 to read the answer from the ADC. The adress is always the same and is well sent. Only the answer is not always correct. The signal on the oscilloscope looks good. Sometimes if i don't touch the CLK with the oscilloscope it works fine, sometimes not.
Seems to be that there is a little timing problem with the SPI and the MAX11210. Sometimes the answer is shifted a little bit, but i don't know why.

It also won't work if i use the code clive posted in another thread
uint8_t WriteByte(uint8_t Data)
{
  /*!< Wait until the transmit buffer is empty */
  while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET);
    
  /*!< Send the byte */
  SPI_I2S_SendData(SD_SPI, Data);
    
  /*!< Wait to receive a byte*/
  while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
    
  /*!< Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SD_SPI);
}
  
uint8_t ReadByte(void)
{
  /*!< Wait until the transmit buffer is empty */
  while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET);
  
  /*!< Send the byte */
  SPI_I2S_SendData(SD_SPI, SD_DUMMY_BYTE);
  
  /*!< Wait until a data is received */
  while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  
  /*!< Return the byte read from the SPI bus */
  return SPI_I2S_ReceiveData(SD_SPI);
}


With the ATMEL ATMEGA16 all works fine, also with a raspberry pi. Only with the STM32 it won't work. If i use a single ADS8320 converter instead it works without a problem. The problem also occurs with one MAX11210 converter at the SPI.

Do you have any ideas how i can fix this issue? I don't have any idea how i can handle this. #Help

Outcomes