speeding up the SPI CLOCK

Status
Not open for further replies.

irilias

New Member
Hi, i hope you're all doing well .
i'm trying to implement an interface between a PIC16f877a (8Mhz xtal) and an MMC, and i have a bit of a problem with CCS, now i understand that MMC requires a clock lower than 400khz for initialization and that's what i did, the code is running with SPI_CLK_DIV_64 (125khz).

my question is, what code should i add to speed up the SPI connection? i mean should i just redefine the SPI setup: Setup_spi(SPI_CLK_DIV_4) ?!

my second question concerns the bus interface circuitry, what Transistors do you recommend using ?

Code:
#include<16f877a.h> 
#fuses hs,nowdt, noprotect, nolvp 
#use delay(clock=10000000) 
#include<math.h> 
#include<string.h> 
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) 
int mmc_init(); 
int mmc_response(unsigned char response); 
int mmc_write_block(unsigned long block_number); 

/************************** MMC Init **************************************/ 
/* Initialises the MMC into SPI mode and sets block size, returns 0 on success */ 
int mmc_init() 
{ 
int i; 
SETUP_SPI(SPI_MASTER | SPI_H_TO_L | SPI_CLK_DIV_64); 
*0x94 |= 0x40;		// set CKE = 1 - clock idle low 
*0x14 &= 0xEF; 		// set CKP = 0 - data valid on rising edge 
OUTPUT_HIGH(PIN_C2); 	// set SS = 1 (off) 
for(i=0;i<10;i++)  	// initialise the MMC card into SPI mode by sending clks on 
{ 
SPI_WRITE(0xFF); 
} 
OUTPUT_LOW(PIN_C2);  // set SS = 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 
puts("Sent go to SPI\n\r"); 
if(mmc_response(0x01)==1) return 1
// if = 1 then there was a timeout waiting for 0x01 from the mmc 
puts("Got response from MMC\n\r"); 
i = 0; 
while((i < 255) && (mmc_response(0x00)==1))  // must keep sending command if response 
{ 
SPI_WRITE(0x41);     // send mmc command one to bring out of idle state 
SPI_WRITE(0x00);    // all the arguments are 0x00 for command one 
SPI_WRITE(0x00); 
SPI_WRITE(0x00); 
SPI_WRITE(0x00); 
SPI_WRITE(0xFF);   // checksum is no longer required but we always send 0xFF 
i++; 
} 
if(i >= 254) return 1;  // if >= 254 then there was a timeout waiting for 0x00 from the mmc 
puts("Got out of idle response from MMC\n\r"); 
OUTPUT_HIGH(PIN_C2);   // set SS = 1 (off) 
SPI_WRITE(0xFF);   // extra clocks to allow mmc to finish off what it is doing 
OUTPUT_LOW(PIN_C2);   // set SS = 0 (on) 
SPI_WRITE(0x50);    // send mmc command one to bring out of idle state 
SPI_WRITE(0x00); 
SPI_WRITE(0x00); 
SPI_WRITE(0x02);   // high block length bits - 512 bytes 
SPI_WRITE(0x00);  // low block length bits 
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF 
if((mmc_response(0x00))==1) return 1; 
OUTPUT_HIGH(PIN_C2);  // set SS = 1 (off) 
puts("Got set block length response from MMC\n\r"); 
return 0; 
} 

/************************** MMC Write Block  *******************************/ 
int mmc_write_block(unsigned long block_number) 
{ 
unsigned long i; 
unsigned long varh,varl; 
char p,f,n; 
set_adc_channel(0); 
delay_us(10); 
f=read_adc(); 
n=(f*5)/256; 
p=(n*9375)/206; 
varl=((block_number&0x003F)<<9); 
varh=((block_number&0xFFC0)>>7); 
puts("Write block\n\r");   // block size has been set in mmc_init() 
OUTPUT_LOW(PIN_C2);   // set SS = 0 (on) 
SPI_WRITE(0x58);   // send mmc write block 
SPI_WRITE(varh); 
SPI_WRITE(varl); 
SPI_WRITE(0x00);  // always zero as mulitples of 512 
SPI_WRITE(0xFF); // checksum is no longer required but we always send 0xFF 
if((mmc_response(0x00))==1) return 1; 
puts("Got response to write block\n\r"); 
SPI_WRITE(0xFE);   // send data token 
for(i=0;i<512;i++) 
{ 
SPI_WRITE(p);   // send data 
} 
SPI_WRITE(0xFF);   // dummy CRC 
SPI_WRITE(0xFF); 
if((SPI_READ(0xFF)&0x0F)!=0x05) return 1; 
puts("Got data response to write block\n\r"); 
OUTPUT_HIGH(PIN_C2);  // set SS = 1 (off) 
return 0; 
}
 
/************************** MMC get response  *******************************/ 
/**** Repeatedly reads the MMC until we get the response we want or timeout ****/ 
int mmc_response(unsigned char response) 
{ 
unsigned long count = 0xFFFF;
  // 16bit repeat, it may be possible to shrink this to 8 bit but there is not much point 
while(SPI_READ(0xFF) != response && --count > 0); 
if(count==0) return 1;  // loop was exited due to timeout 
else return 0;	 // loop was exited before timeout 
} 
/**************************************************************************/



Thank you
 
i have some 2N2222 lying around and they seem comparable to the one you mentioned, thanks for your answer i really appreciate it
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…