Well after the complete failure of my previous attempt to interface between my msp430 and the enc28j60 I decided to try again. The main problem was just not sitting down and reading the damn datasheets. To begin with I am using the ENC28J60-H which is a breakout board by Olimex. I am using the following pin out.

MSP430 ----> ENC28J60-H
GND       GND
VCC       3.3V & RST
P2.0      CS
UCB0SOMI  MISO
UCB0CLK   SCK
USB0SIMO  MOSI

The msp430 that I have chosen has a USCI instead of the basic USI that comes with the value line of msp430’s. Now for the actual code for communicating between the two. First we have the code that switches on or off the slave select this is just a small macro.

#define SEL_MAC(x)  (x==TRUE) ? (P2OUT&=(~BIT0)) : (P2OUT|=BIT0)

Now the part I had most trouble doing was actually the initialisation of the MSP430s USCI. Having come from AVRs I was used to just setting up whatever internal part I wanted to use and off I went. With the MSP430 though there are seperate registers (PxSEL) that switch where the pins are connected to. So to connect the USCI to the pin I have to change this register as well. I have also decided to not base the code off of Arduino code and am instead trying to interface using uIP IP stack. Here is my final init routine. Update from 09/02/2012: I made another mistake in the data sheet the SPI interface is said to be mode 0,0 which means that it is falling edge and therefore UCCKPH should also be set.

#define SCLK BIT3
#define SDI BIT2
#define SDO BIT1
#define CS BIT0
void initSPI(void)
{
 UCB0CTL1 = UCSWRST;
 UCB0CTL0 = UCSYNC + UCSPB + UCMSB + UCCKPH;
 UCB0CTL1 |= UCSSEL_2;
 UCB0BR0 |= 0x01;
 UCB0BR1 = 0;
 P3SEL |= SCLK + SDO + SDI;
 P3DIR |= SCLK + SDO;
 P2DIR |= CS;
 P3DIR &= ~SDI;
 UCB0CTL1 &= ~UCSWRST;
}

Note that I have the speed of the SPI interface at the same as clock speed. The minimum speed for the ENC28J60 to operate is 8MHz and I therefore had to change the DCO of the chip. To send and receive commands the following were used.

unsigned int SPIWrite(unsigned char * ptrBuffer, unsigned int ui_Len)
{
 unsigned int i;

 if (ui_Len == 0) // no data no send
 return 0;
for (i=0;i<ui_Len;i++)
 {
 UCB0TXBUF = *ptrBuffer++;
 while (! (IFG2 & UCB0TXIFG));
 }
return i;
}
unsigned int SPIRead(unsigned char * ptrBuffer, unsigned int ui_Len)
{
 unsigned int i;
for ( i=0;i<ui_Len;i++)
 {
 UCB0TXBUF = 0xff; //First send a dummy transmit byte
 while (! (IFG2 & UCB0TXIFG));
 *ptrBuffer++ = UCB0RXBUF;
 }
 return i;
}

And for a change from normal this worked first time. I now just need to setup the ENC28J60 and get a working IP stack.

Advertisements