SPI headaches

Good afternoon!

Does anybody have any experience of connecting an external ADC (like MCP3008) to Arduino over SPI using SPI built-in library?
The problem is:
When I manage SPI by hand (bit banging on the lines) the resulting ADC value for a sensor is correct and nearly to a single bit the same as the one from the on-board ADC (A0).
But, if I try to use the standard SPI library the resulting value is way different from the value of A0.

Here is the variant with .transfer(byte). .transfer(buffer, 3) gives the same result:

uint16_t queryMCP(int chan) {
  byte cmd, val;
  uint16_t adc = 0;
  
  cmd = (0x18 | chan) << 3;
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  digitalWrite(chipSelect, LOW);
  val = SPI.transfer(cmd);
  adc = (val & 3) << 9;
  val = SPI.transfer(0);
  adc |= (val & 0xff) << 1;
  val = SPI.transfer(0);
  adc |= (val >> 7) & 0x1;
  digitalWrite(chipSelect, HIGH);
  SPI.endTransaction();
  return (adc & 0x3ff);
}

Kit: Arduino Uno, MCP3008.
P.S.: 6 A ports is not enough for my project :frowning:

I'm not sure about this. I think most Arduino boards will not be able to handle 10MHz on the SPI bus. Try 4MHz.

// change this
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
// to this
SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));

@SurferTim - Oh yes! The only way I could bring the values close enough was to drop the speed well down to 1MHz(!) And THAT surprises me a lot... will try it on 32u4 for a change.

@Hackscribble - The code there is very much the same as mine, just nicely aligned to byte-by-byte operation, as the MCP datasheet suggests for communication with some PICs - just less bit shifting.

Not to bother really, should read datasheets more accurately. Clock frequency for the MCP3008 @5Vdd is 3.6MHz and 1.35MHz @2.7V. Uno is not to be blamed here.