Skip to content

Commit

Permalink
Merge pull request #251 from sabdulqadir/feat/expanding_hal_nand_c
Browse files Browse the repository at this point in the history
Expansion to nand flash driver
  • Loading branch information
fpoussin authored Feb 14, 2021
2 parents ba33139 + 34bb526 commit c0b5cfa
Show file tree
Hide file tree
Showing 5 changed files with 373 additions and 79 deletions.
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

0 comments on commit c0b5cfa

Please sign in to comment.