|
|
View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 08, 2005 4:28 am |
|
|
Quote: | However, the MMC specifications requires pull up resistors to Vsupply to be inserted on the DataIn and DataOut lines. Is the above mentioned circuit wrong? Please can someone help me. | Seems like an error in the schematic. You are right about the specifications specifying pull-up resistors, that is what I use in my circuit and works. |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Wed Jun 08, 2005 4:34 am |
|
|
Hi Ckielstra
Thank you for the confirmation. Is it possible for you to post your circuit please?
All the best
arrow |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Wed Jun 08, 2005 5:44 am |
|
|
Hi Ckielstra
Also, to do level shifting from 5V to 3V (or 3.3V), is there a problem using a voltage bridge with 2 resistors say 2k and 3k?
All the best
arrow |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 08, 2005 6:18 am |
|
|
Sorry, I can't post my schematic (company confidential).
Strange, searching for an online schematic I stumbled across http://www.cc5x.de/MMC/, here they also use a setup with pull-downs i.s.o. pull-ups.
I studied the specification again, and there it is very clear: pull-ups, not pull-downs. On the CMD line a pull-up of 4k7 to 100k max. and on the DAT line a resistor of 50k to 100k max. No series resistors are used. In my schematic I use 100k pull up resistors.
Just an extra remark, beware of the cross-connection in the SPI setup:
- SPI-out of the PIC goes to DATA_IN (pin 2) of the MMC
- SPI-in of the PIC to DATA_OUT (pin 7) of the MMC |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Wed Jun 08, 2005 6:30 am |
|
|
Hi Ckielstra
Thank you- I think what these circuits are doing is to divide the voltage so that only about 3V comes into the MMC. (The PICS output 5V and they want to have only 3V come into the MMC).
That will explain the 1.8+3.3k resistors.
But in this case I dont see any pull up/ down resistors as in the specifications.
In your circuit do you
(a) use any additional capacitors, as is recommended in the spec sheet?
(b) Do you use a 5V PIC (F) or 3V PIC (LF)?
(c) Do you connect the PIC input/ output directly into the MMC?
Thank you once again
arrow |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jun 08, 2005 7:57 am |
|
|
Quote: | Thank you- I think what these circuits are doing is to divide the voltage so that only about 3V comes into the MMC. (The PICS output 5V and they want to have only 3V come into the MMC).
That will explain the 1.8+3.3k resistors. | That makes sense. I didn't think about this because we are running the PIC at 3,3V.
a) I just had a look into the specifications and according to Appendix A a 100nF close to the card is required. We currently don't use any capacitors close to the MMC and it's working but to be sure I will add them in the next hardware revision.
b) LF-version at 3,3V.
c) PIC is directly connected to the MMC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 08, 2005 12:12 pm |
|
|
I was curious about that schematic. It shows a 3.3v device driving
the hardware SPI input pin (RC4 - SDI). In the Overview section
of the 16F877 data sheet, it says that RC4 has a Schmitt Trigger input.
In the Electrical section, it says that Vih for RC4 is .7 x Vdd (min).
For 5v operation, this would be 3.5v. So, supposedly a 3.3v device
could never output a sufficiently high level to meet the Vih spec.
Since their project apparently works, I decided to test this spec.
I put a 1K trimpot on pin RC4 and created the small test program below.
It continously reads the SPI data coming in on RC4 and displays it.
I found that the actual high-level threshold is about 2.50v. That's
when the trimpot is initially set to 0v, and I slowly increase the
voltage. When I turn the voltage back down, there is a bit of hysteresis,
because it doesn't start putting out 0's again until I get to about 2.25v.
Microchip specs Vil at 1.5v max, so it's actually switching at .75v above
that. I also heated up the PIC with a heat gun and froze it with freeze
spray. The thresholds changed slightly, but not very much.
This test shows why project works, even though it violates the official
specs for input levels on RC4. But I wonder why Microchip specs
such a large margin for Vih ? It switches at 2.5v, but they want
a full 1.0v margin. Anyway, I think this shows that for a hobby project
you can get away with not using level-shifters from 3.3->5v logic on
the SDI pin. I wouldn't do it in a real product, though.
Code: | #include <16f877.h>
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main()
{
int8 value;
setup_spi(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_16);
while(1)
{
value = spi_read(0);
printf("%X ", value);
delay_ms(500);
}
}
|
|
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Jun 09, 2005 4:01 am |
|
|
Hi Ckielstra
You are very helpful!
I baught the 16LF873 chip, but now I have a question about programming it.
I have a very old version of PICC compiler, and a 1997 version of MPLAB. I download teh hex file into MPLAB and since it only has the 16F873 chip I use that to setting to program the LF PIC.
I plug it into the circuit and simply try to flash a few led's with the LF chip, and I see nothing. If I put in a 5V regulator (LF chip being supplied with 5V instead of 3.3V), then the LF chip flashes my leds.
Can you please tell me what I am doing wrong?
In the new version of the MPLAB is there a PIC16LF873 selection that I have to use?
Thank you once again for all your help.
arrow |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jun 09, 2005 4:39 am |
|
|
MPLAB version 7.00 has no special selection for a 16LF873, only the 16F873.
Very likely your problem with not starting at 3V is the BROWNOUT fuse, set this to NOBROWNOUT and try again. |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Jun 09, 2005 5:04 am |
|
|
Hi Ckielstra
THANK YOU! that was exactly the problem with using the LF chip.
I am going to try and interface it to the MMC card now.
I will do it directly from the PIC16LF873 to the MMC card, and I will use 2 100k pull up resistors to the 3.3V on the DataIn and DataOut lines.
I will update on any progress/ problems.
All the best
arrow |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Jun 09, 2005 5:40 am |
|
|
Hi Ckielstra
I am sorry to bug you like this, but I still cannot get the MMC to work. Can you please tell me if you see anything wrong with this piece of code? (Its from Ed Waugh code). I get a time out in the mmc_response() routine.
I am not sure if SPI is working or not.
Can you please help me?
Thank you, and
All the best
arrow
#include <16F873.H>
#fuses LP, PROTECT, PUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay(clock=4000000)
short mmc_init(){
int i;
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_4);
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
OUTPUT_HIGH(PIN_C2); // set CS = 1 (off)
for(i=0;i<10;i++){
SPI_WRITE(0xFF);
}
OUTPUT_LOW(PIN_C2); // set CS = 0 (on) tells card to go to spi mode when it receives reset
SPI_WRITE(0x40); // send reset command
SPI_WRITE(0x00); // all the arguments are 0x00 for the reset command
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x00);
SPI_WRITE(0x95); // precalculated checksum as we are still in MMC mode
if(mmc_response(0x01)==1) return 1;
//-----
//------
}
//==============
short mmc_response(char response){
unsigned long count = 0xFFFF; // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point
displayIt(12);
delay_ms(1500);
while(SPI_READ(0xFF) != response && --count > 0);
//***IT TIMES OUT HERE and I GET A count = 0
if(count==0)displayIt(9);
if(count==1)displayIt(8);
delay_ms(1500);
if(count==0) return 1; // loop was exited due to timeout
else return 0; // loop was exited before timeout
}
//==============
void main(void){
int i;
i = mmc_init();
//------
//------
} |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jun 09, 2005 6:18 am |
|
|
Just checking: Which pins of the PIC did you connect to which pins on the MMC connector? |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Jun 09, 2005 6:47 am |
|
|
Hi Ckielstra
In a 28 pin package, I connected
*pin 13 (RC2) to CS
*pin 14 (RC3) to SCKL
*pin 15 (RC4/SDI) to DOUT on this line I have a 100k to 3.3V
*pin 16 (RC5/SDO) to DIN on this line I have a 100k to 3.3V
I am a bit confused by these two statements in the code:
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
Are they correct? I dont understand why the operator in these two statements are different. I also dont know how the bits are set?
The specification sheet says that the lower bits in 14h should be
0000 if I am going for SPI_CLK_DIV_4 (Fosc/4).
Is the last line reflecting this?
Thank you very much
arrow |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jun 09, 2005 9:28 am |
|
|
Your pin connections look fine to me.
Quote: | I am a bit confused by these two statements in the code:
*0x94 |= 0x40; // set CKE = 1 - clock idle low
*0x14 &= 0xEF; // set CKP = 0 - data valid on rising edge
Are they correct? I dont understand why the operator in these two statements are different. I also dont know how the bits are set? |
These are common programming 'tricks' for setting or clearing bits in the given byte without modifying other bits.
It's easier to read when you write the value not in hexadecimal, but binary format. Code: | #byte SSPCON = 0x14
#byte SSPSTAT = 0x94
SSPSTAT |= 0b01000000; // Will set bit 6 and leave all other bits untouched
SSPCON &= 0b11101111; // Reset bit 4 |
Make sure your I/O pins are configured correct. From the PIC16F673 datasheet: Quote: | For the
pins to behave as the serial port function, some must
have their data direction bits (in the TRIS register)
appropriately programmed. That is:
• SDI is automatically controlled by the SPI module
• SDO must have TRISC<5> cleared
• SCK (Master mode) must have TRISC<3>
cleared |
I have this in my code Code: | #use fast_io(C) // We will take care of the Port-C I/O direction registers
set_tris_c(0b00010000); // SDI = input, all others output |
One omission in Ed Waugh's code is that he is initializing the MMC card at too fast a clock rate. On startup the clock should be lowered to 400 kHz or less. When the initialization process is complete the host can raise the clock speed to the card’s maximum. First try to get your code running with SPI_CLK_DIV_16, then later you can add code for a faster SPI after the init has finished. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 09, 2005 1:53 pm |
|
|
I translated the code given in ckielstra's link, to CCS.
http://www.cc5x.de/MMC/
I also wired up my test board according to their schematic.
It works.
In the translation to CCS, I tried to make as few changes as possible.
I translated a few of the German comments.
Also, they had the read operation occur first, followed by the write.
That was confusing to me, so I changed it to write the data, and then
read it back and display it.
They had the data set to all "MMMMM". I wanted to know that it
could do something besides that, so I added "Begin" and "End"
to the data block.
We should thank those guys for posting their code and the schematic.
We had a thread on MMC a few weeks ago, and nothing worked.
Code: | #include <16F877.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use fast_io(C)
#byte SSPBUF = 0x13
#byte SSPCON = 0x14
#byte SSPSTAT = 0x94
#bit BF = SSPSTAT.0
#bit SMP = SSPSTAT.7
#bit CKE = SSPSTAT.6
#bit CKP = SSPCON.4
#bit SSPM1 = SSPCON.1
#bit SSPEN = SSPCON.5
#byte PORTC = 7
#bit CS = PORTC.2
//****************************************
// This is the same as the CCS spi_read() function.
char SPI(char d)
{
SSPBUF=d;
while (!BF);
return SSPBUF;
}
//******************************************
char Command(char befF, int16 AdrH, int16 AdrL, char befH)
{
SPI(0xFF);
SPI(befF);
SPI(AdrH >> 8);
SPI(AdrH);
SPI(AdrL >> 8);
SPI(AdrL);
SPI(befH);
SPI(0xFF);
return SPI(0xFF); // Return with the response
}
//********************************************
char MMC_Init()
{
char i;
// Init SPI
SMP=0;
CKE=0;
CKP=1;
SSPM1=1;
//SSPM0=1;
SSPEN=1;
CS=1; // MMC-Disabled
// MMC in SPI Mode -- start and Reset.
for(i=0; i < 10; i++) SPI(0xFF); // 10*8=80 clocks
CS=0; // MMC-Enabled
// CMD0
if (Command(0x40,0,0,0x95) !=1) goto Error; // Reset
st:
// CMD1
if (Command(0x41,0,0,0xFF) !=0) goto st ; // CMD1
return 1;
Error:
return 0;
}
//*********************************************
void main(void)
{
int16 i;
setup_port_a(NO_ANALOGS);
set_tris_c(0b11010011); // sck rc3-0, sdo rc5-0, CS rc2-0.
set_tris_b(0b00000010);
puts("Start\n\r");
if(MMC_Init())
puts("MMC ON\n\r"); // MMC Init OK
//*****************************************
// Write in 512 Byte-Mode
if (Command(0x58,0,512,0xFF) !=0) puts("Write error ");
SPI(0xFF);
SPI(0xFF);
SPI(0xFE);
SPI("Begin\n\r"); // 7 characters
for(i=0; i < 500; i++) // Was 512, but used 12 for text
{
SPI('M');
}
SPI("\n\rEnd"); // 5 characters
SPI(255); // Send two bytes of 0xFF at the end
SPI(255);
i=SPI(0xFF);
i &=0b00011111;
if (i != 0b00000101) puts("Write Error ");
while(SPI(0xFF) !=0xFF); // Wait for end of Busy condition
//*************************************
// Read in 512 Byte-Mode
if (Command(0x51,0,512,0xFF) !=0) puts("Read Error ");
while(SPI(0xFF) != 0xFE);
for(i=0; i < 512; i++)
{
putc(SPI(0xFF)); // Send data
}
SPI(0xFF); // Send two bytes of 0xFF at the end
SPI(0xFF);
//**********************************************
while(1); // The program stops here.
} |
|
|
|
|
|
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
|