Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expansion to nand flash driver #251

Merged
merged 1 commit into from
Feb 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion os/hal/include/hal_fsmc.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
*/
#if (defined(STM32F427xx) || defined(STM32F437xx) || \
defined(STM32F429xx) || defined(STM32F439xx) || \
defined(STM32F722xx) || defined(STM32F723xx) || \
defined(STM32F732xx) || defined(STM32F733xx) || \
defined(STM32F745xx) || defined(STM32F746xx) || \
defined(STM32F756xx) || defined(STM32F767xx) || \
defined(STM32F769xx) || defined(STM32F777xx) || \
Expand Down Expand Up @@ -321,7 +323,7 @@ struct FSMCDriver {
#if STM32_NAND_USE_NAND1
FSMC_NAND_TypeDef *nand1;
#endif
#if STM32_NAND_USE_NAND1
#if STM32_NAND_USE_NAND2
FSMC_NAND_TypeDef *nand2;
#endif
#endif
Expand Down
32 changes: 22 additions & 10 deletions os/hal/include/hal_nand.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,34 @@ extern "C" {
void nandObjectInit(NANDDriver *nandp);
void nandStart(NANDDriver *nandp, const NANDConfig *config, bitmap_t *bb_map);
void nandStop(NANDDriver *nandp);
uint8_t nandErase(NANDDriver *nandp, uint32_t block);
void nandReadPageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t nandErase(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block);
void nandReadPageWhole(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
void *data, size_t datalen);
void nandReadPageData(NANDDriver *nandp, uint32_t block, uint32_t page,
void nandReadPageData(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
void *data, size_t datalen, uint32_t *ecc);
void nandReadPageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
void nandReadPageSpare(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
void *spare, size_t sparelen);
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t nandWritePageWhole(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
const void *data, size_t datalen);
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t nandWritePageData(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
const void *data, size_t datalen, uint32_t *ecc);
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t block, uint32_t page,
uint8_t nandWritePageSpare(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page,
const void *spare, size_t sparelen);
uint16_t nandReadBadMark(NANDDriver *nandp, uint32_t block, uint32_t page);
void nandMarkBad(NANDDriver *nandp, uint32_t block);
bool nandIsBad(NANDDriver *nandp, uint32_t block);
uint16_t nandReadBadMark(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page);
void nandMarkBad(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block);
bool nandIsBad(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, uint32_t block, uint32_t page);
bool readIsBlockBad(NANDDriver *nandp, uint32_t die, uint32_t logun,
uint32_t plane, size_t block);
#if NAND_USE_MUTUAL_EXCLUSION
void nandAcquireBus(NANDDriver *nandp);
void nandReleaseBus(NANDDriver *nandp);
Expand Down
52 changes: 43 additions & 9 deletions os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,11 @@ void nand_lld_init(void) {
NANDD1.rxdata = NULL;
NANDD1.datalen = 0;
NANDD1.thread = NULL;
NANDD1.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM);
NANDD1.dma = NULL;
NANDD1.nand = FSMCD1.nand1;
NANDD1.map_data = (void *)FSMC_Bank2_MAP_COMMON_DATA;
NANDD1.map_cmd = (uint16_t *)FSMC_Bank2_MAP_COMMON_CMD;
NANDD1.map_addr = (uint16_t *)FSMC_Bank2_MAP_COMMON_ADDR;
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_NAND1 */

Expand All @@ -304,11 +304,11 @@ void nand_lld_init(void) {
NANDD2.rxdata = NULL;
NANDD2.datalen = 0;
NANDD2.thread = NULL;
NANDD2.dma = STM32_DMA_STREAM(STM32_NAND_DMA_STREAM);
NANDD2.dma = NULL;
NANDD2.nand = FSMCD1.nand2;
NANDD2.map_data = (void *)FSMC_Bank3_MAP_COMMON_DATA;
NANDD2.map_cmd = (uint16_t *)FSMC_Bank3_MAP_COMMON_CMD;
NANDD2.map_addr = (uint16_t *)FSMC_Bank3_MAP_COMMON_ADDR;
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_NAND2 */
}
Expand All @@ -322,19 +322,18 @@ void nand_lld_init(void) {
*/
void nand_lld_start(NANDDriver *nandp) {

bool b;
uint32_t dmasize;
uint32_t pcr_bus_width;

if (FSMCD1.state == FSMC_STOP)
fsmcStart(&FSMCD1);

if (nandp->state == NAND_STOP) {
b = dmaStreamAlloc(nandp->dma,
nandp->dma = dmaStreamAlloc(STM32_NAND_DMA_STREAM,
STM32_EMC_FSMC1_IRQ_PRIORITY,
(stm32_dmaisr_t)nand_lld_serve_transfer_end_irq,
(void *)nandp);
osalDbgAssert(!b, "stream already allocated");
osalDbgAssert(nandp->dma != NULL, "stream already allocated");

#if AHB_TRANSACTION_WIDTH == 4
dmasize = STM32_DMA_CR_PSIZE_WORD | STM32_DMA_CR_MSIZE_WORD;
Expand Down Expand Up @@ -409,9 +408,12 @@ void nand_lld_read_data(NANDDriver *nandp, uint16_t *data, size_t datalen,

set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_READ0);
__DSB();
nand_lld_write_addr(nandp, addr, addrlen);
__DSB();
osalSysLock();
nand_lld_write_cmd(nandp, NAND_CMD_READ0_CONFIRM);
__DSB();
set_8bit_bus(nandp);

/* Here NAND asserts busy signal and starts transferring from memory
Expand Down Expand Up @@ -459,8 +461,10 @@ uint8_t nand_lld_write_data(NANDDriver *nandp, const uint16_t *data,

set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_WRITE);
__DSB();
osalSysLock();
nand_lld_write_addr(nandp, addr, addrlen);
__DSB();
set_8bit_bus(nandp);

/* Now start DMA transfer to NAND buffer and put thread in sleep state.
Expand Down Expand Up @@ -526,9 +530,12 @@ uint8_t nand_lld_erase(NANDDriver *nandp, uint8_t *addr, size_t addrlen) {

set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_ERASE);
__DSB();
nand_lld_write_addr(nandp, addr, addrlen);
__DSB();
osalSysLock();
nand_lld_write_cmd(nandp, NAND_CMD_ERASE_CONFIRM);
__DSB();
set_8bit_bus(nandp);

nand_lld_suspend_thread(nandp);
Expand Down Expand Up @@ -580,12 +587,39 @@ uint8_t nand_lld_read_status(NANDDriver *nandp) {

set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_STATUS);
__DSB();
set_8bit_bus(nandp);
status = nandp->map_data[0];

return status & 0xFF;
}

/**
* @brief Read ID of the nand flash
*
* @param[in] nandp pointer to the @p NANDDriver object
*
* @return 4 bytes ID of the nandflash
*
* @notapi
*/
uint32_t nand_lld_read_id(NANDDriver *nandp) {

uint8_t addr;
uint32_t data;

//set_16bit_bus(nandp);
nand_lld_write_cmd(nandp, NAND_CMD_READID);
/* Address sent to read ID based on ONFI code */
addr = 0x20;
nand_lld_write_addr(nandp, &addr, 1);
//set_8bit_bus(nandp);
__DSB();
data = *(uint32_t *)(&nandp->map_data[0]);

return data;
}

#endif /* HAL_USE_NAND */

/** @} */
Expand Down
19 changes: 16 additions & 3 deletions os/hal/ports/STM32/LLD/FSMCv1/hal_nand_lld.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,18 @@ typedef void (*nandisrhandler_t)(NANDDriver *nandp);
* @note It could be empty on some architectures.
*/
typedef struct {
/**
* @brief Number of dies in NAND device.
*/
uint32_t dies;
/**
* @brief Number of logical units in NAND device.
*/
uint32_t loguns;
/**
* @brief Number of planes in NAND device.
*/
uint32_t planes;
/**
* @brief Number of erase blocks in NAND device.
*/
Expand Down Expand Up @@ -232,15 +244,15 @@ struct NANDDriver {
/**
* @brief Memory mapping for data.
*/
uint16_t *map_data;
uint8_t *map_data;
/**
* @brief Memory mapping for commands.
*/
uint16_t *map_cmd;
uint8_t *map_cmd;
/**
* @brief Memory mapping for addresses.
*/
uint16_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.
Expand Down Expand Up @@ -279,6 +291,7 @@ extern "C" {
size_t datalen, uint8_t *addr, size_t addrlen, uint32_t *ecc);
uint8_t nand_lld_read_status(NANDDriver *nandp);
void nand_lld_reset(NANDDriver *nandp);
uint32_t nand_lld_read_id(NANDDriver *nandp);
#ifdef __cplusplus
}
#endif
Expand Down
Loading