diff options
Diffstat (limited to 'nuttx/drivers')
-rw-r--r-- | nuttx/drivers/mtd/Make.defs | 2 | ||||
-rwxr-xr-x | nuttx/drivers/mtd/mtd_nand.c | 42 | ||||
-rw-r--r-- | nuttx/drivers/mtd/mtd_nandmodel.c | 245 | ||||
-rwxr-xr-x | nuttx/drivers/mtd/mtd_rawnand.c | 115 |
4 files changed, 144 insertions, 260 deletions
diff --git a/nuttx/drivers/mtd/Make.defs b/nuttx/drivers/mtd/Make.defs index e5e4a3e6c..1d83cf5f9 100644 --- a/nuttx/drivers/mtd/Make.defs +++ b/nuttx/drivers/mtd/Make.defs @@ -46,7 +46,7 @@ CSRCS += mtd_partition.c endif ifeq ($(CONFIG_MTD_NAND),y) -CSRCS += mtd_nand.c mtd_onfi.c mtd_nandmodel.c mtd_modeltab.c +CSRCS += mtd_nand.c mtd_onfi.c mtd_rawnand.c mtd_nandmodel.c mtd_modeltab.c endif ifeq ($(CONFIG_RAMMTD),y) diff --git a/nuttx/drivers/mtd/mtd_nand.c b/nuttx/drivers/mtd/mtd_nand.c index f94b0bae8..b0bf9826d 100755 --- a/nuttx/drivers/mtd/mtd_nand.c +++ b/nuttx/drivers/mtd/mtd_nand.c @@ -59,6 +59,7 @@ #include <nuttx/mtd/mtd.h> #include <nuttx/mtd/nand.h> #include <nuttx/mtd/onfi.h> +#include <nuttx/mtd/nand_raw.h> #include <nuttx/mtd/nand_scheme.h> #include <nuttx/mtd/nand_model.h> @@ -230,7 +231,7 @@ static int nand_ioctl(struct mtd_dev_s *dev, int cmd, unsigned long arg) * Probe and initialize NAND. * * Input parameters: - * raw - Raw NAND FLASH MTD interface + * raw - Lower-half, raw NAND FLASH interface * cmdaddr - NAND command address base * addraddr - NAND address address base * dataaddr - NAND data address @@ -243,43 +244,53 @@ static int nand_ioctl(struct mtd_dev_s *dev, int cmd, unsigned long arg) * ****************************************************************************/ -FAR struct mtd_dev_s *nand_initialize(FAR struct mtd_dev_s *raw, - uintptr_t cmdaddr, uintptr_t addraddr, - uintptr_t dataaddr, - FAR struct nand_model_s *model) +FAR struct mtd_dev_s *nand_initialize(FAR struct nand_raw_s *raw) { FAR struct nand_dev_s *priv; struct onfi_pgparam_s onfi; - bool compatible; - bool havemodel = false; int ret; fvdbg("cmdaddr=%p addraddr=%p dataaddr=%p\n", - (FAR void *)cmdaddr, (FAR void *)addraddr, (FAR void *)dataaddr); + (FAR void *)raw->cmdaddr, (FAR void *)raw->addraddr, + (FAR void *)raw->dataaddr); /* Check if there is NAND connected on the EBI */ - if (!onfi_ebidetect(cmdaddr, addraddr, dataaddr)) + if (!onfi_ebidetect(raw->cmdaddr, raw->addraddr, raw->dataaddr)) { fdbg("ERROR: No NAND device detected at: %p %p %p\n", - (FAR void *)cmdaddr, (FAR void *)addraddr, (FAR void *)dataaddr); + (FAR void *)raw->cmdaddr, (FAR void *)raw->addraddr, + (FAR void *)raw->dataaddr); return NULL; } /* Read the ONFI page parameters from the NAND device */ - ret = onfi_read(cmdaddr, addraddr, dataaddr, &onfi); + ret = onfi_read(raw->cmdaddr, raw->addraddr, raw->dataaddr, &onfi); if (ret < 0) { - fvdbg("ERROR: Failed to get ONFI page parameters: %d\n", ret); - compatible = false; + uint32_t chipid; + + fvdbg("Failed to get ONFI page parameters: %d\n", ret); + + /* If the ONFI model is not supported, determine the NAND + * model from a lookup of known FLASH parts. + */ + + chipid = nand_chipid(raw); + if (nandmodel_find(g_nandmodels, NAND_NMODELS, chipid, + &raw->model)) + { + fdbg("ERROR: Could not determine NAND model\n"); + return NULL; + } } else { + FAR struct nand_model_s *model = &raw->model; uint64_t size; fvdbg("Found ONFI compliant NAND FLASH\n"); - compatible = true; /* Construct the NAND model structure */ @@ -320,8 +331,6 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct mtd_dev_s *raw, break; } - havemodel = true; - /* Disable any internal, embedded ECC function */ (void)onfi_embeddedecc(&onfi, cmdaddr, addraddr, dataaddr, false); @@ -343,7 +352,6 @@ FAR struct mtd_dev_s *nand_initialize(FAR struct mtd_dev_s *raw, priv->mtd.bwrite = nand_bwrite; priv->mtd.ioctl = nand_ioctl; priv->raw = raw; - priv->model = model; #warning Missing logic diff --git a/nuttx/drivers/mtd/mtd_nandmodel.c b/nuttx/drivers/mtd/mtd_nandmodel.c index 643804fa4..bd7d898c2 100644 --- a/nuttx/drivers/mtd/mtd_nandmodel.c +++ b/nuttx/drivers/mtd/mtd_nandmodel.c @@ -89,8 +89,8 @@ int nandmodel_find(FAR const struct nand_model_s *modeltab, size_t size, bool found = false; int i; - id2 = (uint8_t)(chipid>>8); - id4 = (uint8_t)(chipid>>24); + id2 = (uint8_t)(chipid >> 8); + id4 = (uint8_t)(chipid >> 24); fvdbg("NAND ID is 0x%08x\n", (int)chipid); @@ -206,14 +206,13 @@ int nandmodel_translate(FAR const struct nand_model_s *model, off_t address, if ((address + size) > nandmodel_getdevbytesize(model)) { - fvdbg("nandmodel_translate: out-of-bounds access.\n"); return -ESPIPE; } /* Get Nand info */ - blocksize = nandmodel_getblocksize(model); + blocksize = nandmodel_getbyteblocksize(model); pagesize = nandmodel_getpagesize(model); /* Translate address */ @@ -246,183 +245,6 @@ int nandmodel_translate(FAR const struct nand_model_s *model, off_t address, } /**************************************************************************** - * Name: nandmodel_getscheme - * - * Description: - * Returns the spare area placement scheme used by a particular nandflash - * model. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Spare placement scheme - * - ****************************************************************************/ - -FAR const struct nand_dev_scheme_s * -nandmodel_getscheme(FAR const struct nand_model_s *model) -{ - return model->scheme; -} - -/**************************************************************************** - * Name: nandmodel_getdevid - * - * Description: - * Returns the device ID of a particular NAND FLASH model. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Device ID - * - ****************************************************************************/ - -uint8_t nandmodel_getdevid(FAR const struct nand_model_s *model) -{ - return model->devid; -} - -/**************************************************************************** - * Name: nandmodel_getdevblocksize - * - * Description: - * Returns the number of blocks in the entire device. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Number of blocks in the device - * - ****************************************************************************/ - -off_t nandmodel_getdevblocksize(FAR const struct nand_model_s *model) -{ - return (1024 * model->devsize) / model->blocksize; -} - -/**************************************************************************** - * Name: nandmodel_getdevpagesize - * - * Description: - * Returns the number of pages in the entire device. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Number of pages in the device - * - ****************************************************************************/ - -size_t nandmodel_getdevpagesize(FAR const struct nand_model_s *model) -{ - return (uint32_t)nandmodel_getdevblocksize(model) //* 8 // HACK - * nandmodel_getblocksize(model); -} - -/**************************************************************************** - * Name: nandmodel_getdevbytesize - * - * Description: - * Returns the size of the whole device in bytes (this does not include - * the size of the spare zones). - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Size of the device in bytes - * - ****************************************************************************/ - -uint64_t nandmodel_getdevbytesize(FAR const struct nand_model_s *model) -{ - return ((uint64_t)model->devsize) << 20; -} - -/**************************************************************************** - * Name: nandmodel_getdevmbsize - * - * Description: - * Returns the size of the whole device in Mega bytes (this does not - * include the size of the spare zones). - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * size of the device in MB. - * - ****************************************************************************/ - -uint32_t nandmodel_getdevmbsize(FAR const struct nand_model_s *model) -{ - return ((uint32_t)model->devsize); -} - -/**************************************************************************** - * Name: nandmodel_getblockpagesize - * - * Description: - * Returns the number of pages in one single block of a device. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Block size in pages - * - ****************************************************************************/ - -unsigned int nandmodel_getblockpagesize(FAR const struct nand_model_s *model) -{ - return model->blocksize * 1024 / model->pagesize; -} - -/**************************************************************************** - * Name: nandmodel_getblockbytesize - * - * Description: - * Returns the size in bytes of one single block of a device. This does not - * take into account the spare zones size. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Block size in bytes - * - ****************************************************************************/ - -unsigned int nandmodel_getblockbytesize(FAR const struct nand_model_s *model) -{ - return model->blocksize * 1024; -} - -/**************************************************************************** - * Name: nandmodel_getpagesize - * - * Description: - * Returns the size of the data area of a page in bytes. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Size of data area in bytes - * - ****************************************************************************/ - -unsigned int nandmodel_getpagesize(FAR const struct nand_model_s *model) -{ - return model->pagesize; -} - -/**************************************************************************** * Name: nandmodel_getsparesize * * Description: @@ -447,64 +269,3 @@ unsigned int nandmodel_getsparesize(FAR const struct nand_model_s *model) return (model->pagesize >> 5); /* Spare size is 16/512 of data size */ } } - -/**************************************************************************** - * Name: nandmodel_getbuswidth - * - * Description: - * Returns the number of bits used by the data bus of a NAND FLASH device. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * data width - * - ****************************************************************************/ - -unsigned int nandmodel_getbuswidth(FAR const struct nand_model_s *model) -{ - return (model->options & NANDMODEL_DATAWIDTH16)? 16 : 8; -} - -/**************************************************************************** - * Name: nandmodel_havesmallblocks - * - * Description: - * Returns true if the given NAND FLASH model uses the "small blocks/pages" - * command set; otherwise returns false. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Returns true if the given NAND FLASH model uses the "small blocks/pages" - * command set; otherwise returns false. - * - ****************************************************************************/ - -bool nandmodel_havesmallblocks(FAR const struct nand_model_s *model) -{ - return (model->pagesize <= 512 )? 1: 0; -} - -/**************************************************************************** - * Name: nandmodel_havecopyback - * - * Description: - * Returns true if the device supports the copy-back operation. Otherwise - * returns false. - * - * Input Parameters: - * model Pointer to a nand_model_s instance. - * - * Returned Values: - * Returns true if the device supports the copy-back operation. Otherwise - * returns false. - * - ****************************************************************************/ - -bool nandmodel_havecopyback(FAR const struct nand_model_s *model) -{ - return ((model->options & NANDMODEL_COPYBACK) != 0); -} diff --git a/nuttx/drivers/mtd/mtd_rawnand.c b/nuttx/drivers/mtd/mtd_rawnand.c new file mode 100755 index 000000000..92e4d82b6 --- /dev/null +++ b/nuttx/drivers/mtd/mtd_rawnand.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * drivers/mtd/mtd_rawnand.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * This logic was based largely on Atmel sample code with modifications for + * better integration with NuttX. The Atmel sample code has a BSD + * compatibile license that requires this copyright notice: + * + * Copyright (c) 2011, 2012, Atmel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the names NuttX nor Atmel nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <nuttx/mtd/nand_config.h> + +#include <stdint.h> +#include <assert.h> +#include <debug.h> + +#include <nuttx/mtd/nand_raw.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nand_chipid + * + * Description: + * Reads and returns the identifiers of a NAND FLASH chip + * + * Input Parameters: + * raw - Pointer to a struct nand_raw_s instance. + * + * Returned Value: + * id1|(id2<<8)|(id3<<16)|(id4<<24) + * + ****************************************************************************/ + +uint32_t nand_chipid(struct nand_raw_s *raw) +{ + uint8_t id[5]; + + DEBUGASSERT(raw); + + WRITE_COMMAND8(raw, COMMAND_READID); + WRITE_ADDRESS8(raw, 0); + + id[0] = READ_DATA8(raw); + id[1] = READ_DATA8(raw); + id[2] = READ_DATA8(raw); + id[3] = READ_DATA8(raw); + id[4] = READ_DATA8(raw); + + fvdbg("Chip ID: %02x %02x %02x %02x %02x\n", + id[0], id[1], id[2], id[3], id[4]); + + return (uint32_t)id[0] | + ((uint32_t)id[1] << 8) | + ((uint32_t)id[2] << 16) | + ((uint32_t)id[3] << 24); +} |