7 years, 6 months ago.

Can't get MCP3913 to talk to mbed via SPI

EDIT: Nevermind. Finally sorted it out. I got goofed up by the 5 bit register addresses when I was laying out my control bytes, mistakenly using 4 bit addresses for the ADC data registers. So my 7-bit (unpadded) control 'byte' of 0x21 (0100001) was meaningless. The appropriate control byte instead being 0x41 (01000001). Getting plenty of data on MISO now. Sigh. It's always something silly..

Original post: I'm trying to interface the MCP3913 AFE (datasheet: http://tinyurl.com/j2tjf5z) with the mbed via SPI (I've tried with both an LPC1768 and a KL25Z). No matter what I try, I get nothing on the MISO line from the AFE.

The relevant code I'm using to test on the mbed (LPC1768):

title

#include "mbed.h"

//ADC SPI communications setup
SPI adcSPI(p5, p6, p7); // mosi, miso, sck
DigitalOut adcCS(p8);
DigitalIn adcDR(p9);

int adcValueCh0a = 0;
int adcValueCh0b = 0;
int adcValueCh0c = 0;
int adcValueCh0 = 0;

int adcValueCh1a = 0;
int adcValueCh1b = 0;
int adcValueCh1c = 0;
int adcValueCh1 = 0;

int adcValueCh2a = 0;
int adcValueCh2b = 0;
int adcValueCh2c = 0;
int adcValueCh2 = 0;

int adcValueCh3a = 0;
int adcValueCh3b = 0;
int adcValueCh3c = 0;
int adcValueCh3 = 0;

int adcValueCh4a = 0;
int adcValueCh4b = 0;
int adcValueCh4c = 0;
int adcValueCh4 = 0;

int adcValueCh5a = 0;
int adcValueCh5b = 0;
int adcValueCh5c = 0;
int adcValueCh5 = 0;

int adcFlag = 1;


void adc_setup(void){
    adcCS = 1;  
    adcSPI.format(8,3);
    adcSPI.frequency(500000); 
        
    // Write CONFIG0 register
    adcCS = 0;
    adcSPI.write(0x3A); 
    adcSPI.write(0x39); 
    adcSPI.write(0xE0); 
    adcSPI.write(0x50); 
    adcCS = 1; 
    
    // Write CONFIG1 register
    adcCS = 0; 
    adcSPI.write(0x3E); 
    adcSPI.write(0x00); 
    adcSPI.write(0x00); 
    adcSPI.write(0x40); 
    adcCS = 1; 
    }
       
void get_adc_value(void){
    adcCS = 0; 
    adcSPI.write(0x21); 
    adcValueCh0a = adcSPI.write(0xFF);
    adcValueCh0b = adcSPI.write(0xFF);
    adcValueCh0c = adcSPI.write(0xFF);
    adcValueCh0 = adcValueCh0a * 65536 + adcValueCh0b * 256 + adcValueCh0a;
    
    adcSPI.write(0x23); 
    adcValueCh1a = adcSPI.write(0xFF);
    adcValueCh1b = adcSPI.write(0xFF);
    adcValueCh1c = adcSPI.write(0xFF);
    adcValueCh1 = adcValueCh1a * 65536 + adcValueCh1b * 256 + adcValueCh1a;
    
    adcSPI.write(0x25); 
    adcValueCh2a = adcSPI.write(0xFF);
    adcValueCh2b = adcSPI.write(0xFF);
    adcValueCh2c = adcSPI.write(0xFF);
    adcValueCh2 = adcValueCh2a * 65536 + adcValueCh2b * 256 + adcValueCh2a;
    
    adcSPI.write(0x27); 
    adcValueCh3a = adcSPI.write(0xFF);
    adcValueCh3b = adcSPI.write(0xFF);
    adcValueCh3c = adcSPI.write(0xFF);
    adcValueCh3 = adcValueCh3a * 65536 + adcValueCh3b * 256 + adcValueCh3a;
    
    adcSPI.write(0x29); 
    adcValueCh4a = adcSPI.write(0xFF);
    adcValueCh4b = adcSPI.write(0xFF);
    adcValueCh4c = adcSPI.write(0xFF);
    adcValueCh4 = adcValueCh4a * 65536 + adcValueCh4b * 256 + adcValueCh4a;
    
    adcSPI.write(0x2B); 
    adcValueCh5a = adcSPI.write(0xFF);
    adcValueCh5b = adcSPI.write(0xFF);
    adcValueCh5c = adcSPI.write(0xFF);
    adcValueCh5 = adcValueCh5a * 65536 + adcValueCh5b * 256 + adcValueCh5a;
    
    adcCS = 1;
    }
    
int main() {
    adc_setup();
  
    while (1){
        if (!adcDR){
            adcFlag = 1;
            get_adc_value();
            }
        else if (adcDR and adcFlag == 1){
            adcFlag = 0;
            }
       }
    }

Here is a schematic of my connections to the MCP3913:

https://s12.postimg.org/4dtohgo0b/image.png

Here is what I'm getting on my logic analyzer:

https://s12.postimg.org/v93pwd4zv/image.png

https://s12.postimg.org/yh879er9n/image.png

https://s12.postimg.org/5u56zlqx7/image.png

(the last picture shows a weird blip I see inconsistently on the !DR pin, I'm not sure if it's diagnostically relevant).

I've tried various SPI rates (between 500KHz and 10MHz), both 0,0 and 1,1 SPI modes, and a handful of code iterations (raising !CS between reads, looping through read registers, addressing read registers individually, etc.).

I've tried adding pull ups/downs on the !DR, !CS, and !RESET lines, (even when they're internally pulled / high impedance). I was forced to add a pull down to the MISO line, to clear up erroneous blips when left floating in a high-impedance state.

I can not get any kind of SPI output from this thing. I've tried two separate MCP3913s, one on a development board and the other on a SOIC-to-DIP breakout board (both soldered with extreme care). I've attempted all aforementioned iterations both with the KL25Z and the mbed (LPC1768). I'm ready to pull my hair out, and I'm desperate for help. Ideas?

My thanks in advance.

1 Answer

7 years ago.

Hi!

Why your CONTROL-byte is 0x3A ? By the datasheet - CONTROL-byte must be: <7:6> = Dev_Addr (for MCP39xx is always = 01) <5:1> = Reg_Addr (for example CONFIG0 = 01101) <0> = R/W bit (1=read, 0=write)

If you want to write to CONFIG0 - CONTROL-byte must be 0x5A (b'01011010').