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 CCS Technical Support

Advice on SPI MMC.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
arunkish



Joined: 23 Dec 2008
Posts: 83

View user's profile Send private message

Advice on SPI MMC.
PostPosted: Thu Nov 08, 2012 10:18 am     Reply with quote

Hello All,

I have been working with the following code, that I found on the forum to access MMC card in SPI mode. I am confused on the reading and writing arguments passed on to the card.

Code:

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('G');
   }
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



//*************************************

 puts("Before Read ");
// 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.             
}



(Command(0x58,0,512,0xFF) --- Does it mean that 512 bytes are being written ?????

Is it possible to write only one byte of Data to the card ?? For eg.. read analogue values and write to the card etc. How will i calculate the next available address ?

Please advise.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 08, 2012 3:50 pm     Reply with quote

It helps when you post a link to the library you are using.
General speaking I would suggest you use the drivers supplied by CCS. The driver you use isn't the best MMC implementation, for example time-outs are missing so your code could hang forever. Also, a driver which uses hard coded commands like 0x51 is difficult to understand, much better when a text define is used. Have a look at the file mmcsd.c in the CCS drivers directory. And an example program for how to use it in, surprise, examples/ex_mmcsd.c

About writing individual bytes to the MMC or SD card, this is not really possible. By design the internal implementation of the memory cards is in blocks of 512 bytes and that is the size you have to write. Some tweaks do exist but not recommended because you might loose data on power failure / reset.
Note that reading individual bytes is supported.

Do you really need to use an MMC card? For example FRAM chips have less memory but can be written in individual bytes and saves data faster than the PIC can write.
Another option is to waste lots of memory and write each individual measurement to a 512 byte block. Yes, a huge waste, but the smallest MMC/SD you can buy is about 1Gbyte. That is almost 2 million blocks. Assuming 1 sample session per second you can save 22 days of data.

Note: beware of using memory cards with memory capacities larger than 2Gb. Very few drivers support these cards, so double check they mention to support SDHC cards (as opposed to standard SD cards).
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Nov 08, 2012 5:32 pm     Reply with quote

Another option, though it might cost more, is to use a 'Viniculum' chip and a USB flashdrive. About $40+-, but single byte writes/reads are easy and if stored in CSV format, super easy to transfer data to a PC.
Just another option.
hth
jay
arunkish



Joined: 23 Dec 2008
Posts: 83

View user's profile Send private message

PostPosted: Thu Nov 08, 2012 6:09 pm     Reply with quote

Thank you for your suggestions. as you said I tried with a 4 gb card and failed.

Last edited by arunkish on Thu Nov 08, 2012 6:42 pm; edited 1 time in total
arunkish



Joined: 23 Dec 2008
Posts: 83

View user's profile Send private message

PostPosted: Thu Nov 08, 2012 6:41 pm     Reply with quote

Thank you for your suggestions. for now I will stick on to memory card for startup. I tried mmcsd example in proteus. but it failed to initialize. anyway I will work on it again. writing 512 bytes is not a problem. but I should be able to read it byte by byte.

I am actually planning to convert and store microphone input as 8 bit adc values and read it and send to pwm pin. just like a voice recorder. is this possible using mid range pic like 16f877a with 20 mhz crystal.
arunkish



Joined: 23 Dec 2008
Posts: 83

View user's profile Send private message

PWM
PostPosted: Thu Nov 08, 2012 8:02 pm     Reply with quote

Without MMC read and write I just tried to do ADC- DAC conversion. I mean read the analog value and set the PWM duty. But I don't get any output with i run the following code.

Code:

#include <16F877A.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 PORTC = 7
   

void main(void)
{
int16 adc_value,y;             

setup_adc_ports(ALL_ANALOG);
setup_adc(AN0);
set_adc_channel(0);
delay_us(20);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_16,255,1);
setup_ccp1(CCP_PWM);
setup_comparator(NC_NC_NC_NC);
puts("Start\n\r");               

while(1)
{
   adc_value = read_adc();delay_us(10);
   printf("%lu\n",adc_value); delay_ms(500);
//   y=(adc_value*100)/255;
   set_pwm1_duty(adc_value);
}
       
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Fri Nov 09, 2012 2:23 am     Reply with quote

You haven't given the ADC a clock......

Look at the setup values.

You will only get 1/4 the pwm output range (when you fix the above):
#device ADC=10

Currently you will only get 0 to 255 from the ADC.

Best Wishes
arunkish



Joined: 23 Dec 2008
Posts: 83

View user's profile Send private message

PostPosted: Fri Nov 09, 2012 8:09 pm     Reply with quote

@Ttelmah...
Yes, I missed it out and fixed it and got it working in the real hardware. As expected proteus does not do it. Right now I use 8 bit adc... with the following PWM configuration.

Code:

setup_timer_2(T2_DIV_BY_1,255,1);

///// And loading the adc value

 set_pwm2_duty(adc_value);


The PWM out is given to a preamp and the problem I face is I have a very low sound output. I will post the schematic very soon. My question is if I use 10bit adc, what shall be the Timer 2 configuration ?? Will i need to convert the 10bit adc value back to 8 bit format when setting up the duty cycle ?

@ckielstra....

I checked out the mmcsd code and stimulated it in proteus, I am writing a value of 11 to address 1112, but when I read it I always get 00. I have directly connected the SPI out to the mmc card without 3.3 & 2.2 resistors in proteus. Is it correct ?? I also used Winimage and created Image file for the card. Fat16 format. Is that the problem or something else?

Any suggestions are appreciated.

Thanks a lot.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Nov 10, 2012 2:56 am     Reply with quote

With your period of 256, you should be able to use either 8, or 10 bit values for the PWM period.

Mike

EDIT Please stop talking about Proteus, you could find the thread locked.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Nov 10, 2012 8:42 am     Reply with quote

Quote:
I am writing a value of 11 to address 1112, but when I read it I always get 00. I have directly connected the SPI out to the mmc card without 3.3 & 2.2 resistors in proteus.
Without your actual code and schematic it is hard to tell where the problem is.
Some common errors:
- MMC/SD cards require a maximum of 3.3V. Easiest is to have a PIC working at the same voltage. With the PIC working at 5V some 'glue' logic is required and often people make errors here.
- SDO of the PIC goes to Data In of the MMC and SDI of the PIC to Data Out of the MMC, i.e. a cross connection.
- The MMC card starts up in MultiMediaCard mode where the DataIn and DataOut pins are 'open drain'. This requires <= 10k pull up resistors on these lines.

Quote:
I also used Winimage and created Image file for the card. Fat16 format. Is that the problem or something else?
I don't know. Again, we don't know the exact code you know for writing. Be careful though, writing to a random address can destroy the FAT directory structure so that reading files might fail. Even then, writing to and reading from the same address should work.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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