Interfacing a mcp3301

Discussion to talk about software related topics only.
Post Reply
chrispol
Posts: 30
Joined: Mon Mar 08, 2010 8:46 am

Interfacing a mcp3301

Post by chrispol »

Hi I'm having issues reading a mcp3301 adc my init is as follows

Code: Select all

  QSPIInit( 100000,
            0x0D,         //13 bits
            0x01,         //CS 0 J2[30]
            0x01,         //1 QSPI chip select outputs return to one when not driven from the value in the current command RAM
                          //entry during a transfer (that is, inactive state is 1, chip selects are active low).
            0x00,         //0 The inactive state value of QSPI_CLK is logic level 0.
            0x01,         //1 Data changed on the leading edge of QSPI_CLK and captured on the following edge of QSPI_CLK.
            0x00,         //Default value after reset. QSPI_Dout is actively driven between transfers.
            0x00,
            0x00
          );
and i'm trying to read it as follows

Code: Select all

  WORD l_Value;

  OS_SEM QSPI_SEM;
  OSSemInit(&QSPI_SEM, 0);



  QSPIStart( NULL, (BYTE*)&l_Value, 2, &QSPI_SEM );
  OSSemPend( &QSPI_SEM, 0 );


  return l_Value;
the chip select is on J2[30] spi_cs0 on a mod5282 anyone have any ideas?

Thanks
chrispol
Posts: 30
Joined: Mon Mar 08, 2010 8:46 am

Re: Interfacing a mcp3301

Post by chrispol »

Ok got it working, now my only issue is the following

the sign bit is clocked out of the ADC on the
falling edge of the third clock pulse, followed by the
remaining 12 data bits (MSB first).

so i'm assuming i have to calculate the delay until the third clock and enter that into csToClockDelay
khoney
Posts: 125
Joined: Fri Sep 11, 2009 12:43 pm

Re: Interfacing a mcp3301

Post by khoney »

User avatar
lgitlitz
Posts: 331
Joined: Wed Apr 23, 2008 11:43 am
Location: San Diego, CA
Contact:

Re: Interfacing a mcp3301

Post by lgitlitz »

I took a quick look at the data sheet for this part. The data must be clocked in 15 bits. You should change your 13 to a 15. The csToClockDelay is how much time the peripheral will wait from the assertion of the CS signal to the first clock signal. This really has nothing to do with the adjustments you are looking at. This would be a value in the timing specs of the part but likely do not need to be adjusted.
Make sure you have set all the QSPI pins to be in the QSPI function or they will not work. You can do this with the pins class. I would also set your CS pin to be GPIO at first. Assert and de-assert it manually before and after the QSPIStart call. This will confirm if you are having issues configuring the chip select.
gavinm
Posts: 59
Joined: Wed Jun 04, 2008 4:01 pm
Location: Nottingham UK

Re: Interfacing a mcp3301

Post by gavinm »

I hate to contradict Larry ... but reading the data sheet ... (My knowledge of QSPI is from the MOD5272)
Section 7 is the relevant one - "Serial Comms"
We are all assuming you are reading the data MS bit first as well.
With this A/D the aquisition and each succesive approximation conversion is synchronised to the SPI clock (not some other internal clock) eg After CS goes active (Low), the sample and hold is triggered by the next rising edge of the Clock, the internal sample capacitors "capture" the analogue input for 1.5 clock periods and then the succesive approx conversion begins. This is a factor in why there is an important note about the minimum clock frequency. Clock the chip to slowly and you'll get errors because the sample and hold capacitors will be discharging.
So you do NOT need any QCD delay CS to first Clock (there are no Clocks during this delay so your A/D would never aquire!). The CS high (Tcsh) min time is 580ns so you could use this in the DTL delay.

Then you read 16 bits of data (Datasheet section 7.3 "Using a hardware SPI port with the MCP3301 is very easy because each conversion requires 16 clocks.")

The A/D requires the Clock to idle Low, so Clock Polarity should be 0, (CPOL= 0), and changes the data output on the falling edge (the SPI master should read on the rising edge), therefore Clock Phase should be 0, (CPHA = 0). I think you have the phase set to 1?

Once you've read the 16 bits of data mask off the top 3 bits. The MSbit (bit 15) and bit14 will have read the HiZ stae of the data output. Bit 13 is the NULL bit (always zero). Then the least significant 13 bits are the sign and 12 bits of data.

So in short change to 16 bits of data SPI mode 0,0 (Clock Polarity 0 and Clock Phase 0), make sure the the clock frequency is in range (85kHz to 850kHz) and have a min of 580ns between conversions and it should be fine

I hope this helps.
Gavin Murray
gavinm
Posts: 59
Joined: Wed Jun 04, 2008 4:01 pm
Location: Nottingham UK

Re: Interfacing a mcp3301

Post by gavinm »

Actually scrolling further down the datasheet the A/D will operate with the Clock idle state High (CPOL =1), but it always changes data on the clock falling edge so the SPI master must capture on the clock rising edge (CPHA = 0), and there should always be 16 bits (16 clock cycles).

See Datasheet Figs 7.2 7.4 and 7.5
Gavin Murray
gavinm
Posts: 59
Joined: Wed Jun 04, 2008 4:01 pm
Location: Nottingham UK

Re: Interfacing a mcp3301

Post by gavinm »

Once you've masked off the most significant 3 bits just shift the 13 bit A/D count left 3 places to give a 16 bit signed integer (short int?). Your A/D count will then vary from -32768 to +32767 in steps of 8 counts.

Some A/D families output their 10, 12 or 14 bit data justified to the left of a 16 bit word to make it easy to migrate to higher resolution A/Ds. You always work with a 16 bit count conversions of 0 to 65535 (or -32768 to +32767 if you like).
Gavin Murray
Post Reply