|
|
View previous topic :: View next topic |
Author |
Message |
buzz
Joined: 12 Nov 2009 Posts: 14
|
spi_xfer() with wiznet Wiz812MJ |
Posted: Thu Nov 12, 2009 10:15 pm |
|
|
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
|
|
Posted: Thu Nov 12, 2009 11:32 pm |
|
|
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
|
|
Posted: Thu Nov 12, 2009 11:39 pm |
|
|
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
|
|
Posted: Fri Nov 13, 2009 2:09 am |
|
|
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
|
|
Posted: Fri Nov 13, 2009 11:08 pm |
|
|
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
|
still not working |
Posted: Wed Nov 18, 2009 6:15 pm |
|
|
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
|
|
Posted: Wed Nov 18, 2009 7:00 pm |
|
|
Can you post the declaration statement for 'SIPR0' ? |
|
|
buzz
Joined: 12 Nov 2009 Posts: 14
|
|
Posted: Wed Nov 18, 2009 7:02 pm |
|
|
SIPR0 is the IP register address on wiz812MJ. It's defined as 0x000F. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Nov 18, 2009 8:04 pm |
|
|
Can you post actual line in your program that defines it or declares it ? |
|
|
buzz
Joined: 12 Nov 2009 Posts: 14
|
|
Posted: Wed Nov 18, 2009 8:22 pm |
|
|
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
|
|
Posted: Thu Nov 19, 2009 12:35 am |
|
|
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
|
|
Posted: Thu Nov 19, 2009 2:57 pm |
|
|
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
|
|
Posted: Thu Nov 19, 2009 3:04 pm |
|
|
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
|
|
Posted: Thu Nov 19, 2009 3:16 pm |
|
|
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
|
|
Posted: Thu Nov 19, 2009 4:16 pm |
|
|
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. |
|
|
|
|
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
|