I tried to connect the two memory card devices by connecting it on ssp port of lpc2148, i have access to memory cards when i enabling them one by one but i can't access memory card device 1 when i'm enabling the both devices on file configuration.c I connected both card's MOSI,MISO,SCLK on same ssp port of lpc2148,i'm using GPIO port 0.20 for ss of one memory card and GPIO port 0.07 of another memory card
I used example program for SD_file in MCB2140 ,i modified spi driver with ss pin as gpio port 0.07 for second device,for first device i'm using inbuilt spi driver
NOTE: I can access both device separately on same bus,i can't able to access them at a time
PLS give some idea
> if I enabled two drives
How did you enable two drives? I believe this the supposed way to add MC1.
1) Enable MC1 in File_Config.c
C:\Keil\ARM\Boards\Keil\MCB2140\RL\FlashFS\SD_File\File_Config.c // </e> // <e>Memory Card Drive 1 // ====================== // Enable Memory Card Drive [M1:] #define MC1_EN 0 // <---- 1
Optionally, you may attach a cache (MC1_CASZ) to this drive, like MC0 In this case, the cache address (MC1_CADR) should be placed, so that it doesn't overlap MC0's.
2) Add another SPI driver object (spi1_drv) for MC1 Copy and modiy the SPI driver file (SPI_LPC214x.c) for MC1
C:\Keil\ARM\Boards\Keil\MCB2140\RL\FlashFS\SD_File\SPI_LPC214x_MC1.c (copied SPI_LPC214x.c) #define __DRV_ID spi0_drv // <---- spi1_drv
In your case, SetSS() is customized, too, to select target SD card, both in the original and copied. As most of the routines on the copied file is common to the original, You may combine them into single file.
Tsuneo
He's still likely to have to do something in his hardware abstraction code to mediate/arbitrate access between the two mutually exclusive devices. This is not a responsibility of the file system, but rather the driver for the board/card scheme.
The driver side would appear to function at the individual level, and that's great, but code is still going to need to be written to manage the two together. This part is missing, poking at the existing code isn't going to address that.
So it's stuck in a loop, ok that's great, but why? If you don't sufficiently grasp the low level driver code, and the interplay with the higher level code, then you'll need to instrument the interface points, and become familiar with what's happening, when and why.
This isn't Keil's responsibility, it is the responsibility of the implementer, the one tasked with making the board support package or board drivers. If the task exceeds your skillset consider out-sourcing the task.
> but code is still going to need to be written to manage the two together.
I believe the target drive managemnet is already there, without any additional code by user. In the SPI connection of SD card, - CS is asserted to start an operation (command - response - data). - CS must be kept active while an operation is going on. - At the end of operation, CS is deserted.
CS (SS) is also applied to activate one of SD cards, which share single SPI bus. Therefore, operations occur exclusively for each SD card on the bus.
"CS (SS) is also applied to activate one of SD cards, which share single SPI bus"
But is that actually designed & able to manage two separate CS (SS) lines to select between one of two SD cards sharing the same SPI bus...?
I'm using seperate cs(ss)for each sd card
I think that cs assertion and deassertion will happen when initializing a card with fat initialization if it is defined in low level spi driver needed for Flash fs
You think?
And you think debugging shouldn't be used to verify that one driver is 100% done with the interface before the other driver gets jobs to do?
>Andrew Neil: But is that actually designed & able to manage two separate CS (SS) lines to select between one of two SD cards sharing the same SPI bus…?
It's already added, as described on my above post. "2) Add another SPI driver object (spi1_drv) for MC1 In your case, SetSS() is customized, too, to select target SD card, both in the original and copied."
Ravi, Maybe, spurious signaling on the SPI bus makes the second SD card confused.
1) Pull-up resistors at SPI pins and each CS (SS) pin The I/O ports of LPC2148 are set to input (floating) after reset, including power up. To avoid spurious signaling on SPI bus, these pull-ups are required.
2) Init() / UnInit() on the SPI driver The original Init()/UnInit() routines in SPI_LPC214x.c touch to SPI and SS ports setting. The ports should be initialized once, at the global start-up initialization. And they should be kept untouched while the MCU is running.
Init() / UnInit() change just SPI registers.
C:\Keil\ARM\Boards\Keil\MCB2140\RL\FlashFS\SD_File\SPI_LPC214x.c static BOOL Init (void) { /* Initialize and enable the SSP Interface module. */ /* <------- move these lines into the global start up initialization // SSEL is GPIO, output set to high. IODIR0 |= 1<<20; IOSET0 = 1<<20; // SCK1, MISO1, MOSI1 are SSP pins. PINSEL1 = (PINSEL1 & ~0x000003FC) | 0x000000A8; */ // reset SPI SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; /* Enable SPI in Master Mode, CPOL=0, CPHA=0. */ SSPCR0 = 0x0007; SSPCR1 = 0x0002; SSPCPSR = 0xFE; return (__TRUE); } /*--------------------------- UnInit ----------------------------------------*/ static BOOL UnInit (void) { /* Return SSP interface to default state. */ /* <---- delete these lines IODIR0 &= ~(1<<20); PINSEL1 &= ~0x000003FC; */ SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; return (__TRUE); }
3) finit() finit(NULL), in init_card() on the demo, initializes both of SD cards. To ensure separate initialization per the cards, this call is replaced with finit("M0:") and finit("M1:")
C:\Keil\ARM\Boards\Keil\MCB2140\RL\FlashFS\SD_File\SD_File.c static void init_card (void) { U32 retv; while ((retv = finit (NULL)) != 0) { // Wait until the Card is ready
I'm using pullup of 10k for M0SI,MISO and SS pins of both sd cards there are two pullups in a MOSI and MISO pins
This is my spi driver
/*---------------------------------------------------------------------------- SPI Driver instance definition spi0_drv: First SPI driver spi1_drv: Second SPI driver *---------------------------------------------------------------------------*/ //#define __DRV_ID spi1_drv #define __PCLK 48000000 /* SPI Driver Interface functions */ static BOOL Init (void); static BOOL Init1 (void); static BOOL UnInit (void); static BOOL UnInit1 (void); static U8 Send (U8 outb); static BOOL SendBuf (U8 *buf, U32 sz); static BOOL RecBuf (U8 *buf, U32 sz); static BOOL BusSpeed (U32 kbaud); static BOOL SetSS (U32 ss); static BOOL SetSS1 (U32 ss); static U32 CheckMedia (void); /* Optional function for SD card check */ /* SPI Device Driver Control Block */ SPI_DRV spi0_drv = { Init, UnInit, Send, SendBuf, RecBuf, BusSpeed, SetSS, CheckMedia /* Can be NULL if not existing */ }; /* SSPSR - bit definitions. */ #define TFE 0x01 #define TNF 0x02 #define RNE 0x04 #define RFF 0x08 #define BSY 0x10 SPI_DRV spi1_drv = { Init1, UnInit1, Send, SendBuf, RecBuf, BusSpeed, SetSS1, CheckMedia /* Can be NULL if not existing */ }; /*--------------------------- Init ------------------------------------------*/ static BOOL Init (void) { /* Initialize and enable the SSP Interface module. */ /* SSEL is GPIO, output set to high. */ IODIR0 |= 1<<20; IOSET0 = 1<<20; /* SCK1, MISO1, MOSI1 are SSP pins. */ PINSEL1 = (PINSEL1 & ~0x000003FC) | 0x000000A8; // reset SPI SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; /* Enable SPI in Master Mode, CPOL=0, CPHA=0. */ SSPCR0 = 0x0007; SSPCR1 = 0x0002; SSPCPSR = 0xFE; return (__TRUE); } /*--------------------------- UnInit ----------------------------------------*/ static BOOL UnInit (void) { /* Return SSP interface to default state. */ IODIR0 &= ~(1<<20); PINSEL1 &= ~0x000003FC; SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; return (__TRUE); } /*--------------------------- Send ------------------------------------------*/ static U8 Send (U8 outb) { /* Send and Receive a byte on SPI interface. */ SSPDR = outb; /* Wait if RNE cleared, Rx FIFO is empty. */ while (!(SSPSR & RNE)); return (SSPDR); } /*--------------------------- SendBuf ---------------------------------------*/ static BOOL SendBuf (U8 *buf, U32 sz) { /* Send buffer to SPI interface. */ U32 i; for (i = 0; i < sz; i++) { SSPDR = buf[i]; /* Wait if Tx FIFO is full. */ while (!(SSPSR & TNF)); SSPDR; } /* Wait until Tx finished, drain Rx FIFO. */ while (SSPSR & (BSY | RNE)) { SSPDR; } return (__TRUE); } /*--------------------------- RecBuf ----------------------------------------*/ static BOOL RecBuf (U8 *buf, U32 sz) { /* Receive SPI data to buffer. */ U32 i; for (i = 0; i < sz; i++) { SSPDR = 0xFF; /* Wait while Rx FIFO is empty. */ while (!(SSPSR & RNE)); buf[i] = SSPDR; } return (__TRUE); } /*--------------------------- BusSpeed --------------------------------------*/ static BOOL BusSpeed (U32 kbaud) { /* Set an SPI clock to required baud rate. */ U32 div; div = (__PCLK/1000 + kbaud - 1) / kbaud; if (div == 0) div = 0x02; if (div & 1) div++; if (div > 0xFE) div = 0xFE; SSPCPSR = div; return (__TRUE); } /*--------------------------- SetSS -----------------------------------------*/ static BOOL SetSS (U32 ss) { /* Enable/Disable SPI Chip Select (drive it high or low). */ if (ss) { /* SSEL is GPIO, output set to high. */ IOSET0 = 1<<20; } else { /* SSEL is GPIO, output set to low. */ IOCLR0 = 1<<20; } return (__TRUE); } /*--------------------------- CheckMedia ------------------------------------*/ static U32 CheckMedia (void) { /* Read CardDetect and WriteProtect SD card socket pins. */ U32 stat = 0; #if 0 if (!(IOPIN0 & 0x04)) { /* Card is inserted (CD=0). */ stat |= M_INSERTED; } if ((IOPIN0 & 0x20)) { /* Write Protect switch is active (WP=1). */ stat |= M_PROTECTED; } #else /* When CD,WP signals are not connected. */ stat = M_INSERTED; #endif return (stat); } static BOOL SetSS1 (U32 ss) { /* Enable/Disable SPI Chip Select (drive it high or low). */ if (ss) { /* SSEL is GPIO, output set to high. */ IOSET0 = 1<<7; } else { /* SSEL is GPIO, output set to low. */ IOCLR0 = 1<<7; } return (__TRUE); } /*--------------------------- Init ------------------------------------------*/ static BOOL Init1 (void) { /* Initialize and enable the SSP Interface module. */ /* SSEL is GPIO, output set to high. */ IODIR0 |= 1<<7; IOSET0 = 1<<7; /* SCK1, MISO1, MOSI1 are SSP pins. */ PINSEL1 = (PINSEL1 & ~0x00000FC) | 0x000000A8; // reset SPI SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; /* Enable SPI in Master Mode, CPOL=0, CPHA=0. */ SSPCR0 = 0x0007; SSPCR1 = 0x0002; SSPCPSR = 0xFE; return (__TRUE); } /*--------------------------- UnInit ----------------------------------------*/ static BOOL UnInit1 (void) { /* Return SSP interface to default state. */ IODIR0 &= ~(1<<8); PINSEL1 &= ~0x00000FC; SSPCR1 = 0x0000; SSPCR0 = 0x0000; SSPCPSR = 0x00; return (__TRUE); }
What do you mean by "here are two pullups in a MOSI and MISO pins"
Each signal only needs one pullup resistor even if you connect the signal to two memory cards.
Don't you see any issues with having two drivers perform operations on the same registers?
What if the two memory card "drivers" gets called with different baudrate?
And next thing - have you verified if the file system code initializes an interface before every use and then uninitializes it? Or if it initializes both interfaces and then leaves them initialized?
Now i'm able access two drives in same bus i done a small mistake in my spi1_drv uninit function, you can see it on my above posted code
THANK U ALL for kind advice and guidance
You really should consider initializing the slave-select lines totally outside of your file system code. However many init/uninit you do, the slave-select for each memory card should be in "idle" state at all times when you aren't doing any transfers. So you should deassert them on boot. And they should stay that way after any uninit() calls.