Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
/* Copyright (C) 2020 NANDO authors
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3.
*/
#include "parallel_chip_info.h"
#include <stdint.h>
#include <algorithm>
#include <array>
#include <math.h>
typedef struct __attribute__((__packed__))
{
uint8_t setupTime;
uint8_t waitSetupTime;
uint8_t holdSetupTime;
uint8_t hiZSetupTime;
uint8_t clrSetupTime;
uint8_t arSetupTime;
uint8_t rowCycles;
uint8_t colCycles;
uint8_t read1Cmd;
uint8_t read2Cmd;
uint8_t readSpareCmd;
uint8_t readIdCmd;
uint8_t resetCmd;
uint8_t write1Cmd;
uint8_t write2Cmd;
uint8_t erase1Cmd;
uint8_t erase2Cmd;
uint8_t statusCmd;
uint8_t setFeaturesCmd;
uint8_t enableEccAddr;
uint8_t enableEccValue;
uint8_t disableEccValue;
} ParallelChipConf;
ParallelChipInfo::ParallelChipInfo()
{
hal = CHIP_HAL_PARALLEL;
}
ParallelChipInfo::~ParallelChipInfo()
{
}
/* Convert NAND parameters to STM32 FSMC parameters.
* See Application Note AN2784.
*/
void ParallelChipInfo::chipInfoToStmParams(StmParams *stmParams)
{
double setupTime, waitSetupTime, hiZSetupTime, holdSetupTime, arSetupTime,
clrSetupTime;
const double tHCLK = 13.88; /* 1 / 72MHz */
const double tsuD_NOE = 25;
std::array<quint64, 5> setupArr = { params[CHIP_PARAM_T_CS],
params[CHIP_PARAM_T_CLS], params[CHIP_PARAM_T_ALS],
params[CHIP_PARAM_T_CLR], params[CHIP_PARAM_T_AR] };
std::array<quint64, 3> hiZArr = { params[CHIP_PARAM_T_CS],
params[CHIP_PARAM_T_ALS], params[CHIP_PARAM_T_CLS] };
std::array<quint64, 3> holdArr = { params[CHIP_PARAM_T_CH],
params[CHIP_PARAM_T_CLH], params[CHIP_PARAM_T_ALH] };
/* (SET + 1) * tHCLK >= max(tCS, tCLS, tALS, tCLR, tAR) - tWP */
setupTime = *std::max_element(setupArr.begin(), setupArr.end()) -
params[CHIP_PARAM_T_WP];
setupTime = setupTime / tHCLK - 1;
/* K9F2G08U0C requires at least 1 tick */
setupTime = setupTime <= 0 ? 1 : ceil(setupTime);
stmParams->setupTime = static_cast<uint8_t>(setupTime);
/* (WAIT + 1) * tHCLK >= max(tWP, tRP) */
waitSetupTime = std::max(params[CHIP_PARAM_T_WP], params[CHIP_PARAM_T_RP]);
waitSetupTime = waitSetupTime / tHCLK - 1;
waitSetupTime = waitSetupTime <= 0 ? 0 : ceil(waitSetupTime);
stmParams->waitSetupTime = static_cast<uint8_t>(waitSetupTime);
/* (WAIT + 1) * tHCLK >= tREA + tsuD_NOE */
waitSetupTime = params[CHIP_PARAM_T_REA] + tsuD_NOE;
waitSetupTime = waitSetupTime / tHCLK - 1;
waitSetupTime = waitSetupTime <= 0 ? 0 : ceil(waitSetupTime);
if (waitSetupTime > stmParams->waitSetupTime)
stmParams->waitSetupTime = static_cast<uint8_t>(waitSetupTime);
/* (HIZ + 1) * tHCLK >= max(tCH, tALS, tCLS) + (tWP - tDS) */
hiZSetupTime = *std::max_element(hiZArr.begin(), hiZArr.end());
hiZSetupTime += params[CHIP_PARAM_T_WP] - params[CHIP_PARAM_T_DS];
hiZSetupTime = hiZSetupTime / tHCLK - 1;
hiZSetupTime = hiZSetupTime <= 0 ? 0 : ceil(hiZSetupTime);
stmParams->hiZSetupTime = static_cast<uint8_t>(hiZSetupTime);
/* (HOLD + 1) * tHCLK >= max(tCH, tCLH, tALH) */
holdSetupTime =*std::max_element(holdArr.begin(), holdArr.end());
holdSetupTime = holdSetupTime / tHCLK - 1;
/* K9F2G08U0C requires at least 2 tick */
holdSetupTime = holdSetupTime <= 0 ? 2 : ceil(holdSetupTime);
stmParams->holdSetupTime = static_cast<uint8_t>(holdSetupTime);
/* ((WAIT + 1) + (HOLD + 1) + (SET + 1)) * tHCLK >= max(tWC, tRC) */
while (((stmParams->setupTime + 1) + (stmParams->waitSetupTime + 1) +
(stmParams->holdSetupTime + 1)) * tHCLK <
std::max(params[CHIP_PARAM_T_WC], params[CHIP_PARAM_T_RC]))
{
stmParams->setupTime++;
}
/* RM0008 Reference manual
In any case, it turns out 0 */
/* t_ar = (TAR + SET + 4) × THCLK
t_ar / THCLK - 4 - SET = TAR */
arSetupTime = params[CHIP_PARAM_T_AR] / tHCLK - 4 - stmParams->setupTime;
arSetupTime = arSetupTime <= 0 ? 0 : ceil(arSetupTime);
stmParams->arSetupTime = static_cast<uint8_t>(arSetupTime);
/* t_clr = (TCLR + SET + 4) × THCLK
t_clr / THCLK - 4 - SET = TCLR */
clrSetupTime = params[CHIP_PARAM_T_CLR] / tHCLK - 4 - stmParams->setupTime;
clrSetupTime = clrSetupTime <= 0 ? 0 : ceil(clrSetupTime);
stmParams->clrSetupTime = static_cast<uint8_t>(clrSetupTime);
}
const QByteArray &ParallelChipInfo::getHalConf()
{
ParallelChipConf conf;
StmParams stmParams;
chipInfoToStmParams(&stmParams);
conf.setupTime = stmParams.setupTime;
conf.waitSetupTime = stmParams.waitSetupTime;
conf.holdSetupTime = stmParams.holdSetupTime;
conf.hiZSetupTime = stmParams.hiZSetupTime;
conf.clrSetupTime = stmParams.clrSetupTime;
conf.arSetupTime = stmParams.arSetupTime;
conf.rowCycles = static_cast<uint8_t>(params[CHIP_PARAM_ROW_CYCLES]);
conf.colCycles = static_cast<uint8_t>(params[CHIP_PARAM_COL_CYCLES]);
conf.read1Cmd = static_cast<uint8_t>(params[CHIP_PARAM_READ1_CMD]);
conf.read2Cmd = static_cast<uint8_t>(params[CHIP_PARAM_READ2_CMD]);
conf.readSpareCmd = static_cast<uint8_t>(params[CHIP_PARAM_READ_SPARE_CMD]);
conf.readIdCmd = static_cast<uint8_t>(params[CHIP_PARAM_READ_ID_CMD]);
conf.resetCmd = static_cast<uint8_t>(params[CHIP_PARAM_RESET_CMD]);
conf.write1Cmd = static_cast<uint8_t>(params[CHIP_PARAM_WRITE1_CMD]);
conf.write2Cmd = static_cast<uint8_t>(params[CHIP_PARAM_WRITE2_CMD]);
conf.erase1Cmd = static_cast<uint8_t>(params[CHIP_PARAM_ERASE1_CMD]);
conf.erase2Cmd = static_cast<uint8_t>(params[CHIP_PARAM_ERASE2_CMD]);
conf.statusCmd = static_cast<uint8_t>(params[CHIP_PARAM_STATUS_CMD]);
conf.setFeaturesCmd = static_cast<uint8_t>(params[CHIP_PARAM_STATUS_CMD]);
conf.enableEccAddr =
static_cast<uint8_t>(params[CHIP_PARAM_ENABLE_HW_ECC_ADDR]);
conf.enableEccValue =
static_cast<uint8_t>(params[CHIP_PARAM_ENABLE_HW_ECC_VALUE]);
conf.disableEccValue =
static_cast<uint8_t>(params[CHIP_PARAM_DISABLE_HW_ECC_VALUE]);
halConf.clear();
halConf.append(reinterpret_cast<const char *>(&conf), sizeof(conf));
return halConf;
}
quint64 ParallelChipInfo::getParam(uint32_t num)
{
if (num >= CHIP_PARAM_NUM)
return 0;
return params[num];
}
int ParallelChipInfo::setParam(uint32_t num, quint64 value)
{
if (num >= CHIP_PARAM_NUM)
return -1;
params[num] = value;
return 0;
}
4d840b7afThis file is pinned to the selected release. Download the original to open it in your design tool.