NAND code changed to use bitmap class

This commit is contained in:
barthess 2015-05-02 20:51:04 +03:00
parent 789b4e18b1
commit c44092eb0f
14 changed files with 124 additions and 182 deletions

View File

@ -111,31 +111,28 @@ extern "C" {
#endif #endif
void nandInit(void); void nandInit(void);
void nandObjectInit(NANDDriver *nandp); void nandObjectInit(NANDDriver *nandp);
void nandStart(NANDDriver *nandp, const NANDConfig *config); void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map);
void nandStop(NANDDriver *nandp); void nandStop(NANDDriver *nandp);
void nandReadPageWhole(NANDDriver *nandp, uint32_t block, void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, uint8_t *data, size_t datalen); uint8_t *data, size_t datalen);
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block,
uint32_t page, const uint8_t *data, size_t datalen);
void nandReadPageData(NANDDriver *nandp, uint32_t block,
uint32_t page, uint8_t *data, size_t datalen, uint32_t *ecc);
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block,
uint32_t page, const uint8_t *data, size_t datalen, uint32_t *ecc);
void nandReadPageSpare(NANDDriver *nandp, uint32_t block,
uint32_t page, uint8_t *spare, size_t sparelen);
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block,
uint32_t page, const uint8_t *spare, size_t sparelen);
void nandMarkBad(NANDDriver *nandp, uint32_t block); void nandMarkBad(NANDDriver *nandp, uint32_t block);
uint8_t nandReadBadMark(NANDDriver *nandp, void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t block, uint32_t page); uint8_t *data, size_t datalen, uint32_t *ecc);
void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t *spare, size_t sparelen);
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
const uint8_t *data, size_t datalen);
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint32_t page,
const uint8_t *data, size_t datalen, uint32_t *ecc);
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
const uint8_t *spare, size_t sparelen);
uint8_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page);
uint8_t nandErase(NANDDriver *nandp, uint32_t block); uint8_t nandErase(NANDDriver *nandp, uint32_t block);
bool nandIsBad(NANDDriver *nandp, uint32_t block); bool nandIsBad(NANDDriver *nandp, uint32_t block);
#if NAND_USE_MUTUAL_EXCLUSION #if NAND_USE_MUTUAL_EXCLUSION
void nandAcquireBus(NANDDriver *nandp); void nandAcquireBus(NANDDriver *nandp);
void nandReleaseBus(NANDDriver *nandp); void nandReleaseBus(NANDDriver *nandp);
#endif /* NAND_USE_MUTUAL_EXCLUSION */ #endif /* NAND_USE_MUTUAL_EXCLUSION */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -70,7 +70,7 @@ NANDDriver NANDD2;
* *
* @notapi * @notapi
*/ */
static void wakeup_isr(NANDDriver *nandp){ static void wakeup_isr(NANDDriver *nandp) {
osalDbgCheck(nandp->thread != NULL); osalDbgCheck(nandp->thread != NULL);
osalThreadResumeI(&nandp->thread, MSG_OK); osalThreadResumeI(&nandp->thread, MSG_OK);
@ -91,7 +91,7 @@ static void nand_lld_suspend_thread(NANDDriver *nandp) {
* *
* @param[in] nandp pointer to the @p NANDDriver object * @param[in] nandp pointer to the @p NANDDriver object
*/ */
static uint32_t calc_eccps(NANDDriver *nandp){ static uint32_t calc_eccps(NANDDriver *nandp) {
uint32_t i = 0; uint32_t i = 0;
uint32_t eccps = nandp->config->page_data_size; uint32_t eccps = nandp->config->page_data_size;
@ -148,7 +148,7 @@ static void nand_ready_isr_disable(NANDDriver *nandp) {
* *
* @notapi * @notapi
*/ */
static void nand_isr_handler (NANDDriver *nandp){ static void nand_isr_handler (NANDDriver *nandp) {
osalSysLockFromISR(); osalSysLockFromISR();
@ -252,6 +252,7 @@ void nand_lld_init(void) {
NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA; NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA;
NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD; NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD;
NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR; NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR;
NANDD1.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND1 */ #endif /* STM32_NAND_USE_FSMC_NAND1 */
#if STM32_NAND_USE_FSMC_NAND2 #if STM32_NAND_USE_FSMC_NAND2
@ -265,6 +266,7 @@ void nand_lld_init(void) {
NANDD2.map_data = (uint8_t*)FSMC_Bank3_MAP_COMMON_DATA; NANDD2.map_data = (uint8_t*)FSMC_Bank3_MAP_COMMON_DATA;
NANDD2.map_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD; NANDD2.map_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD;
NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR; NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR;
NANDD2.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND2 */ #endif /* STM32_NAND_USE_FSMC_NAND2 */
} }
@ -332,8 +334,8 @@ void nand_lld_stop(NANDDriver *nandp) {
* *
* @notapi * @notapi
*/ */
void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, size_t datalen,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ uint8_t *addr, size_t addrlen, uint32_t *ecc){
nandp->state = NAND_READ; nandp->state = NAND_READ;
nandp->rxdata = data; nandp->rxdata = data;
@ -381,7 +383,7 @@ void nand_lld_read_data(NANDDriver *nandp, uint8_t *data,
* @notapi * @notapi
*/ */
uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data, uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc){ size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc) {
nandp->state = NAND_WRITE; nandp->state = NAND_WRITE;
@ -425,7 +427,7 @@ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
* *
* @notapi * @notapi
*/ */
uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen){ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen) {
nandp->state = NAND_ERASE; nandp->state = NAND_ERASE;
@ -451,7 +453,7 @@ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen){
* *
* @notapi * @notapi
*/ */
void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len){ void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len) {
size_t i = 0; size_t i = 0;
for (i=0; i<len; i++) for (i=0; i<len; i++)
@ -467,7 +469,7 @@ void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len){
* *
* @notapi * @notapi
*/ */
void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len){ void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len) {
size_t i = 0; size_t i = 0;
for (i=0; i<len; i++) for (i=0; i<len; i++)
@ -482,7 +484,7 @@ void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len){
* *
* @notapi * @notapi
*/ */
void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd){ void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd) {
nandp->map_cmd[0] = cmd; nandp->map_cmd[0] = cmd;
} }

View File

@ -26,6 +26,7 @@
#define _NAND_LLD_H_ #define _NAND_LLD_H_
#include "fsmc.h" #include "fsmc.h"
#include "bitmap.h"
#if HAL_USE_NAND || defined(__DOXYGEN__) #if HAL_USE_NAND || defined(__DOXYGEN__)
@ -167,7 +168,7 @@ typedef struct {
/** /**
* @brief Pointer to lower level driver. * @brief Pointer to lower level driver.
*/ */
FSMCDriver *fsmcp; //const FSMCDriver *fsmcp;
/** /**
* @brief Number of erase blocks in NAND device. * @brief Number of erase blocks in NAND device.
*/ */
@ -184,13 +185,6 @@ typedef struct {
* @brief Number of pages in block. * @brief Number of pages in block.
*/ */
uint32_t pages_per_block; uint32_t pages_per_block;
#if NAND_USE_BAD_MAP
/**
* @brief Pointer to bad block map.
* @details One bit per block. Memory for map must be allocated by user.
*/
uint32_t *bb_map;
#endif /* NAND_USE_BAD_MAP */
/** /**
* @brief Number of write cycles for row addressing. * @brief Number of write cycles for row addressing.
*/ */
@ -287,6 +281,11 @@ struct NANDDriver {
* @brief Memory mapping for addresses. * @brief Memory mapping for addresses.
*/ */
uint8_t *map_addr; uint8_t *map_addr;
/**
* @brief Pointer to bad block map.
* @details One bit per block. All memory allocation is user's responsibility.
*/
bitmap_t *bb_map;
}; };
/*===========================================================================*/ /*===========================================================================*/
@ -311,14 +310,14 @@ extern "C" {
void nand_lld_init(void); void nand_lld_init(void);
void nand_lld_start(NANDDriver *nandp); void nand_lld_start(NANDDriver *nandp);
void nand_lld_stop(NANDDriver *nandp); void nand_lld_stop(NANDDriver *nandp);
uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
void nand_lld_read_data(NANDDriver *nandp, uint8_t *data, void nand_lld_read_data(NANDDriver *nandp, uint8_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc); size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len); void nand_lld_polled_read_data(NANDDriver *nandp, uint8_t *data, size_t len);
uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen);
void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len); void nand_lld_write_addr(NANDDriver *nandp, const uint8_t *addr, size_t len);
void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd); void nand_lld_write_cmd(NANDDriver *nandp, uint8_t cmd);
uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen);
uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
uint8_t nand_lld_read_status(NANDDriver *nandp); uint8_t nand_lld_read_status(NANDDriver *nandp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -62,7 +62,7 @@
* *
* @notapi * @notapi
*/ */
static void pagesize_check(size_t page_data_size){ static void pagesize_check(size_t page_data_size) {
/* Page size out of bounds.*/ /* Page size out of bounds.*/
osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) && osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) &&
@ -85,9 +85,8 @@ static void pagesize_check(size_t page_data_size){
* *
* @notapi * @notapi
*/ */
static void calc_addr(const NANDConfig *cfg, static void calc_addr(const NANDConfig *cfg, uint32_t block, uint32_t page,
uint32_t block, uint32_t page, uint32_t offset, uint32_t offset, uint8_t *addr, size_t addr_len) {
uint8_t *addr, size_t addr_len){
size_t i = 0; size_t i = 0;
uint32_t row = 0; uint32_t row = 0;
@ -121,8 +120,8 @@ static void calc_addr(const NANDConfig *cfg,
* *
* @notapi * @notapi
*/ */
static void calc_blk_addr(const NANDConfig *cfg, static void calc_blk_addr(const NANDConfig *cfg, uint32_t block,
uint32_t block, uint8_t *addr, size_t addr_len){ uint8_t *addr, size_t addr_len) {
size_t i = 0; size_t i = 0;
uint32_t row = 0; uint32_t row = 0;
@ -139,59 +138,55 @@ static void calc_blk_addr(const NANDConfig *cfg,
} }
} }
#if NAND_USE_BAD_MAP
/** /**
* @brief Add new bad block to map. * @brief Read block badness mark directly from NAND memory array.
* *
* @param[in] nandp pointer to the @p NANDDriver object * @param[in] nandp pointer to the @p NANDDriver object
* @param[in] block block number * @param[in] block block number
* @param[in] map pointer to bad block map *
* @return block condition
* @retval true if the block is bad.
* @retval false if the block is good.
*
* @notapi
*/ */
static void bad_map_update(NANDDriver *nandp, size_t block) { static bool read_is_block_bad(NANDDriver *nandp, size_t block) {
uint8_t m0;
uint8_t m1;
uint32_t *map = nandp->config->bb_map; m0 = nandReadBadMark(nandp, block, 0);
const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */ m1 = nandReadBadMark(nandp, block, 1);
size_t i;
size_t shift;
/* Nand device overflow.*/ if ((0xFF != m0) || (0xFF != m1))
osalDbgCheck(nandp->config->blocks > block); return true;
else
i = block / BPMC; return false;
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. * @brief Scan for bad blocks and fill map with their numbers.
* *
* @param[in] nandp pointer to the @p NANDDriver object * @param[in] nandp pointer to the @p NANDDriver object
*
* @notapi
*/ */
static void scan_bad_blocks(NANDDriver *nandp) { static void scan_bad_blocks(NANDDriver *nandp) {
const size_t blocks = nandp->config->blocks; const size_t blocks = nandp->config->blocks;
const size_t maplen = blocks / 32;
size_t b; size_t b;
uint8_t m0;
uint8_t m1; osalDbgCheck(bitmapGetBitsCount(nandp->bb_map) >= blocks);
/* clear map just to be safe */ /* clear map just to be safe */
for (b=0; b<maplen; b++) bitmapObjectInit(nandp->bb_map, 0);
nandp->config->bb_map[b] = 0;
/* now write numbers of bad block to map */ /* now write numbers of bad block to map */
for (b=0; b<blocks; b++){ for (b=0; b<blocks; b++) {
m0 = nandReadBadMark(nandp, b, 0); if (read_is_block_bad(nandp, b)) {
m1 = nandReadBadMark(nandp, b, 1); bitmapSet(nandp->bb_map, b);
if ((0xFF != m0) || (0xFF != m1)){
bad_map_update(nandp, b);
} }
} }
} }
#endif /* NAND_USE_BAD_MAP */
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported functions. */ /* Driver exported functions. */
@ -235,10 +230,11 @@ void nandObjectInit(NANDDriver *nandp) {
* *
* @param[in] nandp pointer to the @p NANDDriver object * @param[in] nandp pointer to the @p NANDDriver object
* @param[in] config pointer to the @p NANDConfig object * @param[in] config pointer to the @p NANDConfig object
* @param[in] bb_map pointer to the bad block map or @NULL if not need
* *
* @api * @api
*/ */
void nandStart(NANDDriver *nandp, const NANDConfig *config) { void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map) {
osalDbgCheck((nandp != NULL) && (config != NULL)); osalDbgCheck((nandp != NULL) && (config != NULL));
osalDbgAssert((nandp->state == NAND_STOP) || osalDbgAssert((nandp->state == NAND_STOP) ||
@ -250,9 +246,10 @@ void nandStart(NANDDriver *nandp, const NANDConfig *config) {
nand_lld_start(nandp); nand_lld_start(nandp);
nandp->state = NAND_READY; nandp->state = NAND_READY;
#if NAND_USE_BAD_MAP if (NULL != bb_map) {
nandp->bb_map = bb_map;
scan_bad_blocks(nandp); scan_bad_blocks(nandp);
#endif /* NAND_USE_BAD_MAP */ }
} }
/** /**
@ -283,8 +280,8 @@ void nandStop(NANDDriver *nandp) {
* *
* @api * @api
*/ */
void nandReadPageWhole(NANDDriver *nandp, uint32_t block, void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, uint8_t *data, size_t datalen) { uint8_t *data, size_t datalen) {
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
uint8_t addrbuf[8]; uint8_t addrbuf[8];
@ -311,8 +308,8 @@ void nandReadPageWhole(NANDDriver *nandp, uint32_t block,
* *
* @api * @api
*/ */
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, const uint8_t *data, size_t datalen) { const uint8_t *data, size_t datalen) {
uint8_t retval; uint8_t retval;
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
@ -369,8 +366,8 @@ void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
* *
* @api * @api
*/ */
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, const uint8_t *data, size_t datalen, uint32_t *ecc) { const uint8_t *data, size_t datalen, uint32_t *ecc) {
uint8_t retval; uint8_t retval;
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
@ -397,8 +394,8 @@ uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block,
* *
* @api * @api
*/ */
void nandReadPageSpare(NANDDriver *nandp, uint32_t block, void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, uint8_t *spare, size_t sparelen) { uint8_t *spare, size_t sparelen) {
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
uint8_t addr[8]; uint8_t addr[8];
@ -425,8 +422,8 @@ void nandReadPageSpare(NANDDriver *nandp, uint32_t block,
* *
* @api * @api
*/ */
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
uint32_t page, const uint8_t *spare, size_t sparelen) { const uint8_t *spare, size_t sparelen) {
uint8_t retVal; uint8_t retVal;
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
@ -453,15 +450,12 @@ uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block,
void nandMarkBad(NANDDriver *nandp, uint32_t block) { void nandMarkBad(NANDDriver *nandp, uint32_t block) {
uint8_t bb_mark[2] = {0, 0}; 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 nandWritePageSpare(nandp, block, 0, bb_mark, sizeof(bb_mark));
bad_map_update(nandp, block); nandWritePageSpare(nandp, block, 1, bb_mark, sizeof(bb_mark));
#endif
if (NULL != nandp->bb_map)
bitmapSet(nandp->bb_map, block);
} }
/** /**
@ -475,9 +469,9 @@ void nandMarkBad(NANDDriver *nandp, uint32_t block) {
* *
* @api * @api
*/ */
uint8_t nandReadBadMark(NANDDriver *nandp, uint8_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page) {
uint32_t block, uint32_t page) {
uint8_t bb_mark[1]; uint8_t bb_mark[1];
nandReadPageSpare(nandp, block, page, bb_mark, sizeof(bb_mark)); nandReadPageSpare(nandp, block, page, bb_mark, sizeof(bb_mark));
return bb_mark[0]; return bb_mark[0];
} }
@ -492,7 +486,7 @@ uint8_t nandReadBadMark(NANDDriver *nandp,
* *
* @api * @api
*/ */
uint8_t nandErase(NANDDriver *nandp, uint32_t block){ uint8_t nandErase(NANDDriver *nandp, uint32_t block) {
uint8_t retVal; uint8_t retVal;
const NANDConfig *cfg = nandp->config; const NANDConfig *cfg = nandp->config;
@ -508,7 +502,7 @@ uint8_t nandErase(NANDDriver *nandp, uint32_t block){
} }
/** /**
* @brief Report block badness. * @brief Check block badness.
* *
* @param[in] nandp pointer to the @p NANDDriver object * @param[in] nandp pointer to the @p NANDDriver object
* @param[in] block block number * @param[in] block block number
@ -519,32 +513,15 @@ uint8_t nandErase(NANDDriver *nandp, uint32_t block){
* *
* @api * @api
*/ */
bool nandIsBad(NANDDriver *nandp, uint32_t block){ bool nandIsBad(NANDDriver *nandp, uint32_t block) {
osalDbgCheck(nandp != NULL); osalDbgCheck(nandp != NULL);
osalDbgAssert(nandp->state == NAND_READY, "invalid state"); osalDbgAssert(nandp->state == NAND_READY, "invalid state");
#if NAND_USE_BAD_MAP if (NULL != nandp->bb_map)
uint32_t *map = nandp->config->bb_map; return 1 == bitmapGet(nandp->bb_map, block);
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 else
return false; return read_is_block_bad(nandp, block);
#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__) #if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -105,6 +105,7 @@ CSRC = $(STARTUPSRC) \
$(PLATFORMSRC) \ $(PLATFORMSRC) \
$(BOARDSRC) \ $(BOARDSRC) \
$(TESTSRC) \ $(TESTSRC) \
$(CHIBIOS)/community/os/various/bitmap.c \
dma_storm_adc.c \ dma_storm_adc.c \
dma_storm_spi.c \ dma_storm_spi.c \
dma_storm_uart.c \ dma_storm_uart.c \
@ -139,7 +140,7 @@ ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
$(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \ $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \
$(CHIBIOS)/os/various $(CHIBIOS)/os/various $(CHIBIOS)/community/os/various
# #

View File

@ -361,7 +361,7 @@
* *
* @note The default is @p FALSE. * @note The default is @p FALSE.
*/ */
#define CH_DBG_ENABLE_TRACE TRUE #define CH_DBG_ENABLE_TRACE FALSE
/** /**
* @brief Debug option, stack checks. * @brief Debug option, stack checks.

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -44,6 +44,8 @@
#include "ch.h" #include "ch.h"
#include "hal.h" #include "hal.h"
#include "bitmap.h"
#include "dma_storm.h" #include "dma_storm.h"
#include "string.h" #include "string.h"
#include "stdlib.h" #include "stdlib.h"
@ -54,6 +56,8 @@
****************************************************************************** ******************************************************************************
*/ */
#define USE_BAD_MAP TRUE
#define USE_KILL_BLOCK_TEST FALSE #define USE_KILL_BLOCK_TEST FALSE
#define FSMCNAND_TIME_SET ((uint32_t) 2) //(8nS) #define FSMCNAND_TIME_SET ((uint32_t) 2) //(8nS)
@ -69,7 +73,7 @@
#define NAND_ROW_WRITE_CYCLES 3 #define NAND_ROW_WRITE_CYCLES 3
#define NAND_COL_WRITE_CYCLES 2 #define NAND_COL_WRITE_CYCLES 2
#define NANF_TEST_START_BLOCK 1200 #define NAND_TEST_START_BLOCK 1200
#define NAND_TEST_END_BLOCK 1220 #define NAND_TEST_END_BLOCK 1220
#if USE_KILL_BLOCK_TEST #if USE_KILL_BLOCK_TEST
@ -120,23 +124,26 @@ static time_measurement_t tmu_write_data;
static time_measurement_t tmu_write_spare; static time_measurement_t tmu_write_spare;
static time_measurement_t tmu_read_data; static time_measurement_t tmu_read_data;
static time_measurement_t tmu_read_spare; static time_measurement_t tmu_read_spare;
static time_measurement_t tmu_driver_start;
#if NAND_USE_BAD_MAP #if USE_BAD_MAP
static uint32_t badblock_map[NAND_BLOCKS_COUNT / 32]; #define BAD_MAP_LEN (NAND_BLOCKS_COUNT / (sizeof(bitmap_word_t) * 8))
static bitmap_word_t badblock_map_array[BAD_MAP_LEN];
static bitmap_t badblock_map = {
badblock_map_array,
BAD_MAP_LEN
};
#endif #endif
/* /*
* *
*/ */
static const NANDConfig nandcfg = { static const NANDConfig nandcfg = {
&FSMCD1, //&FSMCD1,
NAND_BLOCKS_COUNT, NAND_BLOCKS_COUNT,
NAND_PAGE_DATA_SIZE, NAND_PAGE_DATA_SIZE,
NAND_PAGE_SPARE_SIZE, NAND_PAGE_SPARE_SIZE,
NAND_PAGES_PER_BLOCK, NAND_PAGES_PER_BLOCK,
#if NAND_USE_BAD_MAP
badblock_map,
#endif
NAND_ROW_WRITE_CYCLES, NAND_ROW_WRITE_CYCLES,
NAND_COL_WRITE_CYCLES, NAND_COL_WRITE_CYCLES,
/* stm32 specific fields */ /* stm32 specific fields */
@ -567,7 +574,14 @@ int main(void) {
#if STM32_NAND_USE_EXT_INT #if STM32_NAND_USE_EXT_INT
extStart(&EXTD1, &extcfg); extStart(&EXTD1, &extcfg);
#endif #endif
nandStart(&NAND, &nandcfg); chTMObjectInit(&tmu_driver_start);
chTMStartMeasurementX(&tmu_driver_start);
#if USE_BAD_MAP
nandStart(&NAND, &nandcfg, &badblock_map);
#else
nandStart(&NAND, &nandcfg, NULL);
#endif
chTMStopMeasurementX(&tmu_driver_start);
chThdSleepMilliseconds(4000); chThdSleepMilliseconds(4000);
@ -586,7 +600,7 @@ int main(void) {
dma_storm_uart_start(); dma_storm_uart_start();
dma_storm_spi_start(); dma_storm_spi_start();
T = chVTGetSystemTimeX(); T = chVTGetSystemTimeX();
general_test(&NAND, NANF_TEST_START_BLOCK, NAND_TEST_END_BLOCK, 1); general_test(&NAND, NAND_TEST_START_BLOCK, NAND_TEST_END_BLOCK, 1);
T = chVTGetSystemTimeX() - T; T = chVTGetSystemTimeX() - T;
adc_ints = dma_storm_adc_stop(); adc_ints = dma_storm_adc_stop();
uart_ints = dma_storm_uart_stop(); uart_ints = dma_storm_uart_stop();

View File

@ -21,7 +21,7 @@
#define STM32_FSMC_FSMC1_IRQ_PRIORITY 10 #define STM32_FSMC_FSMC1_IRQ_PRIORITY 10
#define STM32_NAND_USE_FSMC_NAND1 TRUE #define STM32_NAND_USE_FSMC_NAND1 TRUE
#define STM32_NAND_USE_EXT_INT TRUE #define STM32_NAND_USE_EXT_INT FALSE
#define STM32_NAND_DMA_STREAM STM32_DMA_STREAM_ID(2, 7) #define STM32_NAND_DMA_STREAM STM32_DMA_STREAM_ID(2, 7)
#define STM32_NAND_DMA_PRIORITY 0 #define STM32_NAND_DMA_PRIORITY 0
#define STM32_NAND_DMA_ERROR_HOOK(nandp) osalSysHalt("DMA failure") #define STM32_NAND_DMA_ERROR_HOOK(nandp) osalSysHalt("DMA failure")

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE #define NAND_USE_MUTUAL_EXCLUSION TRUE
#endif #endif
/**
* @brief Enables internal driver map for bad blocks.
* @note Disabling this option saves both code and data space.
*/
#if !defined(NAND_USE_BAD_MAP) || defined(__DOXYGEN__)
#define NAND_USE_BAD_MAP TRUE
#endif
/*===========================================================================*/ /*===========================================================================*/
/* 1-wire driver related settings. */ /* 1-wire driver related settings. */
/*===========================================================================*/ /*===========================================================================*/