AnsweredAssumed Answered

SPI Strange behaviour

Question asked by lombardini.luca on Dec 6, 2012
Latest reply on Dec 6, 2012 by lombardini.luca
Hi all,

To read or write a register of ADS1298 I need to write 3 byte on SPI bus and I need some delay between every byte. Based on the discovery example I write the following read and write routine:

uint8_t ADS1298ReadRegister(uint8_t ChipNumber, uint8_t Register){
  uint8_t RxRegister;                             
 
//  SPI_Cmd(SPI1,ENABLE);  
  if (ChipNumber == ADS1298_1)
    SPI1_CS1_LOW();
   else
   SPI1_CS2_LOW();
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   SPI_I2S_SendData(SPI1, (uint16_t)(ADS1298_CMD_RREG + Register));
//   SPI_I2S_SendData(SPI1, 0x0000);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   SPI_I2S_ReceiveData(SPI1);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   for (int i=0;i<200;i++);
   SPI_I2S_SendData(SPI1,  0x0a);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   SPI_I2S_ReceiveData(SPI1);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   for (int i=0;i<200;i++);
   SPI_I2S_SendData(SPI1, 0x05);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   RxRegister = SPI_I2S_ReceiveData(SPI1);
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

   if (ChipNumber == ADS1298_1)
    SPI1_CS1_HIGH();
   else
    SPI1_CS2_HIGH();
//  SPI_Cmd(SPI1,DISABLE);
  return RxRegister;
}

uint8_t ADS1298WriteRegister(uint8_t myChipNumber, uint8_t Register,
                             uint16_t Value,uint8_t verify){
  uint8_t RxRegister;                             
//  SPI_Cmd(SPI1,ENABLE);  
  if (myChipNumber == ADS1298_1)
    SPI1_CS1_LOW();
  else
    SPI1_CS2_LOW();
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    SPI_I2S_SendData(SPI1, (uint16_t)(ADS1298_CMD_WREG + Register));
//    SPI_I2S_SendData(SPI1, 0x0000);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   SPI_I2S_ReceiveData(SPI1);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   for (int i=0;i<200;i++);
   SPI_I2S_SendData(SPI1, 0x0a);
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   SPI_I2S_ReceiveData(SPI1);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
   for (int i=0;i<200;i++);
   SPI_I2S_SendData(SPI1, Value);
   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
   SPI_I2S_ReceiveData(SPI1);
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
//   while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET);
  if (myChipNumber == ADS1298_1)
    SPI1_CS1_HIGH();
   else
    SPI1_CS2_HIGH();

//  SPI_Cmd(SPI1,DISABLE);
    for (int i=0;i<300;i++);
//    SPI_Cmd(SPI1,ENABLE);
    if (verify){
      RxRegister = ADS1298ReadRegister(myChipNumber,Register);
      if (RxRegister == Value)
        return 0;
      else
        return 1;
    }
  return 0;
  }
When I tested these two routine reading and writing the ADS1298 register I found that sometimes I have 16 clock cicle on the bus while I setting the SPI size at 8 bit (see Below)
  // ADS1298 CPOL bit is a '0' and its CPHA bit is a '1'.
  SPI_I2S_DeInit(SPI1);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
//  SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
 //SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;
//  SPI_InitStructure.SPI_CRCPolynomial = 0;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_Init(SPI1, &SPI_InitStructure);

Could someone help my to find the root cause of this wrong SPI behaviour?
I sperimentally found that if I set the SPI first bit with LSB the problem disappear.

Thanks
Luca

Below the oscilloscope image. On ch1 there is the CS while on ch2 there is the SPI Clock

Write Register correct


Write problem

READ CORRECT


READ PROBLEM






Outcomes