|
|
View previous topic :: View next topic |
Author |
Message |
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
MicroSD question (SOLVED!) |
Posted: Tue Jan 29, 2013 6:03 pm |
|
|
Been trying to get this working for a while now... and it's close, but so far no joy.
CPU: PIC18F46J53
Compiler: PCWH 4.128
#include "mmcsd.c" - with changes for MBR suggested by andrewg.
#include <fat.c>
Hardware: MicroSD card socket, wired like this:
Pin 1: No connection
Pin 2: To PIC pin 2, RD4 (#define MMCSD_PIN_SELECT PIN_D4)
Pin 3: To PIC pin 40, RD2 (#define MMCSD_PIN_SDO PIN_D2)
Pin 4: 3.3V
Pin 5: To PIC pin 3, RD5 (#define MMCSD_PIN_SCL PIN_D5)
Pin 6: Ground
Pin 7: To PIC pin 41, RD3 (#define MMCSD_PIN_SDI PIN_D3)
Pin 8: No connection
I also have 10K pullup resistors to 3.3V on all four lines.
OK... so apparently the PIC can see the memory card. I tossed in calls to mmcsd_print_cid() and mmcsd_print_csd() and get this:
Code: | Init returned 0
Manufacturer ID: 02
OEM/Application ID: TM
OEM/Application ID: SD02G
Product Revision: 38
Serial Number: A6ACED8D
Manufacturer Date Code: 0084
CRC-7 Checksum: 2D
CSD_STRUCTURE: 00
TAAC: 2E
NSAC: 00
TRAN_SPEED: 32
CCC: 05B5
READ_BL_LEN: 0A
READ_BL_PARTIAL: 01
WRITE_BLK_MISALIGN: 00
READ_BLK_MISALIGN: 00
DSR_IMP: 00
C_SIZE: A7
VDD_R_CURR_MIN: 07
VDD_R_CURR_MAX: 07
VDD_W_CURR_MIN: 07
VDD_W_CURR_MAX: 07
C_SIZE_MULT: 07
ERASE_BLK_EN: 01
SECTOR_SIZE: 7F
WP_GRP_SIZE: 00
WP_GRP_ENABLE: 00
R2W_FACTOR: 05
WRITE_BL_LEN: 0A
WRITE_BL_PARTIAL: 00
FILE_FORMAT_GRP: 00
COPY: 00
PERM_WRITE_PROTECT: 00
TMP_WRITE_PROTECT: 00
FILE_FORMAT: 00
CRC: 91
|
I rolled most of ex_fat.c into my program so I would have a mini command shell to try various things. I formatted the card with FAT32 and put one directory (named 111) and a text file (named abc.txt) on it. I get no error messages other than what shows below:
Code: |
/> dir
/> mkdir 222
Making directory '/222/': Error creating directory
(NOTE: This took about half a minute)
/> cd 111
Error changing directory
/> cd 222
Error changing directory
/> cat abc.txt
Error opening file
/> make test.txt
Making file '/test.txt': OK
/> append test.txt "hello world"
Appending 'hello world' to '/test.txt': Error opening file
/> dir
/>
|
I can also try formatting the card, which reports "OK" but doesn't really do anything. When I read the card with my Windows or Linux machine, it's unchanged.
What am I missing here? It feels like I'm close... but no cigar yet. And yeah, I'm sure it's a MicroSD and not SDHC... it's a 2GB card, smallest one I have.
Last edited by dbotkin on Sat Feb 02, 2013 2:04 pm; edited 1 time in total |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jan 30, 2013 8:01 am |
|
|
What voltage is your PIC running? If it is 5V than you'll need some 'glue' logic to convert from / to the 3.3V for the SD card.
SD cards start with their data bus in Open Collector mode until the initialization to SPI mode databus has completed. Do you have a pull up resistor at the DO from the Mini SD card (pin 7, 10k will do).
What decoupling capacitors do you have at the SD card?
When writing data the power consumed by the SD card is a lot higher than when reading. Perhaps the 3.3V power supply can't cope with this power surge? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Jan 30, 2013 9:11 am |
|
|
The 46J53, is a 3.3v PIC, so he should be OK on this one, unless he has copied circuits with a resistive divider to the card.
Other comment he has set the file system type in fat.c to FAT32?.
He says he has pullups on all four lines (essential on CS as well, since otherwise it can 'glitch select' when the unit is waking up).
Obvious comment card must be MicroSD, not MicroSDHC.
He seems very close, getting the ID etc..
Best Wishes |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Wed Jan 30, 2013 9:19 am |
|
|
ckielstra wrote: | What voltage is your PIC running? If it is 5V than you'll need some 'glue' logic to convert from / to the 3.3V for the SD card. |
Yes, as noted I'm not a student. ;) The entire board is 3.3V.
ckielstra wrote: | SD cards start with their data bus in Open Collector mode until the initialization to SPI mode databus has completed. Do you have a pull up resistor at the DO from the Mini SD card (pin 7, 10k will do). |
Yes, 10K pullups on all four pins. The PIC has internal WPU on PORTD, but I put resistors in place just in case those were not sufficient.
ckielstra wrote: | What decoupling capacitors do you have at the SD card?
When writing data the power consumed by the SD card is a lot higher than when reading. Perhaps the 3.3V power supply can't cope with this power surge? |
The 3.3V supply is coming from a 78L33 regulator, and the PIC is maybe drawing 20-25 mA at most. Nothing else on the board, and the power supply is via USB. There's a .1 uF decoupling cap but it could stand to be closer to the card -- the scope does show some noise but no serious sags in the supply voltage.
I set up a loop to just use mmcsd_write_byte() and mmcsd_read_byte() to see if the card is actually getting written to and read from. I used that to write data to the first 2048 bytes on the card -- it works. Everything writes and reads back as it should. I then plugged the card into my Linux machine and used dd to verify that the data was indeed written to the card, which wiped the partition table of course.
So... it seems I've narrowed this down to a FAT issue. And yes, FAT32 in fat.c. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Wed Jan 30, 2013 9:54 am |
|
|
The weak pull-ups are not enough. The maximum specified is for SPI is 100K, and they don't switch on till the code says to do so. This can still give the CS glitch on boot. The external resistors are the way to go.
I'd triple check the mods you have done for MBR.
Also try FAT16, and see if anything changes.
I don't remember any specific problems around 4.128, though there did seem to be some oddities with some chips around then. Not a version I've 'kept' so can't try to see if it works.
Best Wishes |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Wed Jan 30, 2013 3:15 pm |
|
|
Progress...
Between andrewg's fixes to fat.c (and using my LOCAL copy with those changes applied, instead of the original from CCS), and finding a format that it likes, I'm able to do most of the things I need to. fat_init() works, and with the routines from ex_fat.c I can see the directory, tail a file, etc. From my program I can use fatread() to fill a buffer. There are some unexplained delays I need to chase down, but I'm almost there. |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Wed Jan 30, 2013 3:48 pm |
|
|
Now all I need to do is figure out how to make this all work with #pin_select, SPI2 and FORCE_HW. I can read a file... but slowly, around 3K byte/sec. Ugh. I need about 4x that speed at minumum, preferably 10x.
Back to the grind... sigh. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Wed Jan 30, 2013 4:30 pm |
|
|
dbotkin wrote: | Now all I need to do is figure out how to make this all work with #pin_select, SPI2 and FORCE_HW. I can read a file... but slowly, around 3K byte/sec. Ugh. I need about 4x that speed at minumum, preferably 10x.
Back to the grind... sigh. |
Check the speed you are running the SPI bus at. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Wed Jan 30, 2013 5:25 pm |
|
|
And how would you suggest I change that? Looking at #use_spi...
Quote: | BAUD=n
Target bits per second, default is as fast as possible.
CLOCK_HIGH=n
High time of clock in us (not needed if BAUD= is used). (default=0)
CLOCK_LOW=n
Low time of clock in us (not needed if BAUD= is used). (default=0) |
I tried setting BAUD to some different settings... none seemed to have a big impact.
No BAUD setting: 13 seconds to read a 41K file.
BAUD=1000000 -- Slower. 16 seconds for the same file.
BAUD=4000000 -- No change, same 16 seconds to read the file.
BAUD=8000000 -- Looks like 15 seconds.
BAUD=12000000 -- Won't read the card.
If I were using hardware SPI, I'd know for sure what the clock rate is. As it is I'm left wondering if this is a data transfer rate issue, or just atrocious delays in mmscd.c and fat.c. |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Thu Jan 31, 2013 11:58 pm |
|
|
OK, so a little more digging into mmcsd.c... not the one I had, but a new one Darren emailed me. Thanks, Darren!
mmcsd.c sets the baud to 400000 during mmcsd_init(). Darren's sets it to a more realistic speed, IF you're using the MSSP hardware. He also thoughtfully included some new code to make it easy to specify the MSSP hardware SPI. So... great.
Unfortunately, it still fails to detect the card any time I specify the hardware SPI. Software works great... hardware no. MOSI looks normal, but not CS or CLK. And of course without that, there's no MISO... and no love from the SD card.
I tried setting BAUD to several values far higher than the 400K to which it's initially set with the software SPI. No dice. The improvement in transfer rate is very slight. While waiting on more from CCS support, I'm continuing to look for any mistakes in my own code. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Feb 01, 2013 6:20 am |
|
|
I don't have your v4.128, but early versions of the mmcsd.c contained a bug where the SPI was initialized in a wrong SPI mode (mode 2). SD cards only work in mode 0 or 3.
In V4.138 the setup is correct: Code: | #use spi(MASTER, DI=MMCSD_PIN_SDI, DO=MMCSD_PIN_SDO, CLK=MMCSD_PIN_SCL, BITS=8, MSB_FIRST, MODE=0, stream=mmcsd_spi) |
Quote: | mmcsd.c sets the baud to 400000 during mmcsd_init(). | In the first MMC standard it was defined compulsory for the host device to start up with about 80 clock pulses at 400kHz. So CCS is correct here. Perhaps this requirement was dropped in newer versions of the standard but it's your risk to remove this. Only the slow start up is required, after that you can go full speed. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Fri Feb 01, 2013 8:05 am |
|
|
It's still there in the spec for SPI mode.
SPI mode itself is now 'optional' for MicroSD, _but_ since the cards all generally use variants of the same chipsets used for SD ((where it is still required), I've yet to see a card that doesn't have it.
It also raises a question, since how could a MicroSD card then work in an adapter to SD, where this mode is required....
Best Wishes |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Fri Feb 01, 2013 8:25 am |
|
|
ckielstra wrote: | In the first MMC standard it was defined compulsory for the host device to start up with about 80 clock pulses at 400kHz. So CCS is correct here. Perhaps this requirement was dropped in newer versions of the standard but it's your risk to remove this. Only the slow start up is required, after that you can go full speed. |
The new change to mmcsd.c only changes the speed after the startup, for that reason. After that it switches the clock to Fosc with a divisor (depending on the clock frequency) instead of using a timer for the clock. I don't know if this driver file is something CCS has released with newer compiler versions, or if it's just a modification Darren made. |
|
|
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
Frustrating. |
Posted: Fri Feb 01, 2013 7:15 pm |
|
|
OK, so we've pared this down to the bare minimum. Maybe someone here can see something that explains what we're not getting.
When this code is run, I get positive-going pulses on the chip select pin (PIN_D4) -- and nothing else. No SPI clock or data. It's as if the SPI2 module isn't even there. I've been through the .LST file and everything looks OK to me -- PPS seems to be getting set up correctly, SPI2 initialized, data getting stuffed into the SPI2 buffer. But I get nada on the actual device pins. It's enough to make me think about getting out the heat gun and replacing the chip.
Code: | #include <main.h>
#include "usb_bootloader.h"
#pin_select SDO2=PIN_D2
#pin_select SDI2=PIN_D3
#pin_select SCK2=PIN_D5
#pin_select SCK2IN=PIN_D5 // Per data sheet, page 296. Also tried without this.
#define MMCSD_PIN_SELECT PIN_D4
#use spi(SPI2, MASTER, bits=8, mode=0, ENABLE=MMCSD_PIN_SELECT, ENABLE_ACTIVE=1)
void main(void)
{
output_drive(PIN_D5);
output_drive(PIN_D2);
output_float(PIN_D3);
output_low(MMCSD_PIN_SELECT);
setup_spi2(spi_master |spi_l_to_h |spi_clk_div_4);
while(TRUE)
{
spi_xfer(0x55);
delay_ms(5);
}
} |
Code: | .................... #pin_select SDO2=PIN_D2
.................... #pin_select SDI2=PIN_D3
.................... #pin_select SCK2=PIN_D5
.................... #pin_select SCK2IN=PIN_D5
....................
.................... #define MMCSD_PIN_SELECT PIN_D4
....................
.................... #use spi(SPI2, MASTER, bits=8, mode=0, ENABLE=MMCSD_PIN_SELECT, ENABLE_ACTIVE=1)
*
01C08: BCF F95.4
01C0A: BSF F8C.4
01C0C: MOVF F75,W
01C0E: MOVFF 05,F75
01C12: RRCF F73,W
01C14: BNC 1C12
01C16: MOVFF F75,01
01C1A: BCF F95.4
01C1C: BCF F8C.4
01C1E: GOTO 1CC2 (RETURN)
....................
.................... void main(void)
.................... {
*
01C4C: CLRF FF8
01C4E: BCF FD0.7
01C50: MOVLB E
01C52: MOVLW 55
01C54: MOVWF FA7
01C56: MOVLW AA
01C58: MOVWF FA7
01C5A: BCF xBF.0
01C5C: MOVLW 14
01C5E: MOVWF xFC
01C60: MOVLW 16
01C62: MOVWF xFD
01C64: MOVLW 0A
01C66: MOVWF xD3
01C68: MOVLW 0B
01C6A: MOVWF xD6
01C6C: MOVLW 55
01C6E: MOVWF FA7
01C70: MOVLW AA
01C72: MOVWF FA7
01C74: BSF xBF.0
01C76: CLRF FEA
01C78: CLRF FE9
01C7A: BCF F72.5
01C7C: MOVLW 22
01C7E: MOVWF F72
01C80: MOVLW 40
01C82: MOVWF F73
01C84: BCF F95.4
01C86: BCF F95.4
01C88: BSF F8C.4
01C8A: MOVLB 1
01C8C: CLRF x88
01C8E: MOVLW FF
01C90: MOVLB F
01C92: MOVWF x48
01C94: BCF FC2.6
01C96: BCF FC2.7
01C98: MOVF x49,W
01C9A: ANDLW E0
01C9C: IORLW 1F
01C9E: MOVWF x49
01CA0: CLRF x25
01CA2: CLRF FD1
01CA4: CLRF FD2
....................
.................... output_drive(PIN_D5);
01CA6: BCF F95.5
.................... output_drive(PIN_D2);
01CA8: BCF F95.2
.................... output_float(PIN_D3);
01CAA: BSF F95.3
.................... output_low(MMCSD_PIN_SELECT);
01CAC: BCF F95.4
01CAE: BCF F8C.4
.................... setup_spi2(spi_master |spi_l_to_h |spi_clk_div_4);
01CB0: BCF F72.5
01CB2: MOVLW 20
01CB4: MOVWF F72
01CB6: MOVLW 00
01CB8: MOVWF F73
....................
.................... while(TRUE)
.................... {
.................... spi_xfer(0x55);
01CBA: MOVLW 55
01CBC: MOVWF 05
01CBE: MOVLB 0
01CC0: BRA 1C08
.................... delay_ms(5);
01CC2: MOVLW 05
01CC4: MOVWF 05
01CC6: BRA 1C22
.................... }
01CC8: MOVLB F
01CCA: BRA 1CBA
.................... }
....................
01CCC: SLEEP
Configuration Fuses:
Word 1: F7BE NOWDT PLL1 NOPLLEN STVREN NOXINST NODEBUG NOCPUDIV NOPROTECT
Word 2: F71A INTRC_PLL_IO SOSC_HIGH NOCLOCKOUT NOFCMEN NOIESO WDT128
Word 3: FAF3 DSWDTOSC_INT RTCOSC_T1 NODSBOR NODSWDT DSWDT2147483648 NOIOL1WAY ADC10 MSSPMSK7
Word 4: FBFF WPFP NOWPCFG WPDIS WPEND LS48MHZ |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Feb 02, 2013 2:48 am |
|
|
You are using SPI streams, and then _not_ using these for the transfer.
You need to use:
SPI_XFER(SPI2,0x55);
Then, get rid of the setup_spi2.
There are two distinct ways of using SPI with CCS. #use spi with spi_xfer, and streams, or setup_spix with spi_write/spi_read (no streams). You need to use one or the other, not both.
Your #use spi, needs to select SPI2 and the correct format.
Best Wishes |
|
|
|
|
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
|