chipKIT® Development Platform

Inspired by Arduino™

SPI 16-bit communication

Created Tue, 08 May 2012 14:46:20 +0000 by Mishi


Mishi

Tue, 08 May 2012 14:46:20 +0000

Hello,

How can I set my chipKit Uno32 SPI bus to 16-bit communication?

Thank you!

Mishi


hdphilip

Wed, 09 May 2012 00:00:45 +0000

Mishi

good question, i've been working on it also for a couple of days now, i have no problem with 8 bit transfers, I've just use to of them back to back and shift the bits.

I even added a function into the dspi library to set the data mode to 16 bits or 32 bits, I can see the 16 bits and 32 bits (sclk) on my logic anaylzer, but reading the data, i just havn't been able to do it. I wouldn't think it would be to hard to do.

might have to try it in mplab....

Philip


Ryan K

Wed, 09 May 2012 01:59:24 +0000

Hello,

Try this, I haven't tested this at all let me know if it works. It is basically the DSPI functions copied over with a change to the SPI2CON register so that it works with 16-bit transfers.

#include <DSPI.h>

#define SPI_BAUD 1000000
#define SS_PIN 10 //Set to whatever slave select is attached to.

uint16_t wRcv;
uint16_t wSnd;

void setup()
{
  SPI2CON = 0;
  SPI2BRG = ((F_CPU/(2* SPI_BAUD)) - 1);
  SPI2CONSET = DSPI_MODE0; //Whatever mode you want
  SPI2CONSET = (1 << 15) | (1 << 10);
}

void loop()
{
  wRcv = spiTransfer(wSnd);
}

uint16_t spiTransfer(uint16_t wVal)
{
  volatile int cnt;
  
  digitalWrite(SS_PIN, LOW);
  
  for(cnt = 0; cnt < 100; cnt++)
  {
  }
  
  while ((SPI2STAT & (1 << _SPISTAT_SPITBE)) == 0) {
  }
  SPI2BUF = wVal;

  while ((SPI2STAT & (1 << _SPISTAT_SPIRBF)) == 0) {
  }
  
  digitalWrite(SS_PIN, HIGH);

  return SPI2BUF;
}

Best Regards, Ryan K Digilent


hdphilip

Wed, 09 May 2012 02:22:04 +0000

hello Ryan k

Thanks i'll give it a try,

do you know if when the spi mode is selected for 16 bits, does it set the buffer width to match also?

here's the code i added to the dspi library dspi.cpp

/* ------------------------------------------------------------ */
/***	DSPI::setTransferCharWidth
**
**	Parameters:
**		cmod		- requested SPI mode.
**
**	Return Value:
**		none
**
**	Errors:
**		none
**
**	Description:
**		Set the SPI controller to the requested data mode. This
**		should be one of the values:Word/Byte Communication mode
**     DSPI_MODE32,DSPI_MODE16
**			
*/

void
DSPI::setTransferCharWidth(uint16_t cmod) {

	
	pspi->sxCon.clr = (1 << _SPICON_ON);
	pspi->sxCon.set = cmod;		// set the requested mode
	pspi->sxCon.set = (1 << _SPICON_ON);
	}

and in the dspi.h

#define DSPI_CMODE32 (SPICON_MODE32) #define DSPI_CMODE16 (SPICON_MODE16)

public: void setTransferCharWidth(uint16_t cmod);

Philip


Ryan K

Wed, 09 May 2012 02:44:35 +0000

Hello Philip,

The SPI2BUF is always 32-bits it is just that bits 10 and 11 determines how much of it to grab. If you are talking about the parameters for transmit and the other member functions, that will probably have to be changed to use templates.

Best Regards, Ryan K Digilent


hdphilip

Wed, 09 May 2012 05:13:31 +0000

Thanks Ryan

got it working :D

it's for metal detector project i'm working on, here's the code that worked, i used my modified dspi library with your code, i'm going to try to add your code in the dspi library.

#include <plib.h>
#include <DSPIa.h>
//#define SS_PIN 9

int i;
uint16_t wRcv;
uint16_t wSnd;

DSPI0    spi;

void setup(){
  PORTSetPinsDigitalOut(IOPORT_D, BIT_3);
  pinMode(SS_PIN, OUTPUT);
     
  spi.begin();
  spi.setSpeed(8000000); // 8 mhz spi clock
  spi.setMode(DSPI_MODE0);
  spi.setTransferCharWidth(DSPI_CMODE16); // added to the dspi
   
  Serial.begin(19200);
}
void loop()
{
  wRcv = spiTransfer(wSnd);
}

uint16_t spiTransfer(uint16_t wVal)
{
  volatile int cnt;
   mPORTDClearBits(BIT_3);
   mPORTDSetBits(BIT_3);    // starts conversion of adc
  for(i=0;i<26;i++){       // fine tunes converision pulse width   
    Nop();
  }
  mPORTDClearBits(BIT_3);
    
  for(cnt = 0; cnt < 1; cnt++)
  {
  }
  
  while ((SPI2STAT & (1 << _SPISTAT_SPITBE)) == 0) {
  }
  SPI2BUF = wVal;

  while ((SPI2STAT & (1 << _SPISTAT_SPIRBF)) == 0) {
  }
    
 Serial.println(SPI2BUF,HEX);  
  return SPI2BUF;
}

i have some more work to do, but, i think i'm in the right direction

Philip


Ryan K

Thu, 10 May 2012 00:27:12 +0000

Hello Philip,

I actually plan to overload the DSPI library so that it will hopefully have this functionality in the next full release of MPIDE. :) If you'd like I can post a pre-release build when I'm done with it.

Best Regards, Ryan K Digilent