aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
authorbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-10-18 12:23:31 +0000
committerbarthess <barthess@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-10-18 12:23:31 +0000
commitbe302132c782b951b6f81f2833b642a514a70dad (patch)
tree386f7f8c8677f5110c1aa2edd36c65623df60cdc /os/hal/src
parent7c0786cae15cf93e09604abcc66c6d017c4238bd (diff)
downloadChibiOS-be302132c782b951b6f81f2833b642a514a70dad.tar.gz
ChibiOS-be302132c782b951b6f81f2833b642a514a70dad.tar.bz2
ChibiOS-be302132c782b951b6f81f2833b642a514a70dad.zip
FSMC. Files moved to
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7414 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/nand.c601
1 files changed, 0 insertions, 601 deletions
diff --git a/os/hal/src/nand.c b/os/hal/src/nand.c
deleted file mode 100644
index ee2bd3b2d..000000000
--- a/os/hal/src/nand.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- ChibiOS/HAL - Copyright (C) 2006,2007,2008,2009,2010,
- 2011,2012,2013,2014 Giovanni Di Sirio.
-
- This file is part of ChibiOS/HAL
-
- ChibiOS/HAL is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/RT is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- Concepts and parts of this file have been contributed by Uladzimir Pylinsky
- aka barthess.
- */
-
-/**
- * @file nand.c
- * @brief NAND Driver code.
- *
- * @addtogroup NAND
- * @{
- */
-
-#include "hal.h"
-
-#if HAL_USE_NAND || defined(__DOXYGEN__)
-
-#include "string.h" /* for memset */
-
-/*===========================================================================*/
-/* Driver local definitions. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local types. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @brief Check page size.
- *
- * @param[in] page_data_size size of page data area
- *
- * @notapi
- */
-static void pagesize_check(size_t page_data_size){
-
- /* Page size out of bounds.*/
- osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) &&
- (page_data_size <= NAND_MAX_PAGE_SIZE));
-
- /* Page size must be power of 2.*/
- osalDbgCheck(((page_data_size - 1) & page_data_size) == 0);
-}
-
-/**
- * @brief Translate block-page-offset scheme to NAND internal address.
- *
- * @param[in] cfg pointer to the @p NANDConfig from
- * corresponding NAND driver
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[in] offset data offset related to begin of page
- * @param[out] addr buffer to store calculated address
- * @param[in] addr_len length of address buffer
- *
- * @notapi
- */
-static void calc_addr(const NANDConfig *cfg,
- uint32_t block, uint32_t page, uint32_t offset,
- uint8_t *addr, size_t addr_len){
- size_t i = 0;
- uint32_t row = 0;
-
- /* Incorrect buffer length.*/
- osalDbgCheck(cfg->rowcycles + cfg->colcycles == addr_len);
- osalDbgCheck((block < cfg->blocks) && (page < cfg->pages_per_block) &&
- (offset < cfg->page_data_size + cfg->page_spare_size));
-
- /* convert address to NAND specific */
- memset(addr, 0, addr_len);
- row = (block * cfg->pages_per_block) + page;
- for (i=0; i<cfg->colcycles; i++){
- addr[i] = offset & 0xFF;
- offset = offset >> 8;
- }
- for (; i<addr_len; i++){
- addr[i] = row & 0xFF;
- row = row >> 8;
- }
-}
-
-/**
- * @brief Translate block number to NAND internal address.
- * @note This function designed for erasing purpose.
- *
- * @param[in] cfg pointer to the @p NANDConfig from
- * corresponding NAND driver
- * @param[in] block block number
- * @param[out] addr buffer to store calculated address
- * @param[in] addr_len length of address buffer
- *
- * @notapi
- */
-static void calc_blk_addr(const NANDConfig *cfg,
- uint32_t block, uint8_t *addr, size_t addr_len){
- size_t i = 0;
- uint32_t row = 0;
-
- /* Incorrect buffer length.*/
- osalDbgCheck(cfg->rowcycles == addr_len);
- osalDbgCheck((block < cfg->blocks));
-
- /* convert address to NAND specific */
- memset(addr, 0, addr_len);
- row = block * cfg->pages_per_block;
- for (i=0; i<addr_len; i++){
- addr[i] = row & 0xFF;
- row = row >> 8;
- }
-}
-
-#if NAND_USE_BAD_MAP
-/**
- * @brief Add new bad block to map.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] map pointer to bad block map
- */
-static void bad_map_update(NANDDriver *nandp, size_t block) {
-
- uint32_t *map = nandp->config->bb_map;
- const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */
- size_t i;
- size_t shift;
-
- /* Nand device overflow.*/
- osalDbgCheck(nandp->config->blocks > block);
-
- i = block / BPMC;
- shift = block % BPMC;
- /* This block already mapped.*/
- osalDbgCheck(((map[i] >> shift) & 1) != 1);
- map[i] |= (uint32_t)1 << shift;
-}
-
-/**
- * @brief Scan for bad blocks and fill map with their numbers.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- */
-static void scan_bad_blocks(NANDDriver *nandp) {
-
- const size_t blocks = nandp->config->blocks;
- const size_t maplen = blocks / 32;
-
- size_t b;
- uint8_t m0;
- uint8_t m1;
-
- /* clear map just to be safe */
- for (b=0; b<maplen; b++)
- nandp->config->bb_map[b] = 0;
-
- /* now write numbers of bad block to map */
- for (b=0; b<blocks; b++){
- m0 = nandReadBadMark(nandp, b, 0);
- m1 = nandReadBadMark(nandp, b, 1);
- if ((0xFF != m0) || (0xFF != m1)){
- bad_map_update(nandp, b);
- }
- }
-}
-#endif /* NAND_USE_BAD_MAP */
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief NAND Driver initialization.
- * @note This function is implicitly invoked by @p halInit(), there is
- * no need to explicitly initialize the driver.
- *
- * @init
- */
-void nandInit(void) {
-
- nand_lld_init();
-}
-
-/**
- * @brief Initializes the standard part of a @p NANDDriver structure.
- *
- * @param[out] nandp pointer to the @p NANDDriver object
- *
- * @init
- */
-void nandObjectInit(NANDDriver *nandp) {
-
-#if NAND_USE_MUTUAL_EXCLUSION
-#if CH_CFG_USE_MUTEXES
- chMtxObjectInit(&nandp->mutex);
-#else
- chSemObjectInit(&nandp->semaphore, 1);
-#endif /* CH_CFG_USE_MUTEXES */
-#endif /* NAND_USE_MUTUAL_EXCLUSION */
-
- nandp->state = NAND_STOP;
- nandp->config = NULL;
-}
-
-/**
- * @brief Configures and activates the NAND peripheral.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] config pointer to the @p NANDConfig object
- *
- * @api
- */
-void nandStart(NANDDriver *nandp, const NANDConfig *config) {
-
- osalDbgCheck((nandp != NULL) && (config != NULL));
- osalDbgAssert((nandp->state == NAND_STOP) ||
- (nandp->state == NAND_READY),
- "invalid state");
-
- nandp->config = config;
- pagesize_check(nandp->config->page_data_size);
- nand_lld_start(nandp);
- nandp->state = NAND_READY;
-
-#if NAND_USE_BAD_MAP
- scan_bad_blocks(nandp);
-#endif /* NAND_USE_BAD_MAP */
-}
-
-/**
- * @brief Deactivates the NAND peripheral.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- *
- * @api
- */
-void nandStop(NANDDriver *nandp) {
-
- osalDbgCheck(nandp != NULL);
- osalDbgAssert((nandp->state == NAND_STOP) ||
- (nandp->state == NAND_READY),
- "invalid state");
- nand_lld_stop(nandp);
- nandp->state = NAND_STOP;
-}
-
-/**
- * @brief Read whole page.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[out] data buffer to store data
- * @param[in] datalen length of data buffer
- *
- * @api
- */
-void nandReadPageWhole(NANDDriver *nandp, uint32_t block,
- uint32_t page, uint8_t *data, size_t datalen) {
-
- const NANDConfig *cfg = nandp->config;
- uint8_t addrbuf[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((nandp != NULL) && (data != NULL));
- osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size)));
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, 0, addrbuf, addrlen);
- nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, NULL);
-}
-
-/**
- * @brief Write whole page.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[in] data buffer with data to be written
- * @param[in] datalen length of data buffer
- *
- * @return The operation status reported by NAND IC (0x70 command).
- *
- * @api
- */
-uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block,
- uint32_t page, const uint8_t *data, size_t datalen) {
-
- uint8_t retval;
- const NANDConfig *cfg = nandp->config;
- uint8_t addr[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((nandp != NULL) && (data != NULL));
- osalDbgCheck((datalen <= (cfg->page_data_size + cfg->page_spare_size)));
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, 0, addr, addrlen);
- retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, NULL);
- return retval;
-}
-
-/**
- * @brief Read page data without spare area.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[out] data buffer to store data
- * @param[in] datalen length of data buffer
- * @param[out] ecc pointer to calculated ECC. Ignored when NULL.
- *
- * @api
- */
-void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
- uint8_t *data, size_t datalen, uint32_t *ecc) {
-
- const NANDConfig *cfg = nandp->config;
- uint8_t addrbuf[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((nandp != NULL) && (data != NULL));
- osalDbgCheck((datalen <= cfg->page_data_size));
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, 0, addrbuf, addrlen);
- nand_lld_read_data(nandp, data, datalen, addrbuf, addrlen, ecc);
-}
-
-/**
- * @brief Write page data without spare area.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[in] data buffer with data to be written
- * @param[in] datalen length of data buffer
- * @param[out] ecc pointer to calculated ECC. Ignored when NULL.
- *
- * @return The operation status reported by NAND IC (0x70 command).
- *
- * @api
- */
-uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block,
- uint32_t page, const uint8_t *data, size_t datalen, uint32_t *ecc) {
-
- uint8_t retval;
- const NANDConfig *cfg = nandp->config;
- uint8_t addr[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((nandp != NULL) && (data != NULL));
- osalDbgCheck((datalen <= cfg->page_data_size));
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, 0, addr, addrlen);
- retval = nand_lld_write_data(nandp, data, datalen, addr, addrlen, ecc);
- return retval;
-}
-
-/**
- * @brief Read page spare area.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[out] spare buffer to store data
- * @param[in] sparelen length of data buffer
- *
- * @api
- */
-void nandReadPageSpare(NANDDriver *nandp, uint32_t block,
- uint32_t page, uint8_t *spare, size_t sparelen) {
-
- const NANDConfig *cfg = nandp->config;
- uint8_t addr[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((NULL != spare) && (nandp != NULL));
- osalDbgCheck(sparelen <= cfg->page_spare_size);
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen);
- nand_lld_read_data(nandp, spare, sparelen, addr, addrlen, NULL);
-}
-
-/**
- * @brief Write page spare area.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- * @param[in] spare buffer with spare data to be written
- * @param[in] sparelen length of data buffer
- *
- * @return The operation status reported by NAND IC (0x70 command).
- *
- * @api
- */
-uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block,
- uint32_t page, const uint8_t *spare, size_t sparelen) {
-
- uint8_t retVal;
- const NANDConfig *cfg = nandp->config;
- uint8_t addr[8];
- size_t addrlen = cfg->rowcycles + cfg->colcycles;
-
- osalDbgCheck((NULL != spare) && (nandp != NULL));
- osalDbgCheck(sparelen <= cfg->page_spare_size);
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_addr(cfg, block, page, cfg->page_data_size, addr, addrlen);
- retVal = nand_lld_write_data(nandp, spare, sparelen, addr, addrlen, NULL);
- return retVal;
-}
-
-/**
- * @brief Mark block as bad.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- *
- * @api
- */
-void nandMarkBad(NANDDriver *nandp, uint32_t block) {
-
- uint8_t bb_mark[2] = {0, 0};
- uint8_t op_status;
- op_status = nandWritePageSpare(nandp, block, 0, bb_mark, sizeof(bb_mark));
- osalDbgCheck(0 == (op_status & 1)); /* operation failed*/
- op_status = nandWritePageSpare(nandp, block, 1, bb_mark, sizeof(bb_mark));
- osalDbgCheck(0 == (op_status & 1)); /* operation failed*/
-
-#if NAND_USE_BAD_MAP
- bad_map_update(nandp, block);
-#endif
-}
-
-/**
- * @brief Read bad mark out.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- * @param[in] page page number related to begin of block
- *
- * @return Bad mark.
- *
- * @api
- */
-uint8_t nandReadBadMark(NANDDriver *nandp,
- uint32_t block, uint32_t page) {
- uint8_t bb_mark[1];
- nandReadPageSpare(nandp, block, page, bb_mark, sizeof(bb_mark));
- return bb_mark[0];
-}
-
-/**
- * @brief Erase block.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- *
- * @return The operation status reported by NAND IC (0x70 command).
- *
- * @api
- */
-uint8_t nandErase(NANDDriver *nandp, uint32_t block){
-
- uint8_t retVal;
- const NANDConfig *cfg = nandp->config;
- uint8_t addr[4];
- size_t addrlen = cfg->rowcycles;
-
- osalDbgCheck(nandp != NULL);
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
- calc_blk_addr(cfg, block, addr, addrlen);
- retVal = nand_lld_erase(nandp, addr, addrlen);
- return retVal;
-}
-
-/**
- * @brief Report block badness.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- * @param[in] block block number
- *
- * @return block condition
- * @retval true if the block is bad.
- * @retval false if the block is good.
- *
- * @api
- */
-bool nandIsBad(NANDDriver *nandp, uint32_t block){
-
- osalDbgCheck(nandp != NULL);
- osalDbgAssert(nandp->state == NAND_READY, "invalid state");
-
-#if NAND_USE_BAD_MAP
- uint32_t *map = nandp->config->bb_map;
- const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */
- size_t i;
- size_t shift;
-
- i = block / BPMC;
- shift = block % BPMC;
- if (((map[i] >> shift) & 1) == 1)
- return true;
- else
- return false;
-#else
- uint8_t m0, m1;
- m0 = nandReadBadMark(nandp, block, 0);
- m1 = nandReadBadMark(nandp, block, 1);
- if ((0xFF != m0) || (0xFF != m1))
- return true;
- else
- return false;
-#endif /* NAND_USE_BAD_MAP */
-}
-
-#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
-/**
- * @brief Gains exclusive access to the NAND bus.
- * @details This function tries to gain ownership to the NAND bus, if the bus
- * is already being used then the invoking thread is queued.
- * @pre In order to use this function the option
- * @p NAND_USE_MUTUAL_EXCLUSION must be enabled.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- *
- * @api
- */
-void nandAcquireBus(NANDDriver *nandp) {
-
- osalDbgCheck(nandp != NULL);
-
-#if CH_CFG_USE_MUTEXES
- chMtxLock(&nandp->mutex);
-#elif CH_CFG_USE_SEMAPHORES
- chSemWait(&nandp->semaphore);
-#endif
-}
-
-/**
- * @brief Releases exclusive access to the NAND bus.
- * @pre In order to use this function the option
- * @p NAND_USE_MUTUAL_EXCLUSION must be enabled.
- *
- * @param[in] nandp pointer to the @p NANDDriver object
- *
- * @api
- */
-void nandReleaseBus(NANDDriver *nandp) {
-
- osalDbgCheck(nandp != NULL);
-
-#if CH_CFG_USE_MUTEXES
- chMtxUnlock(&nandp->mutex);
-#elif CH_CFG_USE_SEMAPHORES
- chSemSignal(&nandp->semaphore);
-#endif
-}
-#endif /* NAND_USE_MUTUAL_EXCLUSION */
-
-#endif /* HAL_USE_NAND */
-
-/** @} */
-
-
-
-