|
|
View previous topic :: View next topic |
Author |
Message |
Pete Smith Guest
|
Attn : Tomi. MMC & SPI |
Posted: Thu Mar 06, 2003 11:30 am |
|
|
Hi.
This message is specifically for Tomi - I'm not sure about private messages working, so I thought I'd post to everyone.
I'm now actually trying to get my MMC system up and running.
Quick rundown : CS to C2, SDI to C4, CLK to C3, SDO to C5. SDI and SDO have 33k pull up resistors. PIC is a 16LF876A, running at 3v & 1.8432MHz. The 3v supply is driving the MMC card also. All connections from the card to the PCB are good (less than 2 ohms)
I've hooked the MMC card to the PIC, and I'm trying your MMCInit() routine. All the data seems to be getting to the card. During the initialisation routine, the 1st part (sending 0x040) returns 0x01. The subsequent one (sending 0x41) returns 0x05.
This means that the loop will just keep going round until the error count reaches zero, and the routine will then exit with a return code of zero.
Does this mean anything to you? Are some MMC cards not compatible with SPI, but only the MMC interface?
Can anyone else help?
Many thanks,
Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12430 |
|
|
Tomi Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Thu Mar 06, 2003 12:25 pm |
|
|
Hi Pete,
I think your problem is about the pullup values. 33 kohm is so much... I use 2.2k resistors. It doesn't mean big power consumption because the low states (when the current draws) are stable just for a couple microseconds typically.
By the way, the CMD41 returns R1 result so "5" means "the card is in idle state and executes the initilizing process" (bit0) and "illegal command"(bit2). Try to decrease the resistor values. FYI I have successfully migrated the MMC code to 18F452 (well, I have a 512 byte RAM buffer instead of the I2C chip )
Brg,
Tomi
:=Hi.
:=
:=This message is specifically for Tomi - I'm not sure about private messages working, so I thought I'd post to everyone.
:=
:=I'm now actually trying to get my MMC system up and running.
:=
:=Quick rundown : CS to C2, SDI to C4, CLK to C3, SDO to C5. SDI and SDO have 33k pull up resistors. PIC is a 16LF876A, running at 3v & 1.8432MHz. The 3v supply is driving the MMC card also. All connections from the card to the PCB are good (less than 2 ohms)
:=
:=I've hooked the MMC card to the PIC, and I'm trying your MMCInit() routine. All the data seems to be getting to the card. During the initialisation routine, the 1st part (sending 0x040) returns 0x01. The subsequent one (sending 0x41) returns 0x05.
:=
:=This means that the loop will just keep going round until the error count reaches zero, and the routine will then exit with a return code of zero.
:=
:=Does this mean anything to you? Are some MMC cards not compatible with SPI, but only the MMC interface?
:=
:=Can anyone else help?
:=
:=Many thanks,
:=
:=Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12434 |
|
|
Pete Smith Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Thu Mar 06, 2003 1:36 pm |
|
|
:=Hi Pete,
:=I think your problem is about the pullup values. 33 kohm is so much... I use 2.2k resistors. It doesn't mean big power consumption because the low states (when the current draws) are stable just for a couple microseconds typically.
:=By the way, the CMD41 returns R1 result so "5" means "the card is in idle state and executes the initilizing process" (bit0) and "illegal command"(bit2). Try to decrease the resistor values. FYI I have successfully migrated the MMC code to 18F452 (well, I have a 512 byte RAM buffer instead of the I2C chip
Thanks for the feedback. The docs say the max value should be 100k. I've actually cannibalised an existing board, and used the existing 33k resistors. I'll give it another go with much smaller ones.
At least the device is responding, which is a good thing :-)
Interesting news about porting it to the 18F series. I've just ordered 4 16k FRAM chips (after having bought standard EEPROM chips, and then having read the docs and seeing they'd last about 4 seconds for my application), as well as an 18F252. Sadly Farnell only had the DIL in stock. I'll wait until they have some SM in stock, and see if I can do a direct swap. It'll certainly make the code easier.
Thanks for the suggestion, I'll go and give it a try.
Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12440 |
|
|
Pete Smith Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Thu Mar 06, 2003 4:17 pm |
|
|
:=Hi Pete,
:=I think your problem is about the pullup values. 33 kohm is so much... I use 2.2k resistors. It doesn't mean big power consumption because the low states (when the current draws) are stable just for a couple microseconds typically.
:=By the way, the CMD41 returns R1 result so "5" means "the card is in idle state and executes the initilizing process" (bit0) and "illegal command"(bit2). Try to decrease the resistor values.
Well, I've taken them down to 2.2k, but the problem still remains (illegal command).
When I send CMD0 (IDLE), I assume the fact that I get a response shows that the card is in SPI mode, and is responding to the commands? The fact that I can send CMD0, and get the response I'd expect also leads me to believe that the wiring is fundamentally correct, as are the MMCIn and MMCOut functions. I've included the code below. It should compile - I've just combined all the files together into one big one, and converted it into HTML.
I've tried sending some commands (0x49, 0x4a and 0x4d - SEND_CSD, SEND_CID and SEND_STATUS respectively). Following the instructions of the ignored CRC, I'm leaving it at 0x95.
I've been reading the data in in the same way that you're checking the status after putting it in read mode, by carrying out 8 sequential reads, and I've been displaying the data as it comes in.
0x49 responds initially with an 0x05, and then with 0x01.
0x4a responds very quickly with an 0x01.
0x4d never responds (other than with 0xff).
FWIW the READ_SINGLE_BLOCK in your example code also only ever returns 0xff.
Does anyone have any other ideas as to what could be wrong?
Thanks,
Pete.
#include <16F876A.h> // We're running on a 16F876
#device PIC16F876A *=16 ADC=8 // Tell compiler that ADC is 10 bits
#fuses wdt,xt, noprotect, noput, nowrt, nolvp,nobrownout // Set the fuses
#use delay (clock=1843200,restart_wdt) // PIC is running at4MHz, restarting WDT when delaying
#byte port_c=7 // Addess of port C
#byte port_b=6 // Addess of port B
#byte port_a=5 // Addess of port A
#use fast_io(a) // We want fast IO on all ports
#use fast_io(b) // We want fast IO on all ports
#use fast_io(c) // We want fast IO on all ports
#define A_TRIS 0b001111 // A tris
#define B_TRIS 0b11111011 // B Tris
#define PROGRAM_TX PIN_C6 // Programming transmit
#define PROGRAM_RX PIN_C7 // Programming receive
#define DEBUG_TX PIN_C6 // RS232 debug/program
#define DEBUG_RX PIN_C7 // RS232 debug/program
#define MMC_CS PIN_C2
#define MMC_SCK PIN_C3
#define MMC_SDI PIN_C4
#define MMC_SDO PIN_C5
#define ChipSel PIN_C2 // my bit-banged IO lines
#define ChipClk PIN_C3 // pulled up to +3V
#define ChipDin PIN_C4 // don't forget that MMC needs +3V power and control lines
#define ChipDout PIN_C5
//76543210
#define C_TRIS 0b10100000 // C Tris
#use RS232 (baud=9600, xmit=DEBUG_TX,rcv=DEBUG_RX,parity=N, bits=8)
// The following function is the elementar "send out a byte to MMC"
void MMCOut(char indata)
{
char i;
i = 8;
restart_wdt();
do
{ // this cycle is equivalent with a for() but the code size is less
if (bit_test(indata,7)) output_high(ChipDin);
else output_low(ChipDin);
output_high(ChipClk);
indata <<= 1;
output_low(ChipClk);
} while (--i);
}
// The following function is the elementar "send 8 clocks to MMC for internal operations"
void MMC8Clock()
{
char i;
i = 8;
output_high(ChipDin);
do
{
output_high(ChipClk);
output_low(ChipClk);
} while (--i);
}
// The following function is the elementar "read in a byte from MMC"
char MMCIn()
{
char i,retval;
output_high(ChipDin);
retval = 0;
restart_wdt();
i = 8;
do
{
retval <<= 1;
if (input(ChipDout)) bit_set(retval,0);
output_high(ChipClk);
output_low(ChipClk);
} while (--i);
return retval;
}
// The following function initializes the MMC in SPI mode
// the return value is non-zero if the init was succesful; otherwise it is zero
// call it once from your early main()
char MMCInit()
{
short int flag;
char response,i,errcnt;
// set_tris_d(0x80);
output_high(ChipSel);
output_high(ChipClk);
output_high(ChipDin);
flag = input(ChipDout);
i = 80;
errcnt = 254;
do
{
output_high(ChipClk);
output_low(ChipClk);
} while (--i);
delay_ms(1);
output_low(ChipClk);
output_low(ChipSel);
MMCOut(0x40);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x95);
MMC8Clock();
response = MMCIn();
printf("GO_IDLE_STATE response \%02X\n\r",response);
output_high(ChipSel);
output_high(ChipClk);
do
{
delay_ms(1);
output_low(ChipClk);
output_low(ChipSel);
MMCOut(0x41);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x95);
MMC8Clock();
response = MMCIn();
printf("SEND_OP_COND response \%02X\n\r",response);
output_high(ChipSel);
output_high(ChipClk);
errcnt--;
} while (bit_test(response,0) && errcnt);
return errcnt;
}
void my_mmc_id(void)
{
int temp,errs,response;
int16 loop;
output_low(ChipClk); // open MMC for read
output_low(ChipSel);
MMCOut(0x49);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0x01);
errs = 8;
do
{
response = MMCIn();
printf("Response 1 is \%02x\n\r",response);
} while (--errs && response==0xFF);
errs = 8;
do
{
response = MMCIn();
printf("Response 2 is \%02x\n\r",response);
} while (--errs && response==0xFF);
output_high(ChipSel);
output_high(ChipClk);
output_low(ChipClk); // open MMC for read
output_low(ChipSel);
MMCOut(0x4a);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0x01);
errs = 8;
do
{
response = MMCIn();
printf("Response 3 is \%02x\n\r",response);
} while (--errs && response==0xFF);
errs = 8;
do
{
response = MMCIn();
printf("Response 4 is \%02x\n\r",response);
} while (--errs && response==0xFF);
output_high(ChipSel);
output_high(ChipClk);
output_high(ChipSel);
output_high(ChipClk);
output_low(ChipClk); // open MMC for read
output_low(ChipSel);
MMCOut(0x4d);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0x01);
errs = 8;
do
{
response = MMCIn();
printf("Response 5 is \%02x\n\r",response);
} while (--errs && response==0xFF);
errs = 8;
do
{
response = MMCIn();
printf("Response 6 is \%02x\n\r",response);
} while (--errs && response==0xFF);
output_high(ChipSel);
output_high(ChipClk);
}
void my_mmc_read(void)
{
int temp,errs,response;
int16 loop;
output_low(ChipClk); // open MMC for read
output_low(ChipSel);
MMCOut(0x51);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0);
MMCOut(0x01);
errs = 8;
do
{
response = MMCIn();
printf("Response 7 is \%02x\n\r",response);
} while (--errs && response==0xFF);
errs = 8;
do
{
response = MMCIn();
printf("Response 8 is \%02x\n\r",response);
} while (--errs && response==0xFF);
for (loop=0;loop<512;loop++)
{
if (loop \% 8 == 0)
{
printf("\n\r");
}
temp = MMCIn();
printf("\%02X ",temp);
}
response = MMCIn();
response = MMCIn();
output_high(ChipSel);
output_high(ChipClk);
}
// --------------------------------------------------------------------------------------------------------------------------
// Now that everything is set up, we can finally actually start the main routine!
// --------------------------------------------------------------------------------------------------------------------------
void main() // Main routine
{
char temp;
set_tris_a(A_TRIS);
set_tris_b(B_TRIS);
set_tris_c(C_TRIS);
temp=MMCInit();
printf("\n\rPowering up!\n\r");
printf("Init done (result = \%02X)\n",temp);
getaddr=0x543200;
my_mmc_id();
my_mmc_read();
while (1==1)
{
restart_wdt();
}
}
___________________________
This message was ported from CCS's old forum
Original Post ID: 12443 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: Attn : Tomi. MMC & SPI |
Posted: Thu Mar 06, 2003 6:38 pm |
|
|
:=
:=Can anyone else help?
------------------------------------------------------------
Here are some MMC projects I found on the net:
Source code in CCS:
<a href="http://people.msoe.edu/~barnicks/courses/cs400/2000-2001/mp3\%20player/FinalReport.pdf" TARGET="_blank">http://people.msoe.edu/~barnicks/courses/cs400/2000-2001/mp3\%20player/FinalReport.pdf</a>
Source code in Hi-Tech C:
<a href="http://www.bundu.com/download/mmc.zip" TARGET="_blank">http://www.bundu.com/download/mmc.zip</a>
Complete project, with photos & schematic, but in Pic Basic:
<a href="http://www.compsys1.com/workbench/On_top_of_the_Bench/MMC_Project/mmc_project.html" TARGET="_blank">http://www.compsys1.com/workbench/On_top_of_the_Bench/MMC_Project/mmc_project.html</a>
___________________________
This message was ported from CCS's old forum
Original Post ID: 12444 |
|
|
Tomi Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Fri Mar 07, 2003 2:20 am |
|
|
In your MMCInit() function you have a typo (probably because of copy/paste editing).
Your code:
do
{
delay_ms(1);
output_low(ChipClk);
output_low(ChipSel);
MMCOut(0x41);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x95); // WRONG! Must be 0x01 !
MMC8Clock();
response = MMCIn();
printf("SEND_OP_COND response \%02X\n\r",response);
output_high(ChipSel);
output_high(ChipClk);
errcnt--;
} while (bit_test(response,0) && errcnt);
My code:
do {
delay_us(1000);
output_low(ChipClk);
output_low(ChipSel);
MMCOut(0x41);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x00);
MMCOut(0x01); // THIS!
MMC8Clock();
response = MMCIn();
output_high(ChipSel);
output_high(ChipClk);
errcnt--;
} while (bit_test(response,0) && errcnt);
Note that I use delay_us(1000) instead of delay_ms(1) because the delay_us(1000) is translated to a simple loop but the delay_ms() means a single call for DELAY_MS internal function. It could be a problem when you place MMC function into an ISR and you have delay_ms() call in main(), too.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12452 |
|
|
John Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Fri Mar 07, 2003 2:21 am |
|
|
:=Hi Pete,
:=I think your problem is about the pullup values. 33 kohm is so much... I use 2.2k resistors. It doesn't mean big power consumption because the low states (when the current draws) are stable just for a couple microseconds typically.
:=By the way, the CMD41 returns R1 result so "5" means "the card is in idle state and executes the initilizing process" (bit0) and "illegal command"(bit2). Try to decrease the resistor values. FYI I have successfully migrated the MMC code to 18F452 (well, I have a 512 byte RAM buffer instead of the I2C chip <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0"> )
:=
:=Brg,
:=Tomi
I'm not really good at this and maybe that's why I don't get it... Isn't the need for pull up resistors only because there are times when the MMC could be hot swapped (and thus the input on the PIC would float)? If the MMC should remain connected to the PIC at all times when it is powered up it shouldn't be necessary(?) I've successfully connected to the MMC without any pull-ups at all.
I don't even bother about buffering data before writing. I'm just sending it at a rate that suits me :-) At least so far it seems to work!
/John
___________________________
This message was ported from CCS's old forum
Original Post ID: 12453 |
|
|
Pete Smith Guest
|
Re: Attn : Tomi. MMC & SPI |
Posted: Fri Mar 07, 2003 3:02 am |
|
|
:=In your MMCInit() function you have a typo (probably because of copy/paste editing).
:=Your code:
:=do
:={
:=delay_ms(1);
:=output_low(ChipClk);
:=output_low(ChipSel);
:=MMCOut(0x41);
:=MMCOut(0x00);
:=MMCOut(0x00);
:=MMCOut(0x00);
:=MMCOut(0x00);
:=MMCOut(0x95); // WRONG! Must be 0x01 !
[snip]
This _shouldn't_ make any difference. Once the device is in SPI mode, and has received the IDLE command, after that point, all CRCs are disabled by default.
FWIW, I've modified your code a little (a lot actually). I was wondering if the constant writing of the command was confusing the device a little, so rather than send check send etc, I'm doing a send and then 8 checks. _This_ is now doing something. I'm not sure what, but it is.
I now get :
0x40 = 0x01
0x41 = 0x05 followed by 0x01, followed by x00!
I'm _now_ getting data from the status registers.
0x49 is responding with illegal command (!)
0x4A is responding with 0x00, followed by a lot of data.
0x4D is responding with lots of 0xFF, followed by 0x00FFFE, which I'm assuming is crap, because R2 should have MSB & LSB clear.
I'm now getting suspiciously what looks like a FAT table in the 1st 512 bytes too! I've got 55AA at the end, which is what I should be seeing.
:=Note that I use delay_us(1000) instead of delay_ms(1) because the delay_us(1000) is translated to a simple loop but the delay_ms() means a single call for DELAY_MS internal function. It could be a problem when you place MMC function into an ISR and you have delay_ms() call in main(), too.
I'm not anywhere near that at the moment. I'm just initialising it and reading the IDs.
Thanks (everyone) for the input - I may well be back ;-),
Pete.
___________________________
This message was ported from CCS's old forum
Original Post ID: 12455 |
|
|
|
|
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
|