mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:58:59 +08:00
Fix to lpc214x MMC/SD due to lm3s changes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1833 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -746,5 +746,8 @@
|
|||||||
* configs/eagle100/*/Make.defs: Added configuration options that should make
|
* configs/eagle100/*/Make.defs: Added configuration options that should make
|
||||||
it possible to build NuttX for the Eagle100 using CodeSourcery 2009q1 toolchain
|
it possible to build NuttX for the Eagle100 using CodeSourcery 2009q1 toolchain
|
||||||
and the devkitARM GNU toolchain.
|
and the devkitARM GNU toolchain.
|
||||||
|
* configs/mcu123-lpc214x/src: Corrected some logic in the LPC2148 SPI receive block
|
||||||
|
logic. Re-verified SDC ver1.x support with 1Gb Toshiba SDC, 1Gb PNY SDC, 2Gb SanDisk SDC,
|
||||||
|
and 4Gb Kingston SDHC.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<tr align="center" bgcolor="#e4e4e4">
|
<tr align="center" bgcolor="#e4e4e4">
|
||||||
<td>
|
<td>
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
|
||||||
<p>Last Updated: May 27, 2009</p>
|
<p>Last Updated: May 28, 2009</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -1436,6 +1436,9 @@ nuttx-0.4.7 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
|||||||
* configs/eagle100/*/Make.defs: Added configuration options that should make
|
* configs/eagle100/*/Make.defs: Added configuration options that should make
|
||||||
it possible to build NuttX for the Eagle100 using CodeSourcery 2009q1 toolchain
|
it possible to build NuttX for the Eagle100 using CodeSourcery 2009q1 toolchain
|
||||||
and the devkitARM GNU toolchain.
|
and the devkitARM GNU toolchain.
|
||||||
|
* configs/mcu123-lpc214x/src: Corrected some logic in the LPC2148 SPI receive block
|
||||||
|
logic. Re-verified SDC ver1.x support with 1Gb Toshiba SDC, 1Gb PNY SDC, 2Gb SanDisk SDC,
|
||||||
|
and 4Gb Kingston SDHC.
|
||||||
|
|
||||||
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
pascal-0.1.3 2009-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<h1><big><font color="#3c34ec">
|
<h1><big><font color="#3c34ec">
|
||||||
<i>NuttX RTOS Porting Guide</i>
|
<i>NuttX RTOS Porting Guide</i>
|
||||||
</font></big></h1>
|
</font></big></h1>
|
||||||
<p>Last Updated: May 22, 2009</p>
|
<p>Last Updated: May 28, 2009</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -2180,6 +2180,12 @@ extern void up_ledoff(int led);
|
|||||||
<li>
|
<li>
|
||||||
<code>CONFIG_MMCSD_READONLY</code>: Provide read-only access. Default is Read/Write
|
<code>CONFIG_MMCSD_READONLY</code>: Provide read-only access. Default is Read/Write
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>CONFIG_MMCSD_SPICLOCK</code>: Maximum SPI clock to drive MMC/SD card. Default is 20MHz.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>CONFIG_MMCSD_SYNCHRONIZE</code>: Special synchronization logic needed
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2>Network Support</h2>
|
<h2>Network Support</h2>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# Makefile
|
# Makefile
|
||||||
#
|
#
|
||||||
# Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
# Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||||
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
@@ -268,7 +268,7 @@ subdir_clean:
|
|||||||
@$(MAKE) -C tools -f Makefile.mkconfig TOPDIR="$(TOPDIR)" clean
|
@$(MAKE) -C tools -f Makefile.mkconfig TOPDIR="$(TOPDIR)" clean
|
||||||
@$(MAKE) -C mm -f Makefile.test TOPDIR="$(TOPDIR)" clean
|
@$(MAKE) -C mm -f Makefile.test TOPDIR="$(TOPDIR)" clean
|
||||||
|
|
||||||
clean: subdir_clean clean_context
|
clean: subdir_clean
|
||||||
@rm -f $(BIN) nuttx.* mm_test *.map *~
|
@rm -f $(BIN) nuttx.* mm_test *.map *~
|
||||||
|
|
||||||
subdir_distclean:
|
subdir_distclean:
|
||||||
@@ -278,7 +278,7 @@ subdir_distclean:
|
|||||||
fi \
|
fi \
|
||||||
done
|
done
|
||||||
|
|
||||||
distclean: clean subdir_distclean
|
distclean: clean subdir_distclean clean_context
|
||||||
@rm -f Make.defs setenv.sh .config
|
@rm -f Make.defs setenv.sh .config
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -287,6 +287,7 @@ defconfig -- This is a configuration file similar to the Linux
|
|||||||
Read/Write
|
Read/Write
|
||||||
CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
Default is 20MHz.
|
Default is 20MHz.
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE - Special synchronization logic needed
|
||||||
|
|
||||||
TCP/IP and UDP support via uIP
|
TCP/IP and UDP support via uIP
|
||||||
CONFIG_NET - Enable or disable all network features
|
CONFIG_NET - Enable or disable all network features
|
||||||
|
|||||||
@@ -359,10 +359,13 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
# Default is 20MHz.
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
#
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
CONFIG_MMCSD_SPICLOCK=12500000
|
CONFIG_MMCSD_SPICLOCK=12500000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=n
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -359,10 +359,13 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
# Default is 20MHz.
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
#
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
CONFIG_MMCSD_SPICLOCK=12500000
|
CONFIG_MMCSD_SPICLOCK=12500000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=n
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -358,10 +358,13 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
# Default is 20MHz.
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
#
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
CONFIG_MMCSD_SPICLOCK=12500000
|
CONFIG_MMCSD_SPICLOCK=12500000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=n
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -358,10 +358,13 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
# Default is 20MHz.
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
#
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
CONFIG_MMCSD_SPICLOCK=12500000
|
CONFIG_MMCSD_SPICLOCK=12500000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=n
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -301,9 +301,21 @@ CONFIG_FS_FAT=y
|
|||||||
CONFIG_FS_ROMFS=n
|
CONFIG_FS_ROMFS=n
|
||||||
|
|
||||||
#
|
#
|
||||||
# MMC/SD configuration
|
# SPI-based MMC/SD driver
|
||||||
|
#
|
||||||
|
# CONFIG_MMCSD_NSLOTS
|
||||||
|
# Number of MMC/SD slots supported by the driver
|
||||||
|
# CONFIG_MMCSD_READONLY
|
||||||
|
# Provide read-only access (default is read/write)
|
||||||
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
|
#CONFIG_MMCSD_SPICLOCK=20000000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# SPI-based MMC/SD driver
|
# SPI-based MMC/SD driver
|
||||||
|
|||||||
@@ -303,8 +303,15 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Number of MMC/SD slots supported by the driver
|
# Number of MMC/SD slots supported by the driver
|
||||||
# CONFIG_MMCSD_READONLY
|
# CONFIG_MMCSD_READONLY
|
||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
|
#CONFIG_MMCSD_SPICLOCK=20000000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
#include <nuttx/spi.h>
|
#include <nuttx/spi.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
#include <arch/board/board.h>
|
#include <arch/board/board.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
@@ -79,9 +80,31 @@
|
|||||||
* Definitions
|
* Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Enables debug output from this file (needs CONFIG_DEBUG too) */
|
||||||
|
|
||||||
|
#undef SPI_DEBUG /* Define to enable debug */
|
||||||
|
#undef SPI_VERBOSE /* Define to enable verbose debug */
|
||||||
|
|
||||||
|
#ifdef SPI_DEBUG
|
||||||
|
# define spidbg lldbg
|
||||||
|
# ifdef SPI_VERBOSE
|
||||||
|
# define spivdbg lldbg
|
||||||
|
# else
|
||||||
|
# define spivdbg(x...)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# undef SPI_VERBOSE
|
||||||
|
# define spidbg(x...)
|
||||||
|
# define spivdbg(x...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Clocking */
|
||||||
|
|
||||||
#define LPC214X_CCLKFREQ (LPC214X_FOSC*LPC214X_PLL_M)
|
#define LPC214X_CCLKFREQ (LPC214X_FOSC*LPC214X_PLL_M)
|
||||||
#define LPC214X_PCLKFREQ (LPC214X_CCLKFREQ/LPC214X_APB_DIV)
|
#define LPC214X_PCLKFREQ (LPC214X_CCLKFREQ/LPC214X_APB_DIV)
|
||||||
|
|
||||||
|
/* Use either FIO or legacy GPIO */
|
||||||
|
|
||||||
#ifdef CONFIG_LPC214x_FIO
|
#ifdef CONFIG_LPC214x_FIO
|
||||||
# define CS_SET_REGISTER (LPC214X_FIO0_BASE+LPC214X_FIO_SET_OFFSET)
|
# define CS_SET_REGISTER (LPC214X_FIO0_BASE+LPC214X_FIO_SET_OFFSET)
|
||||||
# define CS_CLR_REGISTER (LPC214X_FIO0_BASE+LPC214X_FIO_CLR_OFFSET)
|
# define CS_CLR_REGISTER (LPC214X_FIO0_BASE+LPC214X_FIO_CLR_OFFSET)
|
||||||
@@ -153,12 +176,14 @@ static void spi_select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, boolean
|
|||||||
{
|
{
|
||||||
/* Enable slave select (low enables) */
|
/* Enable slave select (low enables) */
|
||||||
|
|
||||||
|
spidbg("CD asserted\n");
|
||||||
putreg32(bit, CS_CLR_REGISTER);
|
putreg32(bit, CS_CLR_REGISTER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Disable slave select (low enables) */
|
/* Disable slave select (low enables) */
|
||||||
|
|
||||||
|
spidbg("CD de-asserted\n");
|
||||||
putreg32(bit, CS_SET_REGISTER);
|
putreg32(bit, CS_SET_REGISTER);
|
||||||
|
|
||||||
/* Wait for the TX FIFO not full indication */
|
/* Wait for the TX FIFO not full indication */
|
||||||
@@ -214,6 +239,8 @@ static uint32 spi_setfrequency(FAR struct spi_dev_s *dev, uint32 frequency)
|
|||||||
|
|
||||||
divisor = (divisor + 1) & ~1;
|
divisor = (divisor + 1) & ~1;
|
||||||
putreg8(divisor, LPC214X_SPI1_CPSR);
|
putreg8(divisor, LPC214X_SPI1_CPSR);
|
||||||
|
|
||||||
|
spidbg("Frequency %d->%d\n", frequency, LPC214X_PCLKFREQ / divisor);
|
||||||
return LPC214X_PCLKFREQ / divisor;
|
return LPC214X_PCLKFREQ / divisor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,6 +265,7 @@ static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
|
|||||||
* board.
|
* board.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
spidbg("Return SPI_STATUS_PRESENT\n");
|
||||||
return SPI_STATUS_PRESENT;
|
return SPI_STATUS_PRESENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,6 +287,8 @@ static ubyte spi_status(FAR struct spi_dev_s *dev, enum spi_dev_e devid)
|
|||||||
|
|
||||||
static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
|
static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
|
||||||
{
|
{
|
||||||
|
register uint16 regval;
|
||||||
|
|
||||||
/* Wait while the TX FIFO is full */
|
/* Wait while the TX FIFO is full */
|
||||||
|
|
||||||
while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF));
|
while (!(getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF));
|
||||||
@@ -273,7 +303,9 @@ static uint16 spi_send(FAR struct spi_dev_s *dev, uint16 wd)
|
|||||||
|
|
||||||
/* Get the value from the RX FIFO and return it */
|
/* Get the value from the RX FIFO and return it */
|
||||||
|
|
||||||
return (uint16)getreg16(LPC214X_SPI1_DR);
|
regval = getreg16(LPC214X_SPI1_DR);
|
||||||
|
spidbg("%04x->%04x\n", wd, regval);
|
||||||
|
return regval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -302,6 +334,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||||||
|
|
||||||
/* Loop while thre are bytes remaining to be sent */
|
/* Loop while thre are bytes remaining to be sent */
|
||||||
|
|
||||||
|
spidbg("nwords: %d\n", nwords);
|
||||||
while (nwords > 0)
|
while (nwords > 0)
|
||||||
{
|
{
|
||||||
/* While the TX FIFO is not full and there are bytes left to send */
|
/* While the TX FIFO is not full and there are bytes left to send */
|
||||||
@@ -318,6 +351,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||||||
|
|
||||||
/* Then discard all card responses until the RX & TX FIFOs are emptied. */
|
/* Then discard all card responses until the RX & TX FIFOs are emptied. */
|
||||||
|
|
||||||
|
spidbg("discarding\n");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Is there anything in the RX fifo? */
|
/* Is there anything in the RX fifo? */
|
||||||
@@ -367,11 +401,12 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer, size
|
|||||||
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nwords)
|
||||||
{
|
{
|
||||||
FAR ubyte *ptr = (FAR ubyte*)buffer;
|
FAR ubyte *ptr = (FAR ubyte*)buffer;
|
||||||
uint32 fifobytes = 0;
|
uint32 rxpending = 0;
|
||||||
|
|
||||||
/* While there is remaining to be sent (and no synchronization error has occurred) */
|
/* While there is remaining to be sent (and no synchronization error has occurred) */
|
||||||
|
|
||||||
while (ptr || fifobytes)
|
spidbg("nwords: %d\n", nwords);
|
||||||
|
while (nwords || rxpending)
|
||||||
{
|
{
|
||||||
/* Fill the transmit FIFO with 0xff...
|
/* Fill the transmit FIFO with 0xff...
|
||||||
* Write 0xff to the data register while (1) the TX FIFO is
|
* Write 0xff to the data register while (1) the TX FIFO is
|
||||||
@@ -379,20 +414,22 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer, size_t nw
|
|||||||
* and (3) there are more bytes to be sent.
|
* and (3) there are more bytes to be sent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
spivdbg("TX: rxpending: %d nwords: %d\n", rxpending, nwords);
|
||||||
while ((getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF) &&
|
while ((getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_TNF) &&
|
||||||
(fifobytes < LPC214X_SPI1_FIFOSZ) && nwords)
|
(rxpending < LPC214X_SPI1_FIFOSZ) && nwords)
|
||||||
{
|
{
|
||||||
putreg16(0xff, LPC214X_SPI1_DR);
|
putreg16(0xff, LPC214X_SPI1_DR);
|
||||||
nwords--;
|
nwords--;
|
||||||
fifobytes++;
|
rxpending++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */
|
/* Now, read the RX data from the RX FIFO while the RX FIFO is not empty */
|
||||||
|
|
||||||
|
spivdbg("RX: rxpending: %d\n", rxpending);
|
||||||
while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)
|
while (getreg8(LPC214X_SPI1_SR) & LPC214X_SPI1SR_RNE)
|
||||||
{
|
{
|
||||||
*ptr++ = (ubyte)getreg16(LPC214X_SPI1_DR);
|
*ptr++ = (ubyte)getreg16(LPC214X_SPI1_DR);
|
||||||
fifobytes--;
|
rxpending--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,8 +308,15 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Number of MMC/SD slots supported by the driver
|
# Number of MMC/SD slots supported by the driver
|
||||||
# CONFIG_MMCSD_READONLY
|
# CONFIG_MMCSD_READONLY
|
||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
|
#CONFIG_MMCSD_SPICLOCK=20000000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -308,8 +308,15 @@ CONFIG_FS_ROMFS=n
|
|||||||
# Number of MMC/SD slots supported by the driver
|
# Number of MMC/SD slots supported by the driver
|
||||||
# CONFIG_MMCSD_READONLY
|
# CONFIG_MMCSD_READONLY
|
||||||
# Provide read-only access (default is read/write)
|
# Provide read-only access (default is read/write)
|
||||||
|
# CONFIG_MMCSD_SPICLOCK - Maximum SPI clock to drive MMC/SD card.
|
||||||
|
# Default is 20MHz.
|
||||||
|
# CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
# Special synchronization logic needed
|
||||||
|
#
|
||||||
CONFIG_MMCSD_NSLOTS=1
|
CONFIG_MMCSD_NSLOTS=1
|
||||||
CONFIG_MMCSD_READONLY=n
|
CONFIG_MMCSD_READONLY=n
|
||||||
|
#CONFIG_MMCSD_SPICLOCK=20000000
|
||||||
|
CONFIG_MMCSD_SYNCHRONIZE=y
|
||||||
|
|
||||||
#
|
#
|
||||||
# TCP/IP and UDP support via uIP
|
# TCP/IP and UDP support via uIP
|
||||||
|
|||||||
@@ -168,6 +168,9 @@ static void mmcsd_semtake(sem_t *sem);
|
|||||||
|
|
||||||
/* Card SPI interface *******************************************************/
|
/* Card SPI interface *******************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
static inline void mmcsd_synchronize(FAR struct mmcsd_slot_s *slot);
|
||||||
|
#endif
|
||||||
static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot);
|
static int mmcsd_waitready(FAR struct mmcsd_slot_s *slot);
|
||||||
static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
|
static uint32 mmcsd_sendcmd(FAR struct mmcsd_slot_s *slot,
|
||||||
const struct mmcsd_cmdinfo_s *cmd, uint32 arg);
|
const struct mmcsd_cmdinfo_s *cmd, uint32 arg);
|
||||||
@@ -343,6 +346,38 @@ static void mmcsd_semtake(sem_t *sem)
|
|||||||
|
|
||||||
#define mmcsd_semgive(sem) sem_post(sem)
|
#define mmcsd_semgive(sem) sem_post(sem)
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: mmcsd_synchronize
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Wait until the the card is no longer busy
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* MMC/SD card already selected
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_SYNCHRONIZE
|
||||||
|
static inline void mmcsd_synchronize(FAR struct mmcsd_slot_s *slot)
|
||||||
|
{
|
||||||
|
FAR struct spi_dev_s *spi = slot->spi;
|
||||||
|
|
||||||
|
/* De-select the MMCSD card */
|
||||||
|
|
||||||
|
SPI_SELECT(spi, SPIDEV_MMCSD, FALSE);
|
||||||
|
|
||||||
|
/* Wait a bit */
|
||||||
|
|
||||||
|
SPI_SEND(spi, 0xff);
|
||||||
|
|
||||||
|
/* Reselect the card */
|
||||||
|
|
||||||
|
SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define mmcsd_synchronize(slot) /* No synchronization needed */s
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: mmcsd_waitready
|
* Name: mmcsd_waitready
|
||||||
*
|
*
|
||||||
@@ -625,7 +660,7 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, ubyte *csd)
|
|||||||
g_transpeedru[MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)];
|
g_transpeedru[MMCSD_CSD_TRANSPEED_TRANSFERRATEUNIT(csd)];
|
||||||
|
|
||||||
/* Clip the max frequency to account for board limitations */
|
/* Clip the max frequency to account for board limitations */
|
||||||
|
|
||||||
frequency = maxfrequency;
|
frequency = maxfrequency;
|
||||||
if (frequency > CONFIG_MMCSD_SPICLOCK)
|
if (frequency > CONFIG_MMCSD_SPICLOCK)
|
||||||
{
|
{
|
||||||
@@ -804,6 +839,7 @@ static int mmcsd_getcardinfo(FAR struct mmcsd_slot_s *slot, ubyte *buffer,
|
|||||||
|
|
||||||
/* Send the CMD9 or CMD10 */
|
/* Send the CMD9 or CMD10 */
|
||||||
|
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, cmd, 0);
|
result = mmcsd_sendcmd(slot, cmd, 0);
|
||||||
if (result != MMCSD_SPIR1_OK)
|
if (result != MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
@@ -1081,7 +1117,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
|
|
||||||
mmcsd_semtake(&slot->sem);
|
mmcsd_semtake(&slot->sem);
|
||||||
SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
|
SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
|
||||||
SPI_SEND(spi, 0xff);
|
mmcsd_synchronize(slot);
|
||||||
|
|
||||||
/* Single or multiple block read? */
|
/* Single or multiple block read? */
|
||||||
|
|
||||||
@@ -1108,7 +1144,7 @@ static ssize_t mmcsd_read(FAR struct inode *inode, unsigned char *buffer,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Send CMD17: Reads a block of the size selected by the SET_BLOCKLEN
|
/* Send CMD18: Reads a block of the size selected by the SET_BLOCKLEN
|
||||||
* command and verify that good R1 status is returned
|
* command and verify that good R1 status is returned
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1243,7 +1279,7 @@ static ssize_t mmcsd_write(FAR struct inode *inode, const unsigned char *buffer,
|
|||||||
|
|
||||||
mmcsd_semtake(&slot->sem);
|
mmcsd_semtake(&slot->sem);
|
||||||
SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
|
SPI_SELECT(spi, SPIDEV_MMCSD, TRUE);
|
||||||
SPI_SEND(spi, 0xff);
|
mmcsd_synchronize(slot);
|
||||||
|
|
||||||
/* Single or multiple block transfer? */
|
/* Single or multiple block transfer? */
|
||||||
|
|
||||||
@@ -1533,9 +1569,11 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
|
fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
||||||
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_acmd41, 1 << 30);
|
result = mmcsd_sendcmd(slot, &g_acmd41, 1 << 30);
|
||||||
if (result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
@@ -1578,11 +1616,13 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
|
|||||||
/* Both the MMC card and the SD card support CMD55 */
|
/* Both the MMC card and the SD card support CMD55 */
|
||||||
|
|
||||||
fvdbg("Send CMD55/ACMD41\n");
|
fvdbg("Send CMD55/ACMD41\n");
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
||||||
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
/* But ACMD41 is supported only on SD */
|
/* But ACMD41 is supported only on SD */
|
||||||
|
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
|
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
|
||||||
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
@@ -1600,9 +1640,11 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
|
|||||||
if (IS_SD(slot->type))
|
if (IS_SD(slot->type))
|
||||||
{
|
{
|
||||||
fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
|
fvdbg("%d. Send CMD55/ACMD41\n", elapsed);
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
result = mmcsd_sendcmd(slot, &g_cmd55, 0);
|
||||||
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_IDLESTATE || result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
|
result = mmcsd_sendcmd(slot, &g_acmd41, 0);
|
||||||
if (result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
@@ -1613,6 +1655,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
fvdbg("%d. Send CMD1\n", i);
|
fvdbg("%d. Send CMD1\n", i);
|
||||||
|
mmcsd_synchronize(slot);
|
||||||
result = mmcsd_sendcmd(slot, &g_cmd1, 0);
|
result = mmcsd_sendcmd(slot, &g_cmd1, 0);
|
||||||
if (result == MMCSD_SPIR1_OK)
|
if (result == MMCSD_SPIR1_OK)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user