Added: MT29F2G Nand Flash block driver for sam4s-xplained-pro.

Fixed: SDIO Interface hanging after inserted SD Card.

Disabled the CONFIG_SYSTEMTICK_EXTCLK, using nxsig_usleep instead of usleep
This commit is contained in:
yjdwbj 2020-12-02 23:03:31 +08:00 committed by Brennan Ashton
parent 607ff94793
commit 6aba444359
17 changed files with 1488 additions and 38 deletions

View File

@ -814,6 +814,17 @@ config SAM34_EXTNANDSIZE
default 0
---help---
Size of the external NAND in bytes.
config SAM34_HAVE_NAND
bool
default n
config SAM34_NAND_DUMP
bool "NAND data dump"
default n
depends on DEBUG_FEATURES && DEBUG_FS
---help---
Dump the contents of all data read and written to FLASH. Depends on
CONFIG_DEBUG_FEATURES and DEBUG_FS.
endif # SAM34_EXTNAND

View File

@ -149,6 +149,10 @@ ifeq ($(CONFIG_SAM34_HSMCI),y)
CHIP_CSRCS += sam_hsmci.c
endif
ifeq ($(CONFIG_SAM34_EXTNAND),y)
CHIP_CSRCS += sam4s_nand.c
endif
ifeq ($(CONFIG_SAM34_SPI0),y)
CHIP_CSRCS += sam_spi.c
else

View File

@ -128,7 +128,7 @@
/* MATRIX register addresses ************************************************************/
#define SAM_MATRIX_MCFG(n)) (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n))
#define SAM_MATRIX_MCFG(n) (SAM_MATRIX_BASE+SAM_MATRIX_MCFG_OFFSET(n))
#define SAM_MATRIX_MCFG0 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG0_OFFSET)
#define SAM_MATRIX_MCFG1 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG1_OFFSET)
#define SAM_MATRIX_MCFG2 (SAM_MATRIX_BASE+SAM_MATRIX_MCFG2_OFFSET)
@ -200,6 +200,7 @@
#define SAM_MATRIX_WPSR (SAM_MATRIX_BASE+SAM_MATRIX_WPSR_OFFSET)
/* MATRIX register bit definitions ******************************************************/
/* Master Configuration Registers */
#define MATRIX_MCFG_ULBT_SHIFT (0) /* Bits 0-2: Undefined Length Burst Type */
@ -309,6 +310,7 @@
/* SMC Chip Select NAND Flash Assignment Register */
#if defined(CONFIG_ARCH_CHIP_SAM4S) || defined(CONFIG_ARCH_CHIP_SAM4E)
#define MATRIX_CCFG_SMCNFCS_SMC_NFCS(n) (1<<(n)) /* Bit n: SMC NAND Flash Chip Select n Assignment */
# define MATRIX_CCFG_SMCNFCS_SMC_NFCS0 (1 << 0) /* Bit 0: SMC NAND Flash Chip Select 0 Assignment */
# define MATRIX_CCFG_SMCNFCS_SMC_NFCS1 (1 << 1) /* Bit 1: SMC NAND Flash Chip Select 2 Assignment */
# define MATRIX_CCFG_SMCNFCS_SMC_NFCS2 (1 << 2) /* Bit 2: SMC NAND Flash Chip Select 2 Assignment */
@ -364,8 +366,4 @@
* Public Data
****************************************************************************************/
/****************************************************************************************
* Public Functions
****************************************************************************************/
#endif /* __ARCH_ARM_SRC_SAM34_HARDWARE_SAM_MATRIX_H */

View File

@ -0,0 +1,593 @@
/****************************************************************************
* arch/arm/src/sam34/sam4s_nand.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/mtd/nand_config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/mtd/nand.h>
#include <nuttx/mtd/nand_raw.h>
#include <nuttx/mtd/nand_model.h>
#include <nuttx/irq.h>
#include <arch/board/board.h>
#include "hardware/sam4s_pinmap.h"
#include "arm_arch.h"
#include "sam4s_nand.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nand flash chip status codes */
#define STATUS_ERROR (1 << 0)
#define STATUS_READY (1 << 6)
/* Number of tries for erasing or writing block */
#define NAND_ERASE_NRETRIES 2
#define NAND_WRITE_NRETRIES 2
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Low-level HSMC Helpers */
#ifdef CONFIG_SAM34_NAND_DUMP
# define nand_dump(m,b,s) lib_dumpbuffer(m,b,s)
#else
# define nand_dump(m,b,s)
#endif
/* Raw Data Transfer Helpers */
static int nand_write(struct sam_nandcs_s *priv, uint32_t rowaddr,
uint32_t coladdr, uint8_t *buffer, uint16_t buflen,
uint16_t offset);
static int nand_read(struct sam_nandcs_s *priv, uint32_t rowaddr,
uint32_t coladdr, uint8_t *buffer, uint16_t buflen,
uint16_t offset);
/* MTD driver methods */
static int nand_eraseblock(struct nand_raw_s *raw, off_t block);
static int nand_rawread(struct nand_raw_s *raw, off_t block,
unsigned int page, void *data, void *spare);
static int nand_rawwrite(struct nand_raw_s *raw, off_t block,
unsigned int page, const void *data, const void *spare);
/* Initialization */
static void nand_reset(struct sam_nandcs_s *priv);
/****************************************************************************
* Private Data
****************************************************************************/
/* These pre-allocated structures hold the state of the MTD driver for NAND
* on CS0..3 as configured.
*/
#ifdef CONFIG_SAM34_NCS0_NAND
static struct sam_nandcs_s g_cs0nand;
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
static void nand_reset(struct sam_nandcs_s *priv)
{
WRITE_COMMAND8(&priv->raw, COMMAND_RESET);
/* The device will be busy for a maximum of 1ms. */
up_mdelay(1);
}
/****************************************************************************
* Name: nand_wait_ready
*
* Description:
* Waiting for the completion of a page program, erase and random read
* completion.
*
* Input Parameters:
* priv Pointer to a sam_nandcs_s instance.
*
* Returned Value:
* None
*
****************************************************************************/
static int nand_wait_ready(struct sam_nandcs_s *priv)
{
uint32_t timeout;
uint8_t status;
up_udelay(10);
/* The ready/busy (R/nB) signal of the NAND Flash */
while (!sam_gpioread(priv->rb));
WRITE_COMMAND8(&priv->raw, COMMAND_STATUS);
/* Issue command */
timeout = 0;
while (timeout < MAX_READ_STATUS_COUNT)
{
/* Read status byte */
status = READ_DATA8(&priv->raw);
/* Check status. If status bit 6 = 1 device is ready */
if ((status & STATUS_READY) == STATUS_READY)
{
/* If status bit 0 = 0 the last operation was successful */
if ((status & STATUS_ERROR) == 0)
{
return OK;
}
else
{
return -EIO;
}
}
timeout++;
}
return -ETIMEDOUT;
}
/****************************************************************************
* Name: nand_eraseblock
*
* Description:
* Erases the specified block of the device.
*
* Input Parameters:
* raw - Lower-half, raw NAND FLASH interface
* block - Number of the physical block to erase.
*
* Returned Value:
* OK is returned in success; a negated errno value is returned on failure.
*
****************************************************************************/
static inline int nand_tryeraseblock(struct sam_nandcs_s *priv, off_t block)
{
uint32_t rowaddr;
int ret = OK;
/* Calculate address used for erase */
rowaddr = block * nandmodel_pagesperblock(&priv->raw.model);
WRITE_COMMAND8(&priv->raw, COMMAND_ERASE_1);
WRITE_ADDRESS8(&priv->raw, rowaddr); /* 3rd cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 8); /* 4th cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 16); /* 5st cycle row addr */
WRITE_COMMAND8(&priv->raw, COMMAND_ERASE_2);
ret = nand_wait_ready(priv);
if (ret < 0)
{
ferr("ERROR: Block %d Could not erase: %d\n", block, ret);
}
return ret;
}
static int nand_eraseblock(struct nand_raw_s *raw, off_t block)
{
struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
int retries = NAND_ERASE_NRETRIES;
int ret = OK;
DEBUGASSERT(priv);
finfo("block=%d\n", (int)block);
if (ret < 0)
{
return ret;
}
/* Try up to NAND_ERASE_NRETRIES times to erase the FLASH */
while (retries > 0)
{
ret = nand_tryeraseblock(priv, block);
if (ret == OK)
{
return OK;
}
retries--;
}
ferr("ERROR: Block %d Failed to erase after %d tries\n",
(int)block, NAND_ERASE_NRETRIES);
return -EAGAIN;
}
/****************************************************************************
* Name: nand_write
*
* Description:
* Write data to NAND using the NAND data address.
*
* Input Parameters:
* priv - Lower-half, private NAND FLASH device state
* buffer - Buffer that provides the data for the write
* offset - Data offset in bytes
*
* Returned Value:
* OK on success; a negated errno value on failure.
*
****************************************************************************/
static int nand_write(struct sam_nandcs_s *priv, uint32_t rowaddr,
uint32_t coladdr, uint8_t *buffer,
uint16_t buflen, uint16_t offset)
{
uintptr_t dest;
int ret = OK;
nand_dump("NAND Write", buffer, buflen);
dest = priv->raw.dataaddr + offset;
/* Apply the offset to the destination address */
WRITE_COMMAND8(&priv->raw, COMMAND_WRITE_1);
WRITE_ADDRESS8(&priv->raw, coladdr); /* 1st cycle column addr */
WRITE_ADDRESS8(&priv->raw, coladdr >> 8); /* 2nt cycle column addr */
WRITE_ADDRESS8(&priv->raw, rowaddr); /* 3rd cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 8); /* 4th cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 16); /* 5st cycle row addr */
volatile uint8_t *dest8 = (volatile uint8_t *)dest;
for (; buflen > 0; buflen--)
{
*dest8 = *buffer++;
}
WRITE_COMMAND8(&priv->raw, COMMAND_WRITE_2);
ret = nand_wait_ready(priv);
return ret;
}
static int nand_read(struct sam_nandcs_s *priv, uint32_t rowaddr,
uint32_t coladdr, uint8_t *buffer,
uint16_t buflen, uint16_t offset)
{
volatile uint8_t *src8 = (volatile uint8_t *)priv->raw.dataaddr + offset;
uint8_t *dest8 = (uint8_t *)buffer;
int remaining;
int ret = OK;
WRITE_COMMAND8(&priv->raw, COMMAND_READ_1);
WRITE_ADDRESS8(&priv->raw, coladdr); /* 1st cycle column addr */
WRITE_ADDRESS8(&priv->raw, coladdr >> 8); /* 2nt cycle column addr */
WRITE_ADDRESS8(&priv->raw, rowaddr); /* 3rd cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 8); /* 4th cycle row addr */
WRITE_ADDRESS8(&priv->raw, rowaddr >> 16); /* 5st cycle row addr */
WRITE_COMMAND8(&priv->raw, COMMAND_READ_2);
up_udelay(10);
while (!sam_gpioread(priv->rb));
remaining = buflen;
for (; remaining > 0; remaining--)
{
*dest8++ = *src8;
}
nand_dump("NAND Read", buffer, buflen);
return ret;
}
/****************************************************************************
* Name: nand_rawread
*
* Description:
* Reads the data and/or the spare areas of a page of a NAND FLASH into the
* provided buffers. This is a raw read of the flash contents.
*
* Input Parameters:
* raw - Lower-half, raw NAND FLASH interface
* block - Number of the block where the page to read resides.
* page - Number of the page to read inside the given block.
* data - Buffer where the data area will be stored.
* spare - Buffer where the spare area will be stored.
*
* Returned Value:
* OK is returned in success; a negated errno value is returned on failure.
*
****************************************************************************/
static int nand_rawread(struct nand_raw_s *raw, off_t block,
unsigned int page, void *data, void *spare)
{
struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
uint16_t pagesize;
uint16_t sparesize;
off_t rowaddr;
off_t coladdr;
int ret = OK;
DEBUGASSERT(priv && (data || spare));
/* Get page and spare sizes */
pagesize = nandmodel_getpagesize(&priv->raw.model);
sparesize = nandmodel_getsparesize(&priv->raw.model);
/* Calculate actual address of the page */
rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page;
coladdr = data ? 0 : pagesize;
fwarn("block=%d page=%d rowaddr=%d coladdr %d data=%p spare=%p\n",
(int)block, page, rowaddr, coladdr , data, spare);
coladdr = (coladdr >> 8) & 0x4 ? coladdr & 0x83f : coladdr;
if (data)
{
ret = nand_read(priv, rowaddr, coladdr, (uint8_t *)data, pagesize, 0);
if (ret < 0)
{
ferr("ERROR: nand_nfcsram_read for data region failed: %d\n", ret);
return ret;
}
}
if (spare)
{
uint16_t offset = data ? pagesize : 0;
ret = nand_read(priv, rowaddr, coladdr, (uint8_t *)spare, sparesize,
offset);
if (ret < 0)
{
ferr("ERROR: nand_nfcsram_read for spare region failed: %d\n",
ret);
return ret;
}
}
return ret;
}
/****************************************************************************
* Name: nand_rawwrite
*
* Description:
* Writes the data and/or the spare area of a page on a NAND FLASH chip.
* This is a raw write of the flash contents.
*
* Input Parameters:
* raw - Lower-half, raw NAND FLASH interface
* block - Number of the block where the page to write resides.
* page - Number of the page to write inside the given block.
* data - Buffer containing the data to be writing
* spare - Buffer containing the spare data to be written.
*
* Returned Value:
* OK is returned in success; a negated errno value is returned on failure.
*
****************************************************************************/
static int nand_rawwrite(struct nand_raw_s *raw, off_t block,
unsigned int page, const void *data,
const void *spare)
{
struct sam_nandcs_s *priv = (struct sam_nandcs_s *)raw;
uint16_t pagesize;
uint16_t sparesize;
off_t rowaddr;
int ret = OK;
DEBUGASSERT(raw);
finfo("block=%d page=%d data=%p spare=%p\n",
(int)block, page, data, spare);
/* Get page and spare sizes */
pagesize = nandmodel_getpagesize(&priv->raw.model);
sparesize = nandmodel_getsparesize(&priv->raw.model);
rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page;
if (data)
{
ret = nand_write(priv, rowaddr, 0, (uint8_t *)data, pagesize, 0);
if (ret < 0)
{
ferr("ERROR: Failed writing data area: %d\n", ret);
}
}
if (spare)
{
ret = nand_write(priv, rowaddr, 0, (uint8_t *)spare, sparesize,
pagesize);
if (ret < 0)
{
ferr("ERROR: Failed writing data spare: %d\n", ret);
}
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_nand_initialize
*
* Description:
* Create and initialize an raw NAND device instance. This driver
* implements the RAW NAND interface: No software ECC or sparing is
* performed here. Those necessary NAND features are provided by common,
* higher level NAND MTD layers found in drivers/mtd.
*
* Input Parameters:
* cs - Chip select number (in the event that multiple NAND devices
* are connected on-board).
*
* Returned Value:
* On success a non-NULL pointer to an MTD device structure is returned;
* NULL is returned on a failure.
*
****************************************************************************/
struct mtd_dev_s *sam_nand_initialize(int cs)
{
struct sam_nandcs_s *priv;
struct mtd_dev_s *mtd;
uintptr_t cmdaddr;
uintptr_t addraddr;
uintptr_t dataaddr;
uint8_t ecctype;
int ret;
finfo("CS%d\n", cs);
if (SAM_SMCCS_BASE(cs) == SAM_SMC_CS0_BASE)
{
/* Refer to the pre-allocated NAND device structure */
priv = &g_cs0nand;
/* Set up the NAND addresses. These must be provided in the board.h
* header file.
*/
cmdaddr = BOARD_NCS0_NAND_CMDADDR;
addraddr = BOARD_NCS0_NAND_ADDRADDR;
dataaddr = BOARD_NCS0_NAND_DATAADDR;
/* Pass on the configured ECC type */
ecctype = SAM34_NCS0_ECCTYPE;
}
else
{
ferr("ERROR: CS%d unsupported or invalid\n", cs);
return NULL;
}
/* Initialize the device structure */
memset(priv, 0, sizeof(struct sam_nandcs_s));
priv->raw.cmdaddr = cmdaddr;
priv->raw.addraddr = addraddr;
priv->raw.dataaddr = dataaddr;
priv->raw.ecctype = ecctype;
priv->raw.eraseblock = nand_eraseblock;
priv->raw.rawread = nand_rawread;
priv->raw.rawwrite = nand_rawwrite;
priv->cs = cs;
priv->rb = GPIO_SMC_RB;
/* Initialize the NAND hardware for this CS */
/**
* Note: The initialization is shown for the reference purpose only, and
* for other MCUs, refer to the Package and Pinout chapter of the
* respective data sheet.
*
* The I/O pin initialization for the 8-bit NAND is connected to the NCS0:
*
* To initialize the 8-bit D0-D7 data bus, configure the Port C, PC0 to
* PC7 in Peripheral-A mode
*
* To initialize the NANDOE,configure the Port C,PC9 in Peripheral-A mode
*
* To initialize the NANDWE,configure the Port C,PC10 in Peripheral-A mode
*
* To initialize the NANDCLE,configure the Port C,PC17 in Peripheral-A mode
*
* To initialize the NANDALE,configure the Port C,PC16 in Peripheral-A mode
*
* To initialize the R/nB, configure any PIO as an input pin with pull-up
* enabled
*
* To initialize the nCE, configure any PIO as an output pin (refer to Tips
* and Tricks for the supported nCE connection types)
**/
ret = board_nandflash_config(cs);
if (ret < 0)
{
ferr("ERROR: board_nandflash_config failed for CS%d: %d\n",
cs, ret);
return NULL;
}
/* Reset the NAND FLASH part */
nand_reset(priv);
/* Probe the NAND part. On success, an MTD interface that wraps
* our raw NAND interface is returned.
**/
mtd = nand_initialize(&priv->raw);
if (!mtd)
{
ferr("ERROR: CS%d nand_initialize failed %d\n", cs);
return NULL;
}
/* Return the MTD wrapper interface as the MTD device */
return mtd;
}

View File

@ -0,0 +1,179 @@
/****************************************************************************
* arch/arm/src/sam34/sam4s_nand.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_SAM4S_SAM_NAND_H
#define __ARCH_ARM_SRC_SAM4S_SAM_NAND_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/mtd/nand_config.h>
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <nuttx/mtd/nand_raw.h>
#include <nuttx/semaphore.h>
#include "arm_arch.h"
#include "chip.h"
#include "sam_gpio.h"
#include "hardware/sam_smc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Only NCS0 can support NAND. The rest is a fantasy */
#if defined(CONFIG_SAM34_EXTNAND)
# define CONFIG_SAM34_NCS0_NAND 1
#else
# undef CONFIG_SAM34_NCS0_NAND
#endif
/* On-Die ECC, Requires Micron Flash to support on-die */
#define SAM34_NCS0_ECCTYPE NANDECC_NONE
#if defined(CONFIG_SAM34_NCS0_NAND)
# if defined(CONFIG_SAM34_NCS0_ECCNONE) ||\
defined(CONFIG_MTD_NAND_EMBEDDEDECC)
# define SAM34_NCS0_ECCTYPE NANDECC_NONE
# elif defined(CONFIG_MTD_NAND_SWECC)
# define SAM34_NCS0_ECCTYPE NANDECC_SWECC
# endif
#endif /* CONFIG_SAM34_NCS0_NAND */
/* Count the number of banks that configured for NAND with PMECC support
* enabled.
*/
#ifdef CONFIG_SAM34_NCS0_NAND
# define CONFIG_SAM34_HAVE_NAND 1
# define NAND_HAVE_NCS0 1
#else
# define NAND_HAVE_NCS0 0
#endif
#define MAX_READ_STATUS_COUNT 100000 /* Read status timeout */
/****************************************************************************
* Public Types
****************************************************************************/
/* This type represents the state of a raw NAND MTD device on a single chip
* select. The struct nand_raw_s must appear at the beginning of the
* definition so that you can freely cast between pointers to struct
* nand_raw_s and struct sam_nandcs_s.
*
* NOTE: Currently, only SAM4S CS0 can support NAND. The logic here would
* support NAND on any CS, but that capability is not needed.
*/
struct sam_nandcs_s
{
struct nand_raw_s raw; /* Externally visible part of the driver */
/* Static configuration */
uint8_t cs; /* Chip select number (0..3) */
gpio_pinset_t rb; /* NAND Ready/Busy detect GPIO pin */
#endif
};
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/* NAND global state */
EXTERN struct sam_nand_s g_nand;
/****************************************************************************
* Name: sam_nand_initialize
*
* Description:
* Create and initialize an raw NAND device instance. This driver
* implements the RAW NAND interface: No software ECC or sparing is
* performed here. Those necessary NAND features are provided by common,
* higher level NAND MTD layers found in drivers/mtd.
*
* Input Parameters:
* cs - Chip select number (in the event that multiple NAND devices
* are connected on-board).
*
* Returned Value:
* On success a non-NULL pointer to an MTD device structure is returned;
* NULL is returned on a failure.
*
****************************************************************************/
struct mtd_dev_s;
struct mtd_dev_s *sam_nand_initialize(int cs);
/****************************************************************************
* Name: board_nandflash_config
*
* Description:
* If CONFIG_SAM34_BOOT_CS3FLASH is defined, then NAND FLASH support is
* enabled. This function provides the board-specific implementation of
* the logic to reprogram the SMC to support NAND FLASH on the specified
* CS. As a minimum, this board-specific initialization should do the
* following:
*
* 1. Enable clocking to the HSMC
* 2. Configure timing for the HSMC CS
* 3. Configure NAND PIO pins
*
* Input Parameters:
* cs - Chip select number (in the event that multiple NAND devices
* are connected on-board).
*
* Returned Value:
* OK if the HSMC was successfully configured for this CS. A negated
* errno value is returned on a failure. This would fail with -ENODEV,
* for example, if the board does not support NAND FLASH on the requested
* CS.
*
****************************************************************************/
int board_nandflash_config(int cs);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */

View File

@ -20,4 +20,43 @@ config SAM4S_XPLAINED_PRO_CPULOAD_TIMER_DEVPATH
default "/dev/tc0"
depends on TIMER && SCHED_CPULOAD && SCHED_CPULOAD_EXTCLK
config SAM34_NAND_BLOCKMOUNT
bool "NAND FLASH auto-mount"
default n
depends on NSH_ARCHINIT && SAM34_EXTNAND
---help---
Automatically initialize the NAND FLASH driver when NSH starts.
choice
prompt "NAND FLASH configuration"
default SAM34_NAND_NXFFS
depends on SAM34_NAND_BLOCKMOUNT
config SAM34_NAND_FTL
bool "Create NAND FLASH block driver"
depends on MTD && MTD_NAND
---help---
Create the MTD driver for the NAND and "wrap" the NAND as a standard
block driver that could then, for example, be mounted using FAT or
any other file system. Any file system may be used, but there will
be no wear-leveling.
NOTE: This options is not currently recommended. There is not now
NuttX file system that can handle the NAND back blocks or performs
wear-leveling other than NXFFS and NXFFS does not use a block driver
but, rather, operates directly upon the NAND MTD device.
config SAM34_NAND_NXFFS
bool "Create NAND FLASH NXFFS file system"
depends on MTD && MTD_NAND && FS_NXFFS && NXFFS_NAND
---help---
Create the MTD driver for the NAND and mount the NAND device as
a wear-leveling, NuttX FLASH file system (NXFFS). The downside of
NXFFS is that it can be very slow.
NOTE: NXFFS is recommended because (1) it can handle the NAND back
blocks and (1) performs wear-leveling.
endchoice # NAND FLASH configuration
endif

View File

@ -0,0 +1,101 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_RAMFUNCS is not set
# CONFIG_MTD_NAND_BLOCKCHECK is not set
# CONFIG_MTD_NAND_SWECC is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="sam4s-xplained-pro"
CONFIG_ARCH_BOARD_SAM4S_XPLAINED_PRO=y
CONFIG_ARCH_CHIP="sam34"
CONFIG_ARCH_CHIP_ATSAM4SD32C=y
CONFIG_ARCH_CHIP_SAM34=y
CONFIG_ARCH_CHIP_SAM4S=y
CONFIG_ARCH_INTERRUPTSTACK=1024
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV7M_USEBASEPRI=y
CONFIG_ARM_MPU=y
CONFIG_BOARDCTL_USBDEVCTRL=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=11401
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_BULKIN_REQLEN=250
CONFIG_CDCACM_RXBUFSIZE=1024
CONFIG_CDCACM_TXBUFSIZE=1024
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_ZERO=y
CONFIG_FS_FAT=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INTELHEX_BINARY=y
CONFIG_JULIAN_TIME=y
CONFIG_LIBC_STRERROR=y
CONFIG_LIBC_STRERROR_SHORT=y
CONFIG_MAX_TASKS=16
CONFIG_MMCSD_SDIO=y
CONFIG_MTD=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_EMBEDDEDECC=y
CONFIG_MTD_NAND_MAXNUMBLOCKS=2048
CONFIG_MTD_NAND_MAXNUMPAGESPERBLOCK=64
CONFIG_MTD_NAND_MAXPAGEDATASIZE=2048
CONFIG_MTD_NAND_MAXPAGESPARESIZE=64
CONFIG_MTD_NAND_MAXSPAREECCBYTES=64
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFCONFIG=y
CONFIG_NSH_DISABLE_LOSETUP=y
CONFIG_NSH_FILEIOSIZE=2048
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PIPES=y
CONFIG_PREALLOC_MQ_MSGS=8
CONFIG_PREALLOC_TIMERS=4
CONFIG_PTHREAD_STACK_DEFAULT=4096
CONFIG_PTHREAD_STACK_MIN=512
CONFIG_RAM_SIZE=163840
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=50
CONFIG_RTC=y
CONFIG_RTC_ALARM=y
CONFIG_RTC_FREQUENCY=32768
CONFIG_RTC_HIRES=y
CONFIG_SAM34_EXTNAND=y
CONFIG_SAM34_EXTNANDSIZE=268435456
CONFIG_SAM34_GPIOC_IRQ=y
CONFIG_SAM34_GPIO_IRQ=y
CONFIG_SAM34_HSMCI=y
CONFIG_SAM34_NAND_BLOCKMOUNT=y
CONFIG_SAM34_PDCA=y
CONFIG_SAM34_RTC=y
CONFIG_SAM34_RTT=y
CONFIG_SAM34_SMC=y
CONFIG_SAM34_TC0=y
CONFIG_SAM34_TC1=y
CONFIG_SAM34_UART1=y
CONFIG_SAM34_UDP=y
CONFIG_SAM34_USART1=y
CONFIG_SAM34_WDT=y
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_SDIO_BLOCKSETUP=y
CONFIG_STDIO_BUFFER_SIZE=256
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=15
CONFIG_UART1_SERIAL_CONSOLE=y
CONFIG_USBDEV=y
CONFIG_USERMAIN_STACKSIZE=4096
CONFIG_USER_ENTRYPOINT="nsh_main"
CONFIG_WATCHDOG=y
CONFIG_WDT_ENABLED_ON_RESET=y
CONFIG_WDT_THREAD_STACKSIZE=512

View File

@ -15,12 +15,11 @@ CONFIG_ARCH_CHIP_SAM34=y
CONFIG_ARCH_CHIP_SAM4S=y
CONFIG_ARCH_INTERRUPTSTACK=1024
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT=y
CONFIG_ARMV7M_USEBASEPRI=y
CONFIG_ARM_MPU=y
CONFIG_BOARDCTL_USBDEVCTRL=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=9186
CONFIG_BOARD_LOOPSPERMSEC=11401
CONFIG_BUILTIN=y
CONFIG_CDCACM=y
CONFIG_CDCACM_BULKIN_REQLEN=250
@ -29,7 +28,6 @@ CONFIG_CDCACM_TXBUFSIZE=1024
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_ZERO=y
CONFIG_DISABLE_ENVIRON=y
CONFIG_EXAMPLES_CPUHOG=y
CONFIG_EXAMPLES_SERIALBLASTER=y
CONFIG_EXAMPLES_SERIALRX=y
@ -81,15 +79,11 @@ CONFIG_SAM34_UART1=y
CONFIG_SAM34_UDP=y
CONFIG_SAM34_USART1=y
CONFIG_SAM34_WDT=y
CONFIG_SCHED_CPULOAD=y
CONFIG_SCHED_CPULOAD_EXTCLK=y
CONFIG_SCHED_CPULOAD_TICKSPERSEC=222
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_SDCLONE_DISABLE=y
CONFIG_SDIO_BLOCKSETUP=y
CONFIG_STDIO_BUFFER_SIZE=256
CONFIG_SYSTEMTICK_EXTCLK=y
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=15
CONFIG_UART1_SERIAL_CONSOLE=y

View File

@ -261,4 +261,20 @@
#define BUTTON_SW0_BIT (1 << BUTTON_SW0)
/* NAND *********************************************************************/
#define GPIO_SMC_RB (GPIO_INPUT | GPIO_SMC_NWAIT)
/* Address for transferring command bytes to the nandflash, CLE A22 */
#define BOARD_NCS0_NAND_CMDADDR 0x60400000
/* Address for transferring address bytes to the nandflash, ALE A21 */
#define BOARD_NCS0_NAND_ADDRADDR 0x60200000
/* Address for transferring data bytes to the nandflash. */
#define BOARD_NCS0_NAND_DATAADDR 0x60000000
#endif /* __BOARDS_ARM_SAM34_SAM4S_XPLAINED_PRO_INCLUDE_BOARD_H */

View File

@ -37,10 +37,20 @@ include $(TOPDIR)/Make.defs
CSRCS = sam_boot.c
ifeq ($(CONFIG_MMCSD_SPI),y)
CSRCS += sam_spi.c
endif
ifeq ($(CONFIG_LIB_BOARDCTL),y)
CSRCS += sam_appinit.c
endif
ifeq ($(CONFIG_SAM34_EXTNAND),y)
ifeq ($(CONFIG_MTD_NAND),y)
CSRCS += sam_nandflash.c
endif
endif
ifeq ($(CONFIG_SAM34_HSMCI),y)
CSRCS += sam_hsmci.c
endif

View File

@ -60,8 +60,16 @@
#define HAVE_HSMCI 1
#define HAVE_PROC 1
#define HAVE_USBDEV 1
#if defined(CONFIG_MTD_NAND) && defined(CONFIG_SAM34_EXTNAND)
#define HAVE_NAND 1
#endif
#undef HAVE_USBMONITOR
#if defined(CONFIG_MMCSD_SPI)
# define HAVE_MMCSD_SPI 1
#endif
/* HSMCI */
/* Can't support MMC/SD if the card interface is not enabled */
@ -93,6 +101,16 @@
# undef HAVE_HSMCI
#endif
/* MMC/SD minor numbers */
#ifndef CONFIG_NSH_MMCSDMINOR
# define CONFIG_NSH_MMCSDMINOR 0
#endif
#ifndef CONFIG_NSH_MMCSDSLOTNO
# define CONFIG_NSH_MMCSDSLOTNO 0
#endif
/* USB Device */
/* CONFIG_SAM34_UDP and CONFIG_USBDEV must be defined, or there is no USB
@ -173,11 +191,24 @@
* Public data
****************************************************************************/
#ifndef __ASSEMBLY__
/* SPI0 */
/****************************************************************************
* Public Functions
****************************************************************************/
#ifdef HAVE_MMCSD_SPI
#define GPIO_SPISD_NPCS0 (GPIO_OUTPUT | GPIO_CFG_PULLUP | GPIO_OUTPUT_SET | \
GPIO_PORT_PIOA | GPIO_PIN11)
#define SPISD_PORT SPI0_CS0
#define GPIO_SPI_CD (GPIO_INPUT | GPIO_CFG_PULLUP | GPIO_PORT_PIOC | GPIO_PIN19)
#define SD_SPI_IRQ SAM_IRQ_PC19
#endif /* HAVE_MMCSD_SPI */
/* NAND */
#ifdef HAVE_NAND
# define NAND_MINOR 0
# define SAM_SMC_CS0 0 /* GPIO_SMC_NCS0 connect SAM_SMC_CS0_BASE */
int sam_nand_automount(int minor);
#endif /* HAVE_NAND */
/****************************************************************************
* Name: sam_hsmci_initialize
@ -193,6 +224,8 @@ int sam_hsmci_initialize(void);
# define sam_hsmci_initialize()
#endif
int sam_sdinitialize(int port, int minor);
/****************************************************************************
* Name: sam_cardinserted
*
@ -235,5 +268,4 @@ bool sam_writeprotected(int slotno);
int sam_watchdog_initialize(void);
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_ARM_SAM34_SAM4S_XPLAINED_SRC_SAM4S_XPLAINED_H */

View File

@ -114,6 +114,17 @@ int board_app_initialize(uintptr_t arg)
}
#endif
#ifdef HAVE_NAND
ret = sam_nand_automount(SAM_SMC_CS0);
if (ret < 0)
{
syslog(LOG_ERR,
"ERROR: Failed to initialize the NAND: %d (%d)\n",
ret, errno);
return ret;
}
#endif
#ifdef HAVE_HSMCI
/* Initialize the HSMCI driver */
@ -157,6 +168,18 @@ int board_app_initialize(uintptr_t arg)
}
#endif
/* SPI */
#ifdef HAVE_MMCSD_SPI
ret = sam_sdinitialize(0, 0);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: Failed to initialize MMC/SD slot: %d\n",
ret);
return ret;
}
#endif
#ifdef HAVE_USBMONITOR
/* Start the USB Monitor */

View File

@ -0,0 +1,245 @@
/****************************************************************************
* boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/mount.h>
#include <stdbool.h>
#include <stdint.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/mtd/mtd.h>
#include <nuttx/fs/nxffs.h>
#include <arch/board/board.h>
#include "arm_arch.h"
#include "sam_periphclks.h"
#include "sam4s_nand.h"
#include "hardware/sam_smc.h"
#include "hardware/sam4s_pinmap.h"
#include "hardware/sam_matrix.h"
#include "sam4s-xplained-pro.h"
#ifdef HAVE_NAND
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
static const gpio_pinset_t g_nandpins[] =
{
GPIO_SMC_NCS0, GPIO_SMC_NANDALE, GPIO_SMC_NANDCLE,
GPIO_SMC_NANDOE, GPIO_SMC_NANDWE, GPIO_SMC_RB,
GPIO_SMC_D0, GPIO_SMC_D1, GPIO_SMC_D2, GPIO_SMC_D3,
GPIO_SMC_D4, GPIO_SMC_D5, GPIO_SMC_D6, GPIO_SMC_D7
};
#define NAND_NPINS (sizeof(g_nandpins) / sizeof(gpio_pinset_t))
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_nandflash_config
*
* Description:
* If CONFIG_SAM34_EXTNAND is defined, then NAND FLASH support is
* enabled. This function provides the board-specific implementation of
* the logic to reprogram the SMC to support NAND FLASH on the specified
* CS.
*
* Input Parameters:
* cs - Chip select number (in the event that multiple NAND devices
* are connected on-board).
*
* Returned Value:
* OK if the HSMC was successfully configured for this CS. A negated
* errno value is returned on a failure. This would fail with -ENODEV,
* for example, if the board does not support NAND FLASH on the requested
* CS.
*
****************************************************************************/
int board_nandflash_config(int cs)
{
/* The Embest and Ronetix CM boards and one Hynix NAND HY27UF(08/16)2G2B
* Series NAND (MT29F2G08ABAEAWP).
* This part has a capacity of 256Mx8bit () with spare 8Mx8 bit capacity.
* The device contains 2048 blocks, composed by 64 x 2112 byte pages.
* The effective size is approximately 256MiB.
*
* NAND is available on NCS0.
*/
int i;
/* Configure GPIO pins (leaving SRAM in the disabled state) */
for (i = 0; i < NAND_NPINS; i++)
{
sam_configgpio(g_nandpins[i]);
}
/* SMC NAND Flash Chip Select Configuration Register */
putreg32(MATRIX_CCFG_SMCNFCS_SMC_NFCS(cs), SAM_MATRIX_CCFG_SMCNFCS);
/* below from sam4s-xplained */
sam_smc_enableclk();
/* Configure SMC setup timing */
putreg32(SMCCS_SETUP_NWESETUP(3) | SMCCS_SETUP_NCSWRSETUP(1) |
SMCCS_SETUP_NRDSETUP(2) | SMCCS_SETUP_NCSRDSETUP(1),
SAM_SMCCS_SETUP(cs));
/* Configure the SMC pulse timing */
putreg32(SMCCS_PULSE_NWEPULSE(5) | SMCCS_PULSE_NCSWRPULSE(5) |
SMCCS_PULSE_NRDPULSE(5) | SMCCS_PULSE_NCSRDPULSE(5),
SAM_SMCCS_PULSE(cs));
/* Configure the SMC cycle timing */
/**
* Select 0. Chip Select 0 has been programmed with:
* NRD_HOLD = 4; READ_MODE = 1 (NRD controlled)
* NWE_SETUP = 3; WRITE_MODE = 1 (NWE controlled)
* TDF_CYCLES = 6; TDF_MODE = 1 (optimization enabled).
*/
putreg32(SMCCS_CYCLE_NWECYCLE(12) | SMCCS_CYCLE_NRDCYCLE(11),
SAM_SMCCS_CYCLE(cs));
/* Configure the SMC mode */
/**
*
* READ_MODE:
* 0: The read operation is controlled by the NCS signal.
* 1: The read operation is controlled by the NRD signal.
*
**/
putreg32(SMCCS_MODE_TDFCYCLES(6) | SMCCS_MODE_TDFMODE |
SMCCS_MODE_WRITEMODE | SMCCS_MODE_READMODE,
SAM_SMCCS_MODE(cs));
/* Configure NAND PIO pins
*
* NAND Interface NAND DESC
*
* NCS0 CE - Dedicated pin; no configuration needed
* NANDCLE CLE - Dedicated pin; no configuration needed
* NANDALE ALE - Dedicated pin; no configuration needed
* NANDOE RE - Dedicated pin; no configuration needed
* NANDWE WE - Dedicated pin; no configuration needed
* NAND_RB RB - PC13
* IO_D0-7 IO0-7 - Dedicated pins; no configuration needed
*/
sam_configgpio(GPIO_SMC_NANDALE);
sam_configgpio(GPIO_SMC_NANDCLE);
return OK;
}
/****************************************************************************
* Name: sam_nand_automount
*
* Description:
* Initialize and configure the NAND on CS3
*
****************************************************************************/
int sam_nand_automount(int minor)
{
FAR struct mtd_dev_s *mtd;
static bool initialized = false;
/* Have we already initialized? */
if (!initialized)
{
/* Create and initialize an NAND MATD device */
mtd = sam_nand_initialize(SAM_SMC_CS0);
if (!mtd)
{
ferr("ERROR: Failed to create the NAND driver on CS%d\n",
SAM_SMC_CS0);
return -ENODEV;
}
#if defined(CONFIG_SAM34_NAND_FTL)
/* Use the FTL layer to wrap the MTD driver as a block driver */
int ret = OK;
ret = ftl_initialize(NAND_MINOR, mtd);
if (ret < 0)
{
ferr("ERROR: Failed to initialize the FTL layer: %d\n", ret);
return ret;
}
#elif defined(CONFIG_SAM34_NAND_NXFFS)
/* Initialize to provide NXFFS on the MTD interface */
int ret = OK;
ret = nxffs_initialize(mtd);
if (ret < 0)
{
ferr("ERROR: NXFFS initialization failed: %d\n", ret);
return ret;
}
/* Mount the file system at /mnt/nand */
ret = mount(NULL, "/mnt/nand", "nxffs", 0, NULL);
if (ret < 0)
{
ferr("ERROR: Failed to mount the NXFFS volume: %d\n", errno);
return ret;
}
#endif
/* Now we are initialized */
initialized = true;
}
return OK;
}
#endif /* HAVE_NAND */

View File

@ -0,0 +1,195 @@
/****************************************************************************
* boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/spi/spi.h>
#include <arch/board/board.h>
#include "arm_arch.h"
#include "chip.h"
#include "sam_gpio.h"
#include "sam_spi.h"
#include "sam4s-xplained-pro.h"
#if defined(CONFIG_SAM34_SPI0)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: sam_spidev_initialize
*
* Description:
* Called to configure SPI chip select PIO pins for the SAM4S-Xplained-Pro
* board.
*
****************************************************************************/
void weak_function sam_spidev_initialize(void)
{
#ifdef CONFIG_SAM34_SPI0
sam_configgpio(GPIO_SPI0_NPCS0);
#endif
}
/****************************************************************************
* Name: sam_spi[0|1]select, sam_spi[0|1]status, and sam_spi[0|1]cmddata
*
* Description:
* These external functions must be provided by board-specific logic.
* They include:
*
* o sam_spi[0|1]select is a functions tomanage the board-specific chip
* selects
* o sam_spi[0|1]status and sam_spi[0|1]cmddata:
* Implementations of the status and cmddata methods of the SPI interface
* defined by struct spi_ops_(see include/nuttx/spi/spi.h).
* All other methods including sam_spibus_initialize()) are provided by
* common SAM3/4 logic.
*
* To use this common SPI logic on your board:
*
* 1. Provide logic in sam_boardinitialize() to configure SPI chip select
* pins.
* 2. Provide sam_spi[0|1]select() and sam_spi[0|1]status() functions in
* your board-specific logic.
* These functions will perform chip selection and status operations
* using PIOs in the way your board is configured.
* 2. If CONFIG_SPI_CMDDATA is defined in the NuttX configuration, provide
* sam_spi[0|1]cmddata() functions in your board-specific logic. This
* function will perform cmd/data selection operations using PIOs in
* the way your board is configured.
* 3. Add a call to sam_spibus_initialize() in your low level application
* initialization logic
* 4. The handle returned by sam_spibus_initialize() may then be used to
* bind the SPI driver to higher level logic (e.g., calling
* mmcsd_spislotinitialize(), for example, will bind the SPI driver to
* the SPI MMC/SD driver).
*
****************************************************************************/
/****************************************************************************
* Name: sam_spi[0|1]select
*
* Description:
* PIO chip select pins may be programmed by the board specific logic in
* one of two different ways. First, the pins may be programmed as SPI
* peripherals. In that case, the pins are completely controlled by the
* SPI driver. This method still needs to be provided, but it may be only
* a stub.
*
* An alternative way to program the PIO chip select pins is as a normal
* PIO output. In that case, the automatic control of the CS pins is
* bypassed and this function must provide control of the chip select.
* NOTE: In this case, the PIO output pin does *not* have to be the
* same as the NPCS pin normal associated with the chip select number.
*
* Input Parameters:
* devid - Identifies the (logical) device
* selected - TRUE:Select the device, FALSE:De-select the device
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_SAM34_SPI0
void sam_spi0select(uint32_t devid, bool selected)
{
#ifdef CONFIG_MMCSD_SPI
/* The AT25 serial FLASH connects using NPCS0 */
if (devid == SPIDEV_MMCSD(0))
{
sam_gpiowrite(GPIO_SPI0_NPCS0, !selected);
}
#endif
}
#endif
/****************************************************************************
* Name: sam_spi[0|1]status
*
* Description:
* Return status information associated with the SPI device.
*
* Input Parameters:
* devid - Identifies the (logical) device
*
* Returned Value:
* Bit-encoded SPI status (see include/nuttx/spi/spi.h.
*
****************************************************************************/
#ifdef CONFIG_SAM34_SPI0
uint8_t sam_spi0status(FAR struct spi_dev_s *dev, uint32_t devid)
{
return SPI_STATUS_PRESENT;
}
#endif
int sam_sdinitialize(int port, int minor)
{
FAR struct spi_dev_s *spi;
int ret;
/* Get the SPI driver instance for the SD chip select */
finfo("Initializing SERCOM SPI%d\n", port);
spi = sam_spibus_initialize(port);
if (!spi)
{
ferr("ERROR: Failed to initialize SPI%d\n", port);
return -ENODEV;
}
finfo("Successfully initialized SPI%d\n", port);
/* Bind the SPI device for the chip select to the slot */
finfo("Binding SPI%d to MMC/SD slot %d\n", port, 0);
ret = mmcsd_spislotinitialize(minor, 0, spi);
if (ret < 0)
{
ferr("ERROR: Failed to bind SPI%d to MMC/SD slot %d: %d\n",
port, 0, ret);
return ret;
}
finfo("Successfully bound SPI%d to MMC/SD slot %d\n",
port, 0);
return OK;
}
#endif /* CONFIG_SAM34_SPI0 */

View File

@ -42,6 +42,7 @@
#include <errno.h>
#include <nuttx/kmalloc.h>
#include <nuttx/signal.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/clock.h>
@ -2645,7 +2646,7 @@ static int mmcsd_widebus(FAR struct mmcsd_state_s *priv)
priv->widebus = true;
SDIO_CLOCK(priv->dev, CLOCK_SD_TRANSFER_4BIT);
usleep(MMCSD_CLK_DELAY);
nxsig_usleep(MMCSD_CLK_DELAY);
return OK;
}
@ -2777,7 +2778,7 @@ static int mmcsd_mmcinitialize(FAR struct mmcsd_state_s *priv)
/* Select high speed MMC clocking (which may depend on the DSR setting) */
SDIO_CLOCK(priv->dev, CLOCK_MMC_TRANSFER);
usleep(MMCSD_CLK_DELAY);
nxsig_usleep(MMCSD_CLK_DELAY);
return OK;
}

View File

@ -66,6 +66,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Success Values returned by the nand_checkblock function */
#define GOODBLOCK 254
@ -82,6 +83,7 @@
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* NAND locking */
static int nand_lock(FAR struct nand_dev_s *nand);
@ -94,7 +96,6 @@ static int nand_checkblock(FAR struct nand_dev_s *nand, off_t block);
static int nand_devscan(FAR struct nand_dev_s *nand);
#else
# define nand_checkblock(n,b) (GOODBLOCK)
# define nand_devscan(n) (0)
#endif
/* Misc. NAND helpers */
@ -282,6 +283,7 @@ static int nand_devscan(FAR struct nand_dev_s *nand)
finfo("Good blocks: %u - %u\n", good, good + ngood);
ngood = 0;
}
#endif
if (ret == BADBLOCK)
{
@ -296,12 +298,12 @@ static int nand_devscan(FAR struct nand_dev_s *nand)
#if defined(CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_FS)
else
{
if (ngood == 0)
{
good = block;
}
if (ngood == 0)
{
good = block;
}
ngood++;
ngood++;
}
#endif
}
@ -381,6 +383,7 @@ static int nand_eraseblock(FAR struct nand_dev_s *nand, off_t block,
int ret;
/* finfo("Block %d\n", block); */
DEBUGASSERT(nand && nand->raw);
#ifdef CONFIG_MTD_NAND_BLOCKCHECK
@ -455,7 +458,7 @@ static int nand_readpage(FAR struct nand_dev_s *nand, off_t block,
{
ferr("ERROR: Block is BAD\n");
return -EAGAIN;
}
}
#endif
#ifdef CONFIG_MTD_NAND_SWECC
@ -787,8 +790,8 @@ static int nand_ioctl(struct mtd_dev_s *dev, int cmd, unsigned long arg)
struct mtd_geometry_s *geo = (struct mtd_geometry_s *)arg;
if (geo)
{
/* Populate the geometry structure with information needed to know
* the capacity and how to access the device. Returns:
/* Populate the geometry structure with information needed to
* know the capacity and how to access the device. Returns:
*
* blocksize Size of one read/write block in bytes
* erasesize Size of one erase block in bytes
@ -880,7 +883,7 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
chipid = nand_chipid(raw);
if (nandmodel_find(g_nandmodels, NAND_NMODELS, chipid,
&raw->model))
{
{
ferr("ERROR: Could not determine NAND model\n");
return NULL;
}
@ -895,7 +898,8 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
/* Construct the NAND model structure */
model->devid = onfi.manufacturer;
model->options = onfi.buswidth ? NANDMODEL_DATAWIDTH16 : NANDMODEL_DATAWIDTH8;
model->options = onfi.buswidth ? NANDMODEL_DATAWIDTH16 :
NANDMODEL_DATAWIDTH8;
model->pagesize = onfi.pagesize;
model->sparesize = onfi.sparesize;
@ -933,7 +937,8 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
/* Disable any internal, embedded ECC function */
onfi_embeddedecc(&onfi, cmdaddr, addraddr, dataaddr, false);
onfi_embeddedecc(&onfi, raw->cmdaddr, raw->addraddr, raw->dataaddr,
true);
}
/* Allocate an NAND MTD device structure */
@ -955,9 +960,13 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw)
nxsem_init(&nand->exclsem, 0, 1);
/* Scan the device for bad blocks */
#if defined(CONFIG_MTD_NAND_BLOCKCHECK) && defined(CONFIG_DEBUG_INFO) && \
defined(CONFIG_DEBUG_FS)
/* Scan the device for bad blocks */
nand_devscan(nand);
#endif
/* Return the implementation-specific state structure as the MTD device */

View File

@ -189,7 +189,7 @@ static int onfi_readstatus(uintptr_t cmdaddr, uintptr_t dataaddr)
****************************************************************************/
#ifdef CONFIG_MTD_NAND_EMBEDDEDECC
bool onfi_have_embeddedecc(FAR struct onfi_pgparam_s *onfi)
bool onfi_have_embeddedecc(FAR const struct onfi_pgparam_s *onfi)
{
/* Check if the Nandflash has an embedded ECC controller. Known memories
* with this feature:
@ -243,8 +243,8 @@ bool onfi_compatible(uintptr_t cmdaddr, uintptr_t addraddr,
parmtab[3] = READ_NAND(dataaddr);
return
(parmtab[0] == 'O' && parmtab[1] == 'N' &&
parmtab[2] == 'F' && parmtab[3] == 'I');
(parmtab[0] == 'O' && parmtab[1] == 'N' &&
parmtab[2] == 'F' && parmtab[3] == 'I');
}
/****************************************************************************
@ -318,7 +318,7 @@ int onfi_read(uintptr_t cmdaddr, uintptr_t addraddr, uintptr_t dataaddr,
{
ferr("ERROR: Failed to read ONFI parameter table\n");
return -EIO;
}
}
/* JEDEC manufacturer ID */
@ -398,6 +398,7 @@ bool onfi_embeddedecc(FAR const struct onfi_pgparam_s *onfi,
if (onfi_have_embeddedecc(onfi))
{
/* Yes... enable or disable it */
/* Perform common setup */
WRITE_NAND_COMMAND(NAND_CMD_SET_FEATURE, cmdaddr);
@ -411,7 +412,6 @@ bool onfi_embeddedecc(FAR const struct onfi_pgparam_s *onfi,
WRITE_NAND(0x00, dataaddr);
WRITE_NAND(0x00, dataaddr);
WRITE_NAND(0x00, dataaddr);
setSmcOpEccType(SMC_ECC_INTERNAL);
}
else
{
@ -499,7 +499,7 @@ bool onfi_ebidetect(uintptr_t cmdaddr, uintptr_t addraddr,
*/
found = true;
}
}
}
return found;