CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

spi_xfer() with wiznet Wiz812MJ
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

spi_xfer() with wiznet Wiz812MJ
PostPosted: Thu Nov 12, 2009 10:15 pm     Reply with quote

I'm trying to interface dsPIC33FJ128GP802 with Wiz812MJ module using software SPI, as hardware SPI isnt available on this chip. I've never worked with this chip or SPI before so I am having a hard time getting spi to work.
All I want to do at this point is to write a value into one of the registers of Wiz812, read it back in to a variable, then display it on an oscilloscope to verify I can do the reads and writes correctly.
Here's the code I have so far:
Code:

#include <33fj128gp802.h>
#include "w5100_pic.h"
#fuses HS, NOWDT, PR_PLL
#use delay (clock=40M, osc=20M)

#use spi (DI=PIN_B10, DO=PIN_B9, CLK=PIN_B8, MODE=0, STREAM=xfer, BITS=16)

void main()
{
   char d=0x55;
   char data;
   
   //Reset Wiz812, pin B12 connected to reset pin of wiznet
   output_low(PIN_B12);delay_us(10);
   output_high(PIN_B12); delay_ms(2);
   
   //Write into SIPR0 register address
   output_low(PIN_B11); delay_us(50);  //  /SCS slave select         
      spi_xfer(xfer, 0xF0, 8);           // opcode  for write
      spi_xfer(xfer, SIPR0, 16);        //address, 2 bytes
      spi_xfer(xfer, d, 8);            //data, 1 byte
   output_high(PIN_B11); delay_us(50);  //  /SCS deselect slave
   
   //Read from SIPR0
   output_low(PIN_B11); delay_us(50);  //  /SCS
      spi_xfer(xfer, 0x0F, 8);        // opcode  for read
      spi_xfer(xfer, SIPR0, 16);     //address, 2 bytes
      data=spi_xfer(xfer,0, 8);      //read data, 1 byte     
   output_high(PIN_B11);    //  /SCS
   delay_us(50);
 
   //check data on oscilloscope
   while(1){
      spi_xfer(xfer, data, 8); delay_ms(1);     
   }
}


I have SDO pin of MCU connected to an oscilloscope and am trying to see if i can get a stream of 01010101, which is the data read from the register. But i am getting no results.
If i replace 'data' with 'd' inside while loop, then i see what i want on the oscilloscope since d=0x55; this means that my #use spi directives and spi_xfer() are working correctly.

If anyone could give me any clues on what i'm doing wrong here i would greatly appreciate it. Thanks in advance.
BTW the compiler I'm using is CCS PCD C Compiler, Version 4.084, 27892.

Here are some links which may be useful:

SPI application notes for Wiz812 (please note that this is written for older Wiz810MJ which needs an enable bit to be set and unset for slave to work, but Wiz812MJ doesnt need this enable bit)
http://www.wiznet.co.kr/en/library04_view.php?&ss[st]=1&ss[sc]=1&ss[t]=search&kw=spi&bd_num=20170

Wiz812MJ datasheet
http://www.wiznet.co.kr/en/library04_view.php?&ss[st]=1&ss[sc]=1&ss[t]=search&kw=wiz812&bd_num=19029

Here is some part of Wiz812MJ header file w5100_pic.h:
Code:

#define COMMON_BASE   0x0000

//*
//* Gateway IP Register address
//*
#define GAR0            (COMMON_BASE + 0x0001)
//*
//* Subnet mask Register address
//*
#define SUBR0         (COMMON_BASE + 0x0005)
//*
//* Source MAC Register address
//*
#define SHAR0            (COMMON_BASE + 0x0009)
//*
//* Source IP Register address
//*
#define SIPR0            (COMMON_BASE + 0x000F)
//*
//* Interrupt Register
//*
#define IR               (COMMON_BASE + 0x0015)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 12, 2009 11:32 pm     Reply with quote

Quote:

I'm trying to interface dsPIC33FJ128GP802 with Wiz812MJ module using
software SPI, as hardware SPI isnt available on this chip.

I downloaded the data sheet for that PIC:
http://ww1.microchip.com/downloads/en/DeviceDoc/70292C.pdf
There is a table of features near the front of the data sheet and it says:
Code:

    Device            Remappable Peripheral
                             SPI

dsPIC33FJ128GP802             2
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Thu Nov 12, 2009 11:39 pm     Reply with quote

Thanx for ur reply PCM Programmer. I guess I'm still confused with hardware vs. software spi.
The pin layout on the datasheet doesn't show any SDO, SCK, SDI or SS pins. It however does say that those pins are PPS remappable, so I instead used pins TDO, TCK, TDI and RB11 respectively for my SPI.
Thats why I decided to go with #use spi() and thought they are for software spi, although I am aware that you can use FORCE_HW to use the hardware module.
Also, I'm using a 28-pin SDIP, and I'm not using any pull-up or pull-down resistors for any of the pins, am not sure if that makes any difference.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 13, 2009 2:09 am     Reply with quote

You should specify the pins to be used for the four hardware SPI signals
with #pin_select statements. Then you can use hardware SPI.
This assumes that #pin_select is working for your PIC and your
version of the compiler.

I can't really help much more, because I don't have the PCD compiler
and therefore I can't test it.
Guest








PostPosted: Fri Nov 13, 2009 11:08 pm     Reply with quote

Thanks for that hint PCM programmer, my reads and writes are now working, and I'm using setup_spi() instead of #use_spi(). Thanks again!!
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

still not working
PostPosted: Wed Nov 18, 2009 6:15 pm     Reply with quote

I thought I had it working last weekend but I was mistaken. What I saw in the oscilloscope from SDO were just spikes separated by 2ms, or in other words, I'm seeing the pulse rise for one cycle(25us in my case) then die down to 0, then this repeats every 2ms according to my code. I also sent this pulse to hyperterminal using PIC kit2 UART tool and it translates to hex value 0x80.

It doesnt matter what data I send as input, I always get the same result. I've tried many things like changing SPI clock value in setup_spi(), putting delays after spi_write() statements, putting while(!spi_data_is_in()); after spi_write(), etc. but I am getting nowhere.

Could anyone please give me any ideas on what I'm doing wrong here? Thanks a lot.

Here's my code:
Code:

#include <33fj128gp802.h>
#include "w5100_pic.h"
#fuses HS, NOWDT, PR_PLL
#use delay (clock=40M, osc=20M)

#pin_select SCK1OUT=PIN_B8
#pin_select SDI1=PIN_B10
#pin_select SDO1=PIN_B9
#pin_select SS1OUT=PIN_B11
#define SS PIN_B11
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)    //SPI_XMIT_L_TO_H is not defined in this PIC's header file

char data=0x55;

void main()
{
   BYTE i;
   
   //Reset Wiz812
   output_low(PIN_B12);delay_us(10);
   output_high(PIN_B12); delay_ms(3);
   output_high(SS); delay_us(20);
   
   setup_spi(SPI_MASTER | SPI_L_TO_H);
   
   //Write into SIPR0 register address
   output_low(SS); delay_us(50);  //  /SCS slave select
      spi_write(0xF0);                     // opcode  for Write
      i=((SIPR0 & 0xFF00) >> 8);             //MSB
      spi_write(i);
      i=(SIPR0 & 0x00FF);                    //LSB
      spi_write(i);
      spi_write(data);
   output_high(SS); delay_us(50);  //  /SCS deselect slave
   
   //Read from SIPR0
   output_low(SS); delay_us(50);  //  /SCS
      spi_write(0x0F);                     // opcode  for Read
      i=((SIPR0 & 0xFF00) >> 8); spi_write(i);
      i=(SIPR0 & 0x00FF);        spi_write(i);
      while(!spi_data_is_in());
         data=spi_read();                // read data     
   output_high(SS);    //  /SCS
   delay_us(50);
 
   //check data on oscilloscope
   while(1){
          spi_write(data); delay_ms(2);
       }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 18, 2009 7:00 pm     Reply with quote

Can you post the declaration statement for 'SIPR0' ?
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Wed Nov 18, 2009 7:02 pm     Reply with quote

SIPR0 is the IP register address on wiz812MJ. It's defined as 0x000F.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 18, 2009 8:04 pm     Reply with quote

Can you post actual line in your program that defines it or declares it ?
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Wed Nov 18, 2009 8:22 pm     Reply with quote

I had pasted some part of w5100_pic.h in the original post but here's a bit of it again:
Code:

#define COMMON_BASE   0x0000
//* Source MAC Register address
//*
#define SHAR0            (COMMON_BASE + 0x0009)
//*
//* Source IP Register address
//*
#define SIPR0            (COMMON_BASE + 0x000F)
//*
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 12:35 am     Reply with quote

I don't think your code will work. The following code fits the
WIZ812MJ data sheet and SPI appnote that you posted.
The WIZ812MJ is the name of a small demo board. The actual
chip on it is the Wiznet W5100. That's what you want to write
a test program for. The W5100 data sheet is available here:
http://ohm.bu.edu/~hazen/DataSheets/WIZnet/

I don't have your PIC or the PCD compiler, so I wrote this
code for the 18F452. The W5100 should be connected to
the hardware SPI module pins on the 18F452. I don't have
the Wiznet board, so I can't test the program given below.
But it's more likely to work than your code.

Your version of the PCD compiler, vs. 4.084, is likely to be
buggy. You would be fighting PCD bugs and be trying to
bring up a new chip.

I don't have the PCD compiler so I don't know how to select
SPI mode 0 with your PIC. I don't think it's the same as for
the 16F and 18F PICs.
Code:

#include <18F452.h>
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=4000000) 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

// SPI modes (for 16F and 18F PIC's with CCS)
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

// PIC pins assigned to W5100 signals.
#define W5100_CS     PIN_B0
#define W5100_RESET  PIN_B1
     
// W5100 Commands (from W5100 data sheet).
#define W5100_WRITE_CMD  0xF0
#define W5100_READ_CMD   0x0F

// W5100 Register addresses (from W5100 data sheet).
#define W5100_MR_REG   0x0000
#define W5100_GAR0_REG 0x0001
#define W5100_GAR1_REG 0x0002
#define W5100_GAR2_REG 0x0003
#define W5100_GAR3_REG 0x0004
// etc.

// This routine writes 1 byte of data to a W5100 register
// at the specified register address.
void w5100_write_reg(int16 addr, int8 data)
{
output_low(W5100_CS);
spi_write(W5100_WRITE_CMD);
spi_write(addr >> 8);  // Send address msb
spi_write(addr);       // Send address lsb
spi_write(data);       // Write data to W5100
output_high(W5100_CS);
}

// This routine reads 1 byte of data from a W5100 register
// at the specified register address.
int8 w5100_read_reg(int16 addr)
{
int8 retval;

output_low(W5100_CS);
spi_write(W5100_READ_CMD);
spi_write(addr >> 8);  // Send address msb
spi_write(addr);       // Send address lsb
retval = spi_read(0);  // Read data from W5100
output_high(W5100_CS);

return(retval);
}

//==================================
void main()
{
int8 gar0, gar1, gar2, gar3;

// Initialize the W5100 chip select signal to the deselected state.
output_high(W5100_CS); 

// Setup the PIC's SPI module to work with the W5100 chip.
setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);

// Reset the W5100 chip and then wait for the time
// specified in the W5100 data sheet.   
output_low(W5100_RESET);
delay_us(100);  // Minimum reset pulse width is 2 us
output_high(W5100_RESET);
delay_ms(20);   // Maximum Plock delay time is 10 ms

// See if we can write to the Gateway Address Registers   
// (GAR0-GAR3). Just fill them with some test data.
w5100_write_reg(W5100_GAR0_REG, 0x12);
w5100_write_reg(W5100_GAR1_REG, 0x34);
w5100_write_reg(W5100_GAR2_REG, 0x56);
w5100_write_reg(W5100_GAR3_REG, 0x78);

// Now read back the GAR registers.
gar0 = w5100_read_reg(W5100_GAR0_REG);
gar1 = w5100_read_reg(W5100_GAR1_REG);
gar2 = w5100_read_reg(W5100_GAR2_REG);
gar3 = w5100_read_reg(W5100_GAR3_REG);

// Display the results. Look on the terminal window
// to see if it's correct.  Should be: 12 34 56 78
printf("Result: %X %X %X %X \n\r", gar0, gar1, gar2, gar3);

while(1);
}
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 2:57 pm     Reply with quote

Thank you so much for your effort PCM programmer, but I hate to say that I am still not getting anything in the hyperterminal. I also tried putting the printf() statement inside while loop.

SPI_XMIT_L_TO_H is not defined in the header file of the PIC I'm using, some of the fuses arent defined either, so I modified some parts of your code but I was still unable to make it work. I am not sure how to forward with defining Mode 0 on this chip.
Here are some edits I made to your code,
Code:

#include <33fj128gp802.h>
#fuses HS,NOWDT,PUT2,PR_PLL
//#use delay(clock=4000000)
#use delay (clock=40M, osc=20M)
#use rs232(baud=9600, XMIT=PIN_B0, RCV=PIN_B1, ERRORS)

// Setup the PIC's SPI module to work with the W5100 chip.
setup_spi(SPI_MASTER | SPI_L_TO_H | SPI_CLK_DIV_16);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 3:04 pm     Reply with quote

1. Post your current #pin_select statements.

2. Post the list of pin connections between the PIC and the Wiz812MJ
board. The Wiz812MJ board has two header connectors on it, J1 and J2.

Don't post the signal names. Just trace out the wires, either with your
eyes or with an ohmmeter, and post the connections between the PIC
and the board, in terms of the pin numbers on each one.


With regard the SPI mode, I can't do a lot because I don't have the PCD
compiler, and it's critical to get the correct mode setting. In this thread
they discuss how to set the mode, except it's for the PIC24 series.
http://www.ccsinfo.com/forum/viewtopic.php?t=38491&start=30
Until the method to setup the SPI mode can be determined with
certainty, the SPI communications can not be certain to work.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 3:16 pm     Reply with quote

Code:

#pin_select SCK1OUT=PIN_B8
#pin_select SDI1=PIN_B10
#pin_select SDO1=PIN_B9
#pin_select SS1OUT=PIN_B11

PIC      Wiznet
#17(RB8)   J2:3
#18       J1:1
#21      J1:2
#22      J2:4
#23      J2:2

...and then the usual Vdd and Gnd on Wiznet are where they should be.

Addition:
I also changed the code here:
Code:

// PIC pins assigned to W5100 signals.
#define W5100_CS     PIN_B11
#define W5100_RESET  PIN_B12
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 4:16 pm     Reply with quote

Quote:
#pin_select SS1OUT=PIN_B11

Here you have SS1OUT assigned to a PIC pin. But the driver code I
posted uses manual control of the Slave Select pin. It's not under the
control of the PIC's hardware SPI module.

The PIC can control the SS output pin, in a special mode called
"Framed Master" mode, as described in the dsPIC Reference Manual:
http://ww1.microchip.com/downloads/en/DeviceDoc/70206b.pdf
But do we know that it works with the CCS compiler ?

I think it's safer to remove that #pin_select statement (comment it out)
and let the PIC handle the Slave Select manually with output_high()
and output_low() statements, as contained in the driver code.

Other than that, your connections look OK.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group