View previous topic :: View next topic |
Author |
Message |
arunkish
Joined: 23 Dec 2008 Posts: 83
|
Advice on SPI MMC. |
Posted: Thu Nov 08, 2012 10:18 am |
|
|
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
|
|
Posted: Thu Nov 08, 2012 3:50 pm |
|
|
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
|
|
Posted: Thu Nov 08, 2012 5:32 pm |
|
|
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
|
|
Posted: Thu Nov 08, 2012 6:09 pm |
|
|
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
|
|
Posted: Thu Nov 08, 2012 6:41 pm |
|
|
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
|
PWM |
Posted: Thu Nov 08, 2012 8:02 pm |
|
|
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: 19538
|
|
Posted: Fri Nov 09, 2012 2:23 am |
|
|
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
|
|
Posted: Fri Nov 09, 2012 8:09 pm |
|
|
@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
|
|
Posted: Sat Nov 10, 2012 2:56 am |
|
|
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
|
|
Posted: Sat Nov 10, 2012 8:42 am |
|
|
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. |
|
|
|