title: SPI Extra Clock Cycle over communication between STM32 Nucleo L432KC and MAX31865 ADC
body: <p>The setup that I'm working with is a Nucleo L432KC connected to 8 different MAX31865 ADCs to get temperature readings from RTDs (resistive thermal devices). Each of the 8 chip selects is connected to its own pin, but the SDI/SDO of all chips are connected to the same bus, since I only read from one at a time (only 1 chip select is enabled at a time). For now, I am using a 100 ohm base resistor in the Kelvin connection, not an RTD, just to ensure an accurate resistance reading. The read from an RTD comes from calling the function rtd.read_all(). When I read from one and only one RTD, I get an accurate reading and an accurate SPI waveform (pasted below):</p>
  <p><a href="https://i.stack.imgur.com/JWWCq.jpg" rel="nofollow noreferrer">correct SPI reading for 1 ADC</a>
  (yellow is chip enable, green is clock, blue is miso, purple is mosi)</p>
  <p>However, when I read from 2 or more sequentially, the SPI clock for some reason gains an additional unwanted cycle at the start of the read that throws off the transmitted values. It's been having the effect of shifting the clock to the right and bit-shifting my resistance values to the left by 1.</p>
  <p><a href="https://i.stack.imgur.com/o3KoR.jpg" rel="nofollow noreferrer">Logic analyzer reading of SPI; clock has additional cycle at start</a></p>
  <p>What could be causing this extra clock cycle? I'm programming in C++ using mbed. I can access the SPI.h file but I can't see the implementation so I'm not sure what might be causing this extra clock cycle at the start. If I need to add the code too, let me know and I'll edit/comment.</p>
  <p>rtd.read_all() function:</p>
  <pre><code>uint8_t MAX31865_RTD::read_all( )
  {
    uint16_t combined_bytes;
  
    //SPI clock polarity/phase (CPOL &amp; CPHA) is set to 11 in spi.format (bit 1 = polarity, bit 0 = phase, see SPI.h)
    //polarity of 1 indicates that the SPI reading idles high (default setting is 1; polarity of 0 means idle is 0)
    //phase of 1 indicates that data is read on the first edge/low-to-high leg (as opposed to phase 0,
    //which reads data on the second edge/high-to-low transition)
    //see https://deardevices.com/2020/05/31/spi-cpol-cpha/ to understand CPOL/CPHA
  
    //chip select is negative logic, idles at 1
    //When chip select is set to 0, the chip is then waiting for a value to be written over SPI
    //That value represents the first register that it reads from
    //registers to read from are from addresses 00h to 07h (h = hex, so 0x01, 0x02, etc)
    //00 = configuration register, 01 = MSBs of resistance value, 02 = LSBs of
    //Registers available on datasheet at https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
    //The chip then automatically increments to read from the next register
  
    /* Start the read operation. */
    nss = 0; //tell the MAX31865 we want to start reading, waiting for starting address to be written
    /* Tell the MAX31865 that we want to read, starting at register 0. */
    
    
    spi.write( 0x00 ); //start reading values starting at register 00h
  
    /* Read the MAX31865 registers in the following order:
         Configuration (00)
         RTD (01 = MSBs, 02 = LSBs)
         High Fault Threshold (03 = MSBs, 04 = LSBs)
         Low Fault Threshold (05 = MSBs, 06 = LSBs)
         Fault Status (07) */
      
      this-&gt;measured_resistance = 0;
  
    this-&gt;measured_configuration = spi.write( 0x00 ); //read from register 00
      //automatic increment to register 01
    combined_bytes  = spi.write( 0x00 ) &lt;&lt; 8; //8 bit value from register 01, bit shifted 8 left
      //automatic increment to register 02, OR with previous bit shifted value to get complete 16 bit value
    combined_bytes |= spi.write( 0x00 );
    //bit 0 of LSB is a fault bit, DOES NOT REPRESENT RESISTANCE VALUE
    //bit shift 16-bit value 1 right to remove fault bit and get complete 15 bit raw resistance reading
    this-&gt;measured_resistance = combined_bytes &gt;&gt; 1;
      //high fault threshold
    combined_bytes  = spi.write( 0x00 ) &lt;&lt; 8;
    combined_bytes |= spi.write( 0x00 );
    this-&gt;measured_high_threshold = combined_bytes &gt;&gt; 1;
      //low fault threshold
    combined_bytes  = spi.write( 0x00 ) &lt;&lt; 8;
    combined_bytes |= spi.write( 0x00 );
    this-&gt;measured_low_threshold = combined_bytes &gt;&gt; 1;
      //fault status
    this-&gt;measured_status = spi.write( 0x00 );
  
      //set chip select to 1; chip stops incrementing registers when chip select is high; ends read cycle
    nss = 1;
  
    /* Reset the configuration if the measured resistance is
       zero or a fault occurred. */
    if(    ( this-&gt;measured_resistance == 0 )
        || ( this-&gt;measured_status != 0 ) )
    {
      //reconfigure( );
      // extra clock cycle causes measured_status to be non-zero, so chip will reconfigure even though it doesn't need to. reconfigure commented out for now.
    }
  
    return( status( ) );
  }
  </code></pre>