Merge master

This commit is contained in:
Fabio Utzig 2015-05-10 17:51:59 -03:00
commit a0110bc179
21 changed files with 445 additions and 266 deletions

View File

@ -24,7 +24,7 @@
/*
* Board identifier.
*/
#define BOARD_NAME "NAND and SRAM test board. Codename Buod"
#define BOARD_NAME "NAND and SRAM test board (codename Buod)"
/*
* Board oscillators-related settings.
@ -60,14 +60,22 @@
#define GPIOA_PIN6 6
#define GPIOA_PIN7 7
#define GPIOA_PIN8 8
#define GPIOA_PIN9 9
#define GPIOA_USB_PRESENT 9
#define GPIOA_PIN10 10
#define GPIOA_PIN11 11
#define GPIOA_PIN12 12
#define GPIOA_OTG_FS_DM 11
#define GPIOA_OTG_FS_DP 12
#define GPIOA_JTMS 13
#define GPIOA_JTCK 14
#define GPIOA_JTDI 15
#define GPIOA_USB_PRESENT 9
#define GPIOA_PIN10 10
#define GPIOA_OTG_FS_DM 11
#define GPIOA_OTG_FS_DP 12
#define GPIOB_PIN0 0
#define GPIOB_NAND_WP 1
#define GPIOB_PIN2 2
@ -238,10 +246,10 @@
PIN_MODE_INPUT(GPIOA_PIN6) | \
PIN_MODE_INPUT(GPIOA_PIN7) | \
PIN_MODE_INPUT(GPIOA_PIN8) | \
PIN_MODE_INPUT(GPIOA_PIN9) | \
PIN_MODE_INPUT(GPIOA_USB_PRESENT) | \
PIN_MODE_INPUT(GPIOA_PIN10) | \
PIN_MODE_INPUT(GPIOA_PIN11) | \
PIN_MODE_INPUT(GPIOA_PIN12) | \
PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DM) | \
PIN_MODE_ALTERNATE(GPIOA_OTG_FS_DP) | \
PIN_MODE_ALTERNATE(GPIOA_JTMS) | \
PIN_MODE_ALTERNATE(GPIOA_JTCK) | \
PIN_MODE_ALTERNATE(GPIOA_JTDI))
@ -254,10 +262,10 @@
PIN_OTYPE_PUSHPULL(GPIOA_PIN6) | \
PIN_OTYPE_PUSHPULL(GPIOA_PIN7) | \
PIN_OTYPE_PUSHPULL(GPIOA_PIN8) | \
PIN_OTYPE_PUSHPULL(GPIOA_PIN9) | \
PIN_OTYPE_PUSHPULL(GPIOA_USB_PRESENT) |\
PIN_OTYPE_PUSHPULL(GPIOA_PIN10) | \
PIN_OTYPE_PUSHPULL(GPIOA_PIN11) | \
PIN_OTYPE_PUSHPULL(GPIOA_PIN12) | \
PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DM) | \
PIN_OTYPE_PUSHPULL(GPIOA_OTG_FS_DP) | \
PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \
PIN_OTYPE_PUSHPULL(GPIOA_JTCK) | \
PIN_OTYPE_PUSHPULL(GPIOA_JTDI))
@ -270,10 +278,10 @@
PIN_OSPEED_100M(GPIOA_PIN6) | \
PIN_OSPEED_100M(GPIOA_PIN7) | \
PIN_OSPEED_100M(GPIOA_PIN8) | \
PIN_OSPEED_100M(GPIOA_PIN9) | \
PIN_OSPEED_100M(GPIOA_USB_PRESENT) | \
PIN_OSPEED_100M(GPIOA_PIN10) | \
PIN_OSPEED_100M(GPIOA_PIN11) | \
PIN_OSPEED_100M(GPIOA_PIN12) | \
PIN_OSPEED_100M(GPIOA_OTG_FS_DM) | \
PIN_OSPEED_100M(GPIOA_OTG_FS_DP) | \
PIN_OSPEED_100M(GPIOA_JTMS) | \
PIN_OSPEED_100M(GPIOA_JTCK) | \
PIN_OSPEED_100M(GPIOA_JTDI))
@ -286,10 +294,10 @@
PIN_PUPDR_FLOATING(GPIOA_PIN6) | \
PIN_PUPDR_FLOATING(GPIOA_PIN7) | \
PIN_PUPDR_FLOATING(GPIOA_PIN8) | \
PIN_PUPDR_FLOATING(GPIOA_PIN9) | \
PIN_PUPDR_FLOATING(GPIOA_USB_PRESENT) |\
PIN_PUPDR_FLOATING(GPIOA_PIN10) | \
PIN_PUPDR_FLOATING(GPIOA_PIN11) | \
PIN_PUPDR_FLOATING(GPIOA_PIN12) | \
PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DM) | \
PIN_PUPDR_FLOATING(GPIOA_OTG_FS_DP) | \
PIN_PUPDR_FLOATING(GPIOA_JTMS) | \
PIN_PUPDR_FLOATING(GPIOA_JTCK) | \
PIN_PUPDR_FLOATING(GPIOA_JTDI))
@ -302,10 +310,10 @@
PIN_ODR_HIGH(GPIOA_PIN6) | \
PIN_ODR_HIGH(GPIOA_PIN7) | \
PIN_ODR_HIGH(GPIOA_PIN8) | \
PIN_ODR_HIGH(GPIOA_PIN9) | \
PIN_ODR_HIGH(GPIOA_USB_PRESENT) | \
PIN_ODR_HIGH(GPIOA_PIN10) | \
PIN_ODR_HIGH(GPIOA_PIN11) | \
PIN_ODR_HIGH(GPIOA_PIN12) | \
PIN_ODR_HIGH(GPIOA_OTG_FS_DM) | \
PIN_ODR_HIGH(GPIOA_OTG_FS_DP) | \
PIN_ODR_HIGH(GPIOA_JTMS) | \
PIN_ODR_HIGH(GPIOA_JTCK) | \
PIN_ODR_HIGH(GPIOA_JTDI))
@ -318,10 +326,10 @@
PIN_AFIO_AF(GPIOA_PIN6, 0) | \
PIN_AFIO_AF(GPIOA_PIN7, 0))
#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_PIN8, 0) | \
PIN_AFIO_AF(GPIOA_PIN9, 0) | \
PIN_AFIO_AF(GPIOA_USB_PRESENT, 0) | \
PIN_AFIO_AF(GPIOA_PIN10, 0) | \
PIN_AFIO_AF(GPIOA_PIN11, 0) | \
PIN_AFIO_AF(GPIOA_PIN12, 0) | \
PIN_AFIO_AF(GPIOA_OTG_FS_DM, 10) | \
PIN_AFIO_AF(GPIOA_OTG_FS_DP, 10) | \
PIN_AFIO_AF(GPIOA_JTMS, 0) | \
PIN_AFIO_AF(GPIOA_JTCK, 0) | \
PIN_AFIO_AF(GPIOA_JTDI, 0))

View File

@ -1,20 +1,17 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
This file is part of ChibiOS/HAL
Licensed 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
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.
http://www.apache.org/licenses/LICENSE-2.0
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/>.
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.
*/
/**

View File

@ -1,25 +1,18 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
This file is part of ChibiOS/HAL
Licensed 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
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.
http://www.apache.org/licenses/LICENSE-2.0
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/>.
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.
*/
/*
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
aka barthess.
*/
/**
* @file nand.h
@ -111,31 +104,28 @@ extern "C" {
#endif
void nandInit(void);
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 nandReadPageWhole(NANDDriver *nandp, uint32_t block,
uint32_t page, 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 nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t *data, size_t datalen);
void nandMarkBad(NANDDriver *nandp, uint32_t block);
uint8_t nandReadBadMark(NANDDriver *nandp,
uint32_t block, uint32_t page);
void nandReadPageData(NANDDriver *nandp, 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);
bool nandIsBad(NANDDriver *nandp, uint32_t block);
#if NAND_USE_MUTUAL_EXCLUSION
void nandAcquireBus(NANDDriver *nandp);
void nandReleaseBus(NANDDriver *nandp);
#endif /* NAND_USE_MUTUAL_EXCLUSION */
#ifdef __cplusplus
}
#endif

View File

@ -14,8 +14,6 @@
limitations under the License.
*/
/**
* @file onewire.h
* @brief 1-wire Driver macros and structures.

View File

@ -70,7 +70,7 @@ NANDDriver NANDD2;
*
* @notapi
*/
static void wakeup_isr(NANDDriver *nandp){
static void wakeup_isr(NANDDriver *nandp) {
osalDbgCheck(nandp->thread != NULL);
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
*/
static uint32_t calc_eccps(NANDDriver *nandp){
static uint32_t calc_eccps(NANDDriver *nandp) {
uint32_t i = 0;
uint32_t eccps = nandp->config->page_data_size;
@ -148,7 +148,7 @@ static void nand_ready_isr_disable(NANDDriver *nandp) {
*
* @notapi
*/
static void nand_isr_handler (NANDDriver *nandp){
static void nand_isr_handler (NANDDriver *nandp) {
osalSysLockFromISR();
@ -252,6 +252,7 @@ void nand_lld_init(void) {
NANDD1.map_data = (uint8_t*)FSMC_Bank2_MAP_COMMON_DATA;
NANDD1.map_cmd = (uint8_t*)FSMC_Bank2_MAP_COMMON_CMD;
NANDD1.map_addr = (uint8_t*)FSMC_Bank2_MAP_COMMON_ADDR;
NANDD1.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND1 */
#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_cmd = (uint8_t*)FSMC_Bank3_MAP_COMMON_CMD;
NANDD2.map_addr = (uint8_t*)FSMC_Bank3_MAP_COMMON_ADDR;
NANDD2.bb_map = NULL;
#endif /* STM32_NAND_USE_FSMC_NAND2 */
}
@ -332,8 +334,8 @@ void nand_lld_stop(NANDDriver *nandp) {
*
* @notapi
*/
void nand_lld_read_data(NANDDriver *nandp, 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, size_t datalen,
uint8_t *addr, size_t addrlen, uint32_t *ecc){
nandp->state = NAND_READ;
nandp->rxdata = data;
@ -381,7 +383,7 @@ void nand_lld_read_data(NANDDriver *nandp, uint8_t *data,
* @notapi
*/
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;
@ -425,7 +427,7 @@ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint8_t *data,
*
* @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;
@ -451,7 +453,7 @@ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen){
*
* @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;
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
*/
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;
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
*/
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;
}

View File

@ -26,6 +26,7 @@
#define _NAND_LLD_H_
#include "fsmc.h"
#include "bitmap.h"
#if HAL_USE_NAND || defined(__DOXYGEN__)
@ -167,7 +168,7 @@ typedef struct {
/**
* @brief Pointer to lower level driver.
*/
FSMCDriver *fsmcp;
//const FSMCDriver *fsmcp;
/**
* @brief Number of erase blocks in NAND device.
*/
@ -184,13 +185,6 @@ typedef struct {
* @brief Number of pages in 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.
*/
@ -287,6 +281,11 @@ struct NANDDriver {
* @brief Memory mapping for addresses.
*/
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_start(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,
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);
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_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);
#ifdef __cplusplus
}

View File

@ -1,20 +1,17 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
This file is part of ChibiOS/HAL
Licensed 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
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.
http://www.apache.org/licenses/LICENSE-2.0
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/>.
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.
*/
/**

View File

@ -1,25 +1,18 @@
/*
ChibiOS/HAL - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
This file is part of ChibiOS/HAL
Licensed 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
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.
http://www.apache.org/licenses/LICENSE-2.0
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/>.
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.
*/
/*
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
aka barthess.
*/
/**
* @file nand.c
@ -62,7 +55,7 @@
*
* @notapi
*/
static void pagesize_check(size_t page_data_size){
static void pagesize_check(size_t page_data_size) {
/* Page size out of bounds.*/
osalDbgCheck((page_data_size >= NAND_MIN_PAGE_SIZE) &&
@ -85,9 +78,8 @@ static void pagesize_check(size_t page_data_size){
*
* @notapi
*/
static void calc_addr(const NANDConfig *cfg,
uint32_t block, uint32_t page, uint32_t offset,
uint8_t *addr, size_t addr_len){
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;
@ -121,8 +113,8 @@ static void calc_addr(const NANDConfig *cfg,
*
* @notapi
*/
static void calc_blk_addr(const NANDConfig *cfg,
uint32_t block, uint8_t *addr, size_t addr_len){
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;
@ -139,59 +131,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] 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;
const size_t BPMC = sizeof(uint32_t) * 8; /* bits per map claster */
size_t i;
size_t shift;
m0 = nandReadBadMark(nandp, block, 0);
m1 = nandReadBadMark(nandp, block, 1);
/* 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;
if ((0xFF != m0) || (0xFF != m1))
return true;
else
return false;
}
/**
* @brief Scan for bad blocks and fill map with their numbers.
*
* @param[in] nandp pointer to the @p NANDDriver object
*
* @notapi
*/
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;
osalDbgCheck(bitmapGetBitsCount(nandp->bb_map) >= blocks);
/* clear map just to be safe */
for (b=0; b<maplen; b++)
nandp->config->bb_map[b] = 0;
bitmapObjectInit(nandp->bb_map, 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);
for (b=0; b<blocks; b++) {
if (read_is_block_bad(nandp, b)) {
bitmapSet(nandp->bb_map, b);
}
}
}
#endif /* NAND_USE_BAD_MAP */
/*===========================================================================*/
/* Driver exported functions. */
@ -235,10 +223,11 @@ void nandObjectInit(NANDDriver *nandp) {
*
* @param[in] nandp pointer to the @p NANDDriver 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
*/
void nandStart(NANDDriver *nandp, const NANDConfig *config) {
void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map) {
osalDbgCheck((nandp != NULL) && (config != NULL));
osalDbgAssert((nandp->state == NAND_STOP) ||
@ -250,9 +239,10 @@ void nandStart(NANDDriver *nandp, const NANDConfig *config) {
nand_lld_start(nandp);
nandp->state = NAND_READY;
#if NAND_USE_BAD_MAP
scan_bad_blocks(nandp);
#endif /* NAND_USE_BAD_MAP */
if (NULL != bb_map) {
nandp->bb_map = bb_map;
scan_bad_blocks(nandp);
}
}
/**
@ -283,8 +273,8 @@ void nandStop(NANDDriver *nandp) {
*
* @api
*/
void nandReadPageWhole(NANDDriver *nandp, uint32_t block,
uint32_t page, uint8_t *data, size_t datalen) {
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];
@ -311,8 +301,8 @@ void nandReadPageWhole(NANDDriver *nandp, uint32_t block,
*
* @api
*/
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block,
uint32_t page, const uint8_t *data, size_t datalen) {
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;
@ -369,8 +359,8 @@ void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
*
* @api
*/
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block,
uint32_t page, const 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) {
uint8_t retval;
const NANDConfig *cfg = nandp->config;
@ -397,8 +387,8 @@ uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block,
*
* @api
*/
void nandReadPageSpare(NANDDriver *nandp, uint32_t block,
uint32_t page, uint8_t *spare, size_t sparelen) {
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];
@ -425,8 +415,8 @@ void nandReadPageSpare(NANDDriver *nandp, uint32_t block,
*
* @api
*/
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block,
uint32_t page, const uint8_t *spare, size_t sparelen) {
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;
@ -453,15 +443,12 @@ uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block,
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
nandWritePageSpare(nandp, block, 0, bb_mark, sizeof(bb_mark));
nandWritePageSpare(nandp, block, 1, bb_mark, sizeof(bb_mark));
if (NULL != nandp->bb_map)
bitmapSet(nandp->bb_map, block);
}
/**
@ -475,9 +462,9 @@ void nandMarkBad(NANDDriver *nandp, uint32_t block) {
*
* @api
*/
uint8_t nandReadBadMark(NANDDriver *nandp,
uint32_t block, uint32_t page) {
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];
}
@ -492,7 +479,7 @@ uint8_t nandReadBadMark(NANDDriver *nandp,
*
* @api
*/
uint8_t nandErase(NANDDriver *nandp, uint32_t block){
uint8_t nandErase(NANDDriver *nandp, uint32_t block) {
uint8_t retVal;
const NANDConfig *cfg = nandp->config;
@ -508,7 +495,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] block block number
@ -519,32 +506,15 @@ uint8_t nandErase(NANDDriver *nandp, uint32_t block){
*
* @api
*/
bool nandIsBad(NANDDriver *nandp, uint32_t block){
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;
if (NULL != nandp->bb_map)
return 1 == bitmapGet(nandp->bb_map, block);
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 */
return read_is_block_bad(nandp, block);
}
#if NAND_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)

158
os/various/bitmap.c Normal file
View File

@ -0,0 +1,158 @@
/*
ChibiOS/HAL - Copyright (C) 2015 Uladzimir Pylinsky aka barthess
Licensed 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.
*/
/**
* @file bitmap.c
* @brief Bit map code.
*
* @addtogroup bitmap
* @{
*/
#include "string.h" /* for memset() */
#include "hal.h"
#include "bitmap.h"
/*===========================================================================*/
/* Module local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Module exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Module local functions. */
/*===========================================================================*/
/**
* @brief Get word number.
*
* @param[in] bit number of the bit
*
* @return Index of the word containing specified bit.
*/
static inline size_t word(size_t bit) {
return bit / (sizeof(bitmap_word_t) * 8);
}
/**
* @brief Get bit position in word.
*
* @param[in] bit number of the bit
*
* @return Position of the specified bit related to word start.
*/
static inline size_t pos_in_word(size_t bit) {
return bit % (sizeof(bitmap_word_t) * 8);
}
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
/**
* @brief Initializes an @p bitmap_t structure.
*
* @param[out] map the @p bitmap_t structure to be initialized
* @param[in] val the value to be written in all bitmap
*/
void bitmapObjectInit(bitmap_t *map, bitmap_word_t val) {
uint8_t pattern;
osalDbgCheck(val == 1 || val == 0);
if (val == 1)
pattern = 0xFF;
else
pattern = 0;
memset(map->array, pattern, map->len*sizeof(bitmap_word_t));
}
/**
* @brief Set single bit in an @p bitmap_t structure.
*
* @param[out] map the @p bitmap_t structure
* @param[in] bit number of the bit to be set
*/
void bitmapSet(bitmap_t *map, size_t bit) {
size_t w = word(bit);
osalDbgCheck(w < map->len);
map->array[w] |= (bitmap_word_t)1 << pos_in_word(bit);
}
/**
* @brief Clear single bit in an @p bitmap_t structure.
*
* @param[out] map the @p bitmap_t structure
* @param[in] bit number of the bit to be cleared
*/
void bitmapClear(bitmap_t *map, size_t bit) {
size_t w = word(bit);
osalDbgCheck(w < map->len);
map->array[w] &= ~((bitmap_word_t)1 << pos_in_word(bit));
}
/**
* @brief Invert single bit in an @p bitmap_t structure.
*
* @param[out] map the @p bitmap_t structure
* @param[in] bit number of the bit to be inverted
*/
void bitmapInvert(bitmap_t *map, size_t bit) {
size_t w = word(bit);
osalDbgCheck(w < map->len);
map->array[w] ^= (bitmap_word_t)1 << pos_in_word(bit);
}
/**
* @brief Get bit value from an @p bitmap_t structure.
*
* @param[in] map the @p bitmap_t structure
* @param[in] bit number of the requested bit
*
* @return Requested bit value.
*/
bitmap_word_t bitmapGet(const bitmap_t *map, size_t bit) {
size_t w = word(bit);
osalDbgCheck(w < map->len);
return (map->array[w] >> pos_in_word(bit)) & 1;
}
/**
* @brief Get total amount of bits in an @p bitmap_t structure.
*
* @param[in] map the @p bitmap_t structure
*
* @return Bit number.
*/
size_t bitmapGetBitsCount(const bitmap_t *map) {
return map->len * sizeof(bitmap_word_t) * 8;
}
/** @} */

77
os/various/bitmap.h Normal file
View File

@ -0,0 +1,77 @@
/*
ChibiOS/HAL - Copyright (C) 2015 Uladzimir Pylinsky aka barthess
Licensed 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.
*/
/**
* @file bitmap.h
* @brief Bit map structures and macros.
*
* @addtogroup bitmap
* @{
*/
#ifndef _BITMAP_H_
#define _BITMAP_H_
/*===========================================================================*/
/* Module constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Module pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Module data structures and types. */
/*===========================================================================*/
typedef unsigned int bitmap_word_t;
/**
* @brief Type of a event timer structure.
*/
typedef struct {
bitmap_word_t *array;
size_t len; /* Array length in _words_ NOT bytes */
} bitmap_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void bitmapObjectInit(bitmap_t *map, bitmap_word_t val);
void bitmapSet(bitmap_t *map, size_t bit);
void bitmapClear(bitmap_t *map, size_t bit);
void bitmapInvert(bitmap_t *map, size_t bit);
bitmap_word_t bitmapGet(const bitmap_t *map, size_t bit);
size_t bitmapGetBitsCount(const bitmap_t *map);
#ifdef __cplusplus
}
#endif
#endif /* _BITMAP_H_ */
/** @} */

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/

View File

@ -105,6 +105,7 @@ CSRC = $(STARTUPSRC) \
$(PLATFORMSRC) \
$(BOARDSRC) \
$(TESTSRC) \
$(CHIBIOS)/community/os/various/bitmap.c \
dma_storm_adc.c \
dma_storm_spi.c \
dma_storm_uart.c \
@ -139,7 +140,7 @@ ASMSRC = $(STARTUPASM) $(PORTASM) $(OSALASM)
INCDIR = $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \
$(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.
*/
#define CH_DBG_ENABLE_TRACE TRUE
#define CH_DBG_ENABLE_TRACE FALSE
/**
* @brief Debug option, stack checks.

View File

@ -1,3 +1,19 @@
/*
ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
Licensed 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 DMA_STORM_H_
#define DMA_STORM_H_

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/

View File

@ -44,6 +44,8 @@
#include "ch.h"
#include "hal.h"
#include "bitmap.h"
#include "dma_storm.h"
#include "string.h"
#include "stdlib.h"
@ -54,6 +56,8 @@
******************************************************************************
*/
#define USE_BAD_MAP TRUE
#define USE_KILL_BLOCK_TEST FALSE
#define FSMCNAND_TIME_SET ((uint32_t) 2) //(8nS)
@ -69,7 +73,7 @@
#define NAND_ROW_WRITE_CYCLES 3
#define NAND_COL_WRITE_CYCLES 2
#define NANF_TEST_START_BLOCK 1200
#define NAND_TEST_START_BLOCK 1200
#define NAND_TEST_END_BLOCK 1220
#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_read_data;
static time_measurement_t tmu_read_spare;
static time_measurement_t tmu_driver_start;
#if NAND_USE_BAD_MAP
static uint32_t badblock_map[NAND_BLOCKS_COUNT / 32];
#if USE_BAD_MAP
#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
/*
*
*/
static const NANDConfig nandcfg = {
&FSMCD1,
//&FSMCD1,
NAND_BLOCKS_COUNT,
NAND_PAGE_DATA_SIZE,
NAND_PAGE_SPARE_SIZE,
NAND_PAGES_PER_BLOCK,
#if NAND_USE_BAD_MAP
badblock_map,
#endif
NAND_ROW_WRITE_CYCLES,
NAND_COL_WRITE_CYCLES,
/* stm32 specific fields */
@ -567,7 +574,14 @@ int main(void) {
#if STM32_NAND_USE_EXT_INT
extStart(&EXTD1, &extcfg);
#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);
@ -586,7 +600,7 @@ int main(void) {
dma_storm_uart_start();
dma_storm_spi_start();
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;
adc_ints = dma_storm_adc_stop();
uart_ints = dma_storm_uart_stop();
@ -611,9 +625,9 @@ int main(void) {
* ensure that NAND code have negligible impact on other subsystems
*/
osalDbgCheck(background_cnt > (BackgroundThdCnt / 4));
osalDbgCheck(abs(adc_ints - adc_idle_ints) < (adc_idle_ints / 20));
osalDbgCheck(abs(adc_ints - adc_idle_ints) < (adc_idle_ints / 20));
osalDbgCheck(abs(uart_ints - uart_idle_ints) < (uart_idle_ints / 20));
osalDbgCheck(abs(spi_ints - spi_idle_ints) < (spi_idle_ints / 10));
osalDbgCheck(abs(spi_ints - spi_idle_ints) < (spi_idle_ints / 10));
/*
* perform ECC calculation test

View File

@ -21,7 +21,7 @@
#define STM32_FSMC_FSMC1_IRQ_PRIORITY 10
#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_PRIORITY 0
#define STM32_NAND_DMA_ERROR_HOOK(nandp) osalSysHalt("DMA failure")

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/

View File

@ -50,14 +50,6 @@
#define NAND_USE_MUTUAL_EXCLUSION TRUE
#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. */
/*===========================================================================*/