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
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.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Thu Nov 19, 2009 5:07 pm     Reply with quote

Hmm, I wasnt aware that you could remove that pin_select line and still use SS pin in code. However, still no results yet. I will set up a PIC18F4455 tomorrow and see if it works in that.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 8:27 pm     Reply with quote

I set up the connections on a PIC18F4455 proto board and I have done everything I could think of but I am still unable to make SPI connection work. I am using the code that PCM programmer had posted a couple days back and I'm getting all 00's in Serial Port Monitor. I have gone through the datasheets over and over and I dont think I am missing anything. Could setting up a basic SPI be this hard? I have spent so many days on it but have gotten no results.

Is there any other way to troubleshoot this issue? I feel doomed...
Here are some things I've tried hoping to make it work:
- connected CS pin to ground
- connected SS to ground and did SPI_SS_DISABLED to not use SS at all
- did a soft reset of W5100 by writing 0x80 to MR register (not sure if it worked since I used spi to write to the MR register)
- changed SPI modes, changed SPI timing, added delays after setting SS pin high or low, and so on...

I'm using PCH v4.066.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 9:39 pm     Reply with quote

Post your current test program for the 18F4455, without all the weird
stuff, like grounding the \SS pin, etc. Just a normal SPI test program,
done to the best of your ability to match the W5100 data sheet.
The test program must be compilable, as posted.

Post the list of connections between the 18F4455 pins and the W5100.

Also note that the SDO pin and the Hardware UART's Rx pin are shared
on one pin in this PIC. I hope you're not trying to use both the hardware
SPI and hardware UART.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 10:17 pm     Reply with quote

I'm using USB instead of RS232 because of the shared UART and SPI pins. The code's basically the same as you had provided before, I made a couple of changes here and there but they didn't make any difference so now I've ended up with the same code as yours:
Code:

#include <18F4455.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN                //needed for USB functionality
#use delay(clock=48000000)    //needed for USB functionality

#include <usb_cdc.h>         //needed to perform USB to SERIAL functionality
#rom int 0xf00000={1,2,3,4}  //needed for USB functionality

#include <usb_bootloader.h>

#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_B2
#define W5100_RESET  PIN_B3
     
// 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);   delay_us(30);
   spi_write(W5100_WRITE_CMD);
   spi_write((addr&0xFF00)>> 8);  // Send address msb
   spi_write((addr&0x00FF));       // Send address lsb
   spi_write((data&0x00FF));       // Write data to W5100
   output_high(W5100_CS);delay_us(30);
}
 
// 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);delay_us(30);
   spi_write(W5100_READ_CMD);
   spi_write((addr&0xFF00) >> 8);  // Send address msb
   spi_write((addr&0x00FF));       // Send address lsb
   retval = spi_read(0);  // Read data from W5100
   output_high(W5100_CS);delay_us(30);
 
   return(retval);
}

int8 gar0, gar1, gar2, gar3;
unsigned int8 status;

void main()
{
   usb_cdc_init();  //configure the CDC driver
   usb_init();      //start up the USB driver
     
      // Initialize the W5100 chip select signal to the deselected state.
      output_high(W5100_CS); delay_us(20);
     
      // Reset the W5100 chip and then wait for the time
      // specified in the W5100 data sheet.   
      output_low(W5100_RESET);
      delay_us(10);  // Minimum reset pulse width is 2 us
      output_high(W5100_RESET);
      delay_ms(25);   // Maximum Plock delay time is 10 ms
     
      // Setup the PIC's SPI module to work with the W5100 chip.
      setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_16);
     
      // Writing MR register for software reset, doesnt make any difference
//!      w5100_write_reg(W5100_MR_REG, 0x80);
//!      do {
//!      status = w5100_read_reg(W5100_MR_REG);
//!         } while (status & 0x80);
     
      // 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
   while(TRUE)
   {
      while(usb_cdc_connected())
      {
         usb_task(); 
         // Send to Serial port monitor
         printf(usb_cdc_putc,"Result: %X %X %X %X \n\r", gar0, gar1, gar2, gar3);
         delay_ms(2000);
      }
   }
}


Here are the pin configs:
Code:

PIC          Wiznet
#34          J2:3
#33          J1:2
#26          J1:1
#35(B2)    J2:4
#36(B3)    J2:2

J1:12 and J2:1 to 3.3V
J1:11 and J1:20 to Gnd


I'm powering up Wiznet module with PIC Kit2 for 3.3V, the proto board is powered by its adapter and both proto and wiznet have a common ground.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 11:19 pm     Reply with quote

Quote:
I'm powering up Wiznet module with PIC Kit2 for 3.3V,

Is the PIC's Vdd voltage on the 18F4455 board also at 3.3 volts ?


Quote:
printf(usb_cdc_putc,"Result: %X %X %X %X \n\r", gar0, gar1, gar2, gar3);

Have you proven that the CDC communication works ? Can you put
values into gar0-3, and se values other than 0x00 on your PC ?
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 11:22 pm     Reply with quote

Nope, the PIC's mounted on a prototype board and am using its power adapter to power it up.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 11:23 pm     Reply with quote

But what is the voltage on the Vdd pins of the 18F4455 ? Measure it.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Sat Nov 28, 2009 11:36 pm     Reply with quote

Vdd shows 5V on a multimeter. And yes, cdc is working, I tried putting some random value on gar0 and it displayed the value.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 29, 2009 12:05 am     Reply with quote

Quote:

But what is the voltage on the Vdd pins of the 18F4455 ? Measure it.

Vdd shows 5V on a multimeter

There is a problem with this.

The SDI pin on the PIC is a "Schmitt Trigger" input pin, according to
the 18F4455 data sheet. The high level input voltage is specified at
.8 x Vdd, which is .8 x 5v = 4v in your case. But the MISO pin on the
Wiz812MJ puts out a 3.3v CMOS level signal. That's not high enough to
meet the requirements of the PIC's SDI pin. That's probably the major
reason why your communications don't work.

For the signals going from the PIC to the Wiz board, there is no problem
with the levels, because the Wiz board data sheet says the inputs are
5v tolerant.

You need to add a level converter to the 18F4455 board on the SDI pin.
You need to convert from 3.3v CMOS to 5v CMOS levels. A 74HCTxx-
series gate would work. This logic family can run from 5v, but has TTL
input levels, so it will work with 3.3v CMOS signals on the inputs. It will
put out 5v CMOS levels on the outputs. You need a non-inverting gate,
such as a 74HCT125 (connect the enable pin to ground). Or some other
gate can be used, such as a 74HCT08. Any other logic family that can
run with a 5v Vdd voltage, but has "TTL" compatible inputs will work.

Another possibility is to make your 18F4455 board run at 3.3v, but that
might not be easy to do. It might be easier just to add the level
converter on the SDI pin.
buzz



Joined: 12 Nov 2009
Posts: 14

View user's profile Send private message

PostPosted: Sun Nov 29, 2009 12:24 am     Reply with quote

Hmm, never thought of it from that angle. I will try making a buffer myself and see if that helps, will let you know. Thanks for all your input, I really appreciate it.
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