inline void NANDController::issueCommandToBank(int bank) { setRegister(BSP_CMD(bank), curFCPCommand.cmd); setRegister(BSP_OPTION(bank), curFCPCommand.option); setRegister(BSP_DMA_ADDR(bank), curFCPCommand.dma_addr); setRegister(BSP_DMA_CNT(bank), curFCPCommand.dma_cnt); setRegister(BSP_COL(bank), curFCPCommand.col); setRegister(BSP_ROW_L(bank), curFCPCommand.row[curFCPCommand.bank][0]); setRegister(BSP_ROW_H(bank), curFCPCommand.row[curFCPCommand.bank][1]); setRegister(BSP_DST_COL(bank), curFCPCommand.dst_col); setRegister(BSP_DST_ROW_L(bank), curFCPCommand.dst_row[0]); setRegister(BSP_DST_ROW_H(bank), curFCPCommand.dst_row[1]); setRegister(BSP_CMD_ID(bank), curFCPCommand.cmd_id); }
// BSP interrupt service routine void ftl_isr(void) { UINT32 bank; UINT32 bsp_intr_flag; uart_print("BSP interrupt occured..."); // interrupt pending clear (ICU) SETREG(APB_INT_STS, INTR_FLASH); for (bank = 0; bank < NUM_BANKS; bank++) { while (BSP_FSM(bank) != BANK_IDLE); // get interrupt flag from BSP bsp_intr_flag = BSP_INTR(bank); if (bsp_intr_flag == 0) { continue; } UINT32 fc = GETREG(BSP_CMD(bank)); // BSP clear CLR_BSP_INTR(bank, bsp_intr_flag); // interrupt handling if (bsp_intr_flag & FIRQ_DATA_CORRUPT) { uart_printf("BSP interrupt at bank: 0x%x", bank); uart_print("FIRQ_DATA_CORRUPT occured..."); } if (bsp_intr_flag & (FIRQ_BADBLK_H | FIRQ_BADBLK_L)) { uart_printf("BSP interrupt at bank: 0x%x", bank); if (fc == FC_COL_ROW_IN_PROG || fc == FC_IN_PROG || fc == FC_PROG) { uart_print("find runtime bad block when block program..."); } else { uart_printf("find runtime bad block when block erase...vblock #: %d", GETREG(BSP_ROW_H(bank)) / PAGES_PER_BLK); ASSERT(fc == FC_ERASE); } } } }
void NANDController::outputLogicBankFSM(int bank) { uint32_t r_data = 0; uint32_t *index = &(curIdx[bank]); signal_t signals; uint8_t w_data_l; uint8_t w_data_h; //Default outputs tmp_flash_sout[bank] = 34; //CEn = disable tmp_flash_dout[bank] = 0; switch(getRegister(BSP_FSM(bank))) { case BS_IDLE: //do nothing. break; //////////////////////////////Read Status////////////////////////////// case BS_RS_CMD: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_READ_STATE; break; case BS_RS_DATA: r_data = flash_din_SSlave[bank]; printf( "Read data: 0x%x\n", r_data); break; //////////////////////////////Read////////////////////////////// case BS_READ_CMD_1: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_READ_1; break; case BS_READ_COL_1: //two column addresses are zero. case BS_READ_COL_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = 0; //fix break; case BS_READ_ROW_1: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_L(bank)); break; case BS_READ_ROW_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_H(bank)); break; case BS_READ_CMD_2: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_READ_2; break; case BS_READ_WAIT: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); break; case BS_READ_DATA: //1024 iteration: using curReadIdx signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = ENABLEn; signals.WPn = DISABLEn; //fix if(flash_inputSignal_active[bank]) { //read data r_data = flash_din_SSlave[bank]; //16bit i/o buffers[bank][(*index)] = (uint8_t)(r_data & 0x00FF); buffers[bank][(*index)+1] = (uint8_t)((r_data & 0xFF00) >> 8); //if(p_enableDbgMsg) printf( "[Bank#%d] Read data: 0x%X, index: %d\n", bank, r_data, *index); (*index) += 2; } else { flash_inputSignal_active[bank] = true; } tmp_flash_sout[bank] = encodingSignals(signals); //printf( "[Drive to bank#%d] sout(%d)", bank, encoded_signal); break; case BS_READ_DMA: if(runDMA(bank, 1)) { dma_done[bank] = true; } break; case BS_READ_INC_BM: bm_read_inc = 1; break; //////////////////////////////Write////////////////////////////// case BS_WRITE_DMA: if(runDMA(bank, 0)) { dma_done[bank] = true; } break; case BS_WRITE_CMD_1: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_WRITE_1; break; case BS_WRITE_COL_1: case BS_WRITE_COL_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_COL(bank)); //fix break; case BS_WRITE_ROW_1: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_L(bank)); break; case BS_WRITE_ROW_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_H(bank)); break; case BS_WRITE_DATA: //1024 iteration: using curWriteIdx signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix w_data_l = buffers[bank][(*index)]; //need implement w_data_h = (buffers[bank][(*index)+1]); //if(p_enableDbgMsg) printf( "[Bank#%d] Write data: 0x%X, index: %d\n", bank, ((w_data_h << 8)|w_data_l), *index); (*index)+=2; tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = ((w_data_h << 8)|w_data_l); break; case BS_WRITE_CMD_2: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_WRITE_2; break; case BS_WRITE_WAIT: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); break; case BS_WRITE_INC_BM: bm_write_inc = 1; break; //////////////////////////////Copy-Back////////////////////////////// case BS_CB_CMD_1: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_CP_1; break; case BS_CB_COL_1: case BS_CB_COL_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_COL(bank)); break; case BS_CB_ROW_1: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_L(bank)); break; case BS_CB_ROW_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_H(bank)); break; case BS_CB_CMD_2: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_CP_2; break; case BS_CB_WAIT_1: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); break; case BS_CB_CMD_3: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_CP_3; break; case BS_CB_COL_3: case BS_CB_COL_4: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_DST_COL(bank)); break; case BS_CB_ROW_3: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_DST_ROW_L(bank)); break; case BS_CB_ROW_4: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_DST_ROW_H(bank)); break; case BS_CB_CMD_4: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_CP_4; break; case BS_CB_WAIT_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); break; //////////////////////////////Erase////////////////////////////// case BS_ERASE_CMD_1: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_ERASE_1; break; case BS_ERASE_ROW_1: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_L(bank)); break; case BS_ERASE_ROW_2: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = ENABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = getRegister(BSP_ROW_H(bank)); break; case BS_ERASE_CMD_2: signals.CLE = ENABLE; signals.CEn = ENABLEn; signals.WEn = ENABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); tmp_flash_dout[bank] = FCMD_ERASE_2; break; case BS_ERASE_WAIT: signals.CLE = DISABLE; signals.CEn = ENABLEn; signals.WEn = DISABLEn; signals.ALE = DISABLE; signals.REn = DISABLEn; signals.WPn = DISABLEn; //fix tmp_flash_sout[bank] = encodingSignals(signals); break; //////////////////////////////Error////////////////////////////// default: ; }