Help with FatFs R0.11a and ATMEGA328P

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi everybody!

 

I know that this topic is very popular and that there are tons of tutorials around, but I can't make it work. As the title says, I am trying to make the FatFs work with ATMEGA328P to read a file and send the text through the serial port. I already read the thread named "[TUT] [C] Getting SD/MMC card working painlessly with FatFS" but it seems to not be updated since the example codes shown there differ a little from the last version R0.11a. The disk_initialize(0) method returns STA_NOINIT, but the f_mount function returns FR_OK, which is weird, and the f_read function returns FR_NOT_READY. Since I do not have a debugger yet, I see the return codes by sending them to the PC by UART. I am using Atmel Studio 7.0 and I interfaced the MCU with the SD card through a microSD card breakout and a CD4050 IC powered from a 3.3V regulator. I attached the code in order to avoid doing a very long post. I would appreciate very much if someone could help me find what am I doing wrong. Thank you very much in advance! P.S. I do not have much experience with AVR-GCC :s .

Attachment(s): 

This topic has a solution.

Last Edited: Wed. Jan 27, 2016 - 06:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The disk_initialize(0) method returns STA_NOINIT,

Until that is resolved there is no point calling any higher f_*() functions. You simply are not "talking" to the card.

 

What you can do is litter disk_initialize() with some printf()s to see what path it is taking and why it's making the decision that it cannot initialize the card.

 

But as disk_initialize() is the first point where activity is supposed to happen on the SPI wires then in all likelihood it simply indicates an electrical issue - so get out any analysis tools you have and monitor what is/isn't occurring.

 

Oh and some people have some issues with some cards - so try a few (every house probably has loads of devices with SD/MMCs in them) and see if it is ALL cards that are unresponsive or just one or two.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Clawson, thanks for the answer. I just ordered an Atmel-ICE but while it arrives it is a great idea what you say with the printf()s. I will do that and will let you know what do I get. Also I found that in the mmc module I got some SPI configurations that didn't correspond to my MCU, but that did not resolve my issue. I will try to borrow an Oscilloscope or a signal analyzer to check what signals are being sent. From my SD card, a friend of mine used it for the same purpose some years ago but it seems that he used CodeVision, which does not reflect all the configurations of the library (or I've been not able to find them). I'll try everything and post what I get. Thank you again!
 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

UPDATE: I do not even get into this condition of the disk_initialize(0):

 

if (send_cmd(CMD0, 0) == 1) {
    ...

I am not sure if my SPI configuration is OK, I am using the internal 8 MHz clock.

#define SS          (1<<PORTB0)
#define MOSI	    (1<<PORTB3)
#define MISO	    (1<<PORTB4)
#define SCK		    (1<<PORTB5)
#define CS_LOW()	PORTB &= SS			/* CS=low */
#define	CS_HIGH()	PORTB |= SS			/* CS=high */
#if 0
#define MMC_CD		(!(PINB & 0x10))	/* Card detected.   yes:true, no:false, default:true */
#define MMC_WP		(PINB & 0x20)		/* Write protected. yes:true, no:false, default:false */
#endif

#define	FCLK_SLOW()	SPCR = 0x52		/* Set slow clock (F_CPU / 64) */
#define	FCLK_FAST()	SPCR = 0x50		/* Set fast clock (F_CPU / 2) */

...

void power_on (void)
{
	PORTB |= SS | MOSI;	/* Configure SCK/MOSI/CS as output */
	DDRB  |= SS | SCK | MOSI | (1<<PORTB2);

	SPCR = 0x52;			/* Enable SPI function in mode 0 */
	SPSR = 0x01;			/* SPI 2x mode */
}

I checked the voltage level that powers the card and it is 3.3V. The card works on my PC and was used for a similar project in CodeVision before.

 

I have the MCU and the microSD physically connected as shown below:

 

Physical connections diagram between SD and MCU through a CD4050

 

Am I doing something physically wrong? Or do I have something wrong in the configuration of the registers?

 

Thanks again.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have a "working example" then I would use a scope or a logic analyser to monitor the signal activity in the "works" case and the "no works" case and observe what is different.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

Why don't you use the PB2 pin as CS ? Be aware that the SPI has a multi-master "protection" if PB2 is not configured as an output (see 328P datasheet p.165 chapter 19.3.2). You should make it an output (even if you use PB0 for CS), or be sure that it stays high during communication if it has to be an input.

Have a nice day,
Kraal

Last Edited: Wed. Jan 20, 2016 - 01:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

 

I already set PB0 as an output but it still does not work :( .

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

If you have a "working example" then I would use a scope or a logic analyser to monitor the signal activity in the "works" case and the "no works" case and observe what is different.

 

Ok, I got another CodeVision project and flashed the hex to the MCU. It worked, so the problem is not physical, yet CodeVision does not let you see the configurations (probably it has the libraries precompiled or something). Also in this project they are using the clock with the CKDIV8 fuse set, so it runs at 1 MHz. I am using it without that fuse, so it is at 8 MHz. Still I think that is not the problem, since I got an RTC communicating through I2C in my Atmel Studio Project and it works with the proper CLK calculations. I also set the SPI clock to have a prescaler of 64, so it would run at 125 kHz, which I think is inside the range for SPI. I am sure it is something that has to do with configurations... Right now I've not been able to get a logic analyser :(. I will probably borrow an Oscilloscope from a friend.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

From looking at your schematic you have the output of the SD card connected to the output of the CPU and the inputs connected together as well. The data output of the SD card should be connected to the data input of the CPU. The data input of the SD card should be connected to the level shifter that is connected to the data output of the CPU.

 

I hope this helps.

 

MMR999

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

 

I wrote that you should set PB2 as an output, even if you are not using it.

 

Regarding the connections, they look good to me: SD DO (data out) is connected to MISO (master in slave out) and DI to MOSI.

Have a nice day,
Kraal

Last Edited: Thu. Jan 21, 2016 - 09:14 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, Kraal,

 

Yeah, sorry, that was what I meant (PB2, not PB0). Thank you for your observation. I also found that indeed the wiring is working. Somebody gave mi a hex file of a working project done in CodeVision and it worked. Mine still doesn't and I think this has to do with the SPI. My guess is that SPI is not working at all because I configured it wrong. I was not able to get a logic analyzer or an oscilloscope in this days, but I tried to simulate my program in Proteus (I know is not the best way, but was my only alternative at the moment), and it didn't work while the hex file i got from a friend worked on both Proteus and physically. I will go to basics and try SPI from scratch. After getting it to work, I will use the same configurations on my FatFs project and will let you know what happened. Anyway if someone finds something in the code that I am doing wrong (besides the PB2 as output), it would probably save me more time (: . Thanks!

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So, I found the configuration error and it was pretty stupid. As I read, I found that the CS pin should be low in order to get answer from the Slave, which is the SD card in this case. This was not happening since i had this:

#define CS_LOW()	PORTB &= SS			/* CS=low */
#define	CS_HIGH()	PORTB |= SS			/* CS=high */

So I just changed that to this:

#define CS_LOW()	PORTB &= ~SS		        /* CS=low */
#define	CS_HIGH()	PORTB |= SS			/* CS=high */

With this, I got it working in Proteus, yet no physically, so then I disconnected my generic STK500 from the MCU and voila! It worked. It seems that the STK500 interferes with the communication to the SD card, even if it is idle.

 

Anyway, thank you for your support and advice people!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

acmos25 wrote:
It seems that the STK500 interferes with the communication to the SD card, even if it is idle.

I had the same thing once when trying to use SPI to an AT45 chip on the STK500. While ISP6PIN was still connected it would interfere with the AVR communication over SPI. Guess it's the same thing here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

acmos25 wrote:

So, I found the configuration error and it was pretty stupid. As I read, I found that the CS pin should be low in order to get answer from the Slave, which is the SD card in this case. This was not happening since i had this:

#define CS_LOW()	PORTB &= SS			/* CS=low */
#define	CS_HIGH()	PORTB |= SS			/* CS=high */

So I just changed that to this:

#define CS_LOW()	PORTB &= ~SS		        /* CS=low */
#define	CS_HIGH()	PORTB |= SS			/* CS=high */

With this, I got it working in Proteus, yet no physically, so then I disconnected my generic STK500 from the MCU and voila! It worked. It seems that the STK500 interferes with the communication to the SD card, even if it is idle.

 

Anyway, thank you for your support and advice people!

 

Could u post your code and hardware .zip file here?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Hello, I do not know much English, I use Google translator, I hope you will understand me. I have a problem. I tried everything I could. I do not know what to do. I have Arduino uno rev 3, Atmel studio, I am flashing with the help of 136-gcUploader, throwing compiled HEX files from Atmel Studio into it. I took the project acmos25 (I took the others and did it myself, but the result is the same). He made a mistake in it. I tried to read the file.txt. the program stops at f_open and goes no further. There are no errors. The program just slows down on this feature. If you do not turn off the power and not take out the micro sd, flash the controller in the Arduino with a standard example, and then again flash my firmware from Atmel studio .... everything is in order ... everything works. What could be the problem? Petit FatFs Module- works fine.