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:
parent
607ff94793
commit
6aba444359
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
593
arch/arm/src/sam34/sam4s_nand.c
Normal file
593
arch/arm/src/sam34/sam4s_nand.c
Normal 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;
|
||||
}
|
179
arch/arm/src/sam34/sam4s_nand.h
Normal file
179
arch/arm/src/sam34/sam4s_nand.h
Normal 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__ */
|
@ -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
|
||||
|
101
boards/arm/sam34/sam4s-xplained-pro/configs/fs/defconfig
Normal file
101
boards/arm/sam34/sam4s-xplained-pro/configs/fs/defconfig
Normal 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
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
245
boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
Normal file
245
boards/arm/sam34/sam4s-xplained-pro/src/sam_nandflash.c
Normal 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 */
|
195
boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
Normal file
195
boards/arm/sam34/sam4s-xplained-pro/src/sam_spi.c
Normal 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 */
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user