Weird SPI problem, MCP4802 DAC

I took the AudioZero library to play music. Works great with SPI.
I wrote my own custom SPI code in software to interface with a Microchip DAC IC (MCP4802), and I am able to send data and see output voltages no problem.

So now I tried to use both at SD Card + MCP8402 on SPI at once but it didn't work. Then I tried to just get SPI working with the MCP4802 chip and removing the sd card completely from the circuit. It won't work either, despite using some of the libraries people released specifically for the MCP4802.
I'm confused why I can use all 3 pins and performs transfers myself but not with SPI. I have tried various different bus speeds, though 20Mhz is in the MCP datasheet. I have tried other CS pins, I tried swapping MOSI/MOSO in case I was wrong about which direction. Nothing working.

My code here that works with software SPI.


#define MCP4802_CS  10
#define MCP4802_SCK 12
#define MCP4802_SDI 13

inline void WriteCommandA(unsigned char voltage, char channel)
{
  // gain of 2x and output allowed on Channel A
  unsigned char command = 0b00010000;
 
  digitalWrite(MCP4802_SCK, LOW);
  digitalWrite(MCP4802_CS, HIGH);

  
  //Start writing data. Pull Chip Select low.
  digitalWrite(MCP4802_CS, LOW);

  //CLOCK 4-command bits
  for(int i = 0; i < 4;i++)
  {
    // Reset the clock.
    digitalWrite(MCP4802_SCK, LOW); 

    if((command & 0b10000000) == 0b10000000)
    {
      digitalWrite(MCP4802_SDI, HIGH);
    }
    else
    {
      digitalWrite(MCP4802_SDI, LOW);
    }
    // Clock data in.
    digitalWrite(MCP4802_SCK, HIGH);
    command = command << 1;
  }


  // CLOCK data voltage
  for(int i = 0; i < 8;i++)
  {
    // Reset the clock.
    digitalWrite(MCP4802_SCK, LOW);

    if((voltage & 0b10000000) == 0b10000000)
    {
      digitalWrite(MCP4802_SDI, HIGH);
    }
    else
    {
      digitalWrite(MCP4802_SDI, LOW);
    }
    // Clock data in.
    digitalWrite(MCP4802_SCK, HIGH);
    voltage = voltage << 1;
  }

  //perform the extra 4 unused bits
  digitalWrite(MCP4802_SCK, LOW);
  digitalWrite(MCP4802_SCK, HIGH);
  digitalWrite(MCP4802_SCK, LOW);
  digitalWrite(MCP4802_SCK, HIGH);
  digitalWrite(MCP4802_SCK, LOW);
  digitalWrite(MCP4802_SCK, HIGH);
  digitalWrite(MCP4802_SCK, LOW);
  digitalWrite(MCP4802_SCK, HIGH);
 
  //Done writing data. Pull Chip Select high.
  digitalWrite(MCP4802_CS, HIGH);
  digitalWrite(MCP4802_SCK, LOW);
}

And here is the condensed code from the MCP library I got that will NOT work for some reason. From what I can tell this is the basic code I need to do SPI transfer from all the examples I found.

  pinMode(chipSelect, OUTPUT);
  digitalWrite(chipSelect, HIGH);
  SPI.begin();

// DATA TRANSFER 
  digitalWrite(chipSelect, LOW);

   SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE0));
   SPI.transfer((uint8_t)(data >> 8));
   SPI.transfer((uint8_t)(data & 0xFF));
   SPI.endTransaction();
  digitalWrite(chipSelect, HIGH);

I don't know if this is your specific problem but the SD boards availiable on eBay do not tristate the MISO line.

Yea I googled this issue with chaining multiple slaves, but I'm not even at that point just yet. For no reason I couldn't get SPI working with one slave, the DAC IC.

Is it the responsibility of the SD card or the SD boards to fix the tri-state issue? Any reference on how I can add a circuit to disable the SD card myself with multiple slaves? Simple transistor or something?

Ok I see I can add something like a "SN74AHC1G125" IC so that it is will fix multiple SPI chips.

Frustrating but most cards have the 74HC125 IC. But they didn't connect the MISO line enable to chip select.
There is a "fix" but you need a steady hand.
You have to solder a #30 to that pin and jumper it to chip select. Can be done but its a PIA.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.