Example #1
0
bool onfi_embeddedecc(FAR const struct onfi_pgparam_s *onfi,
                      uintptr_t cmdaddr, uintptr_t addraddr,
                      uintptr_t dataaddr, bool enable)
{
  /* Does the NAND supported the embedded ECC function? */

  if (onfi_have_embeddedecc(onfi))
    {
      /* Yes... enable or disable it */
      /* Perform common setup */

      WRITE_NAND_COMMAND(NAND_CMD_SET_FEATURE, cmdaddr);
      WRITE_NAND_ADDRESS(0x90, addraddr);

      if (enable)
        {
          /* Activate the internal ECC controller */

          WRITE_NAND(0x08, dataaddr);
          WRITE_NAND(0x00, dataaddr);
          WRITE_NAND(0x00, dataaddr);
          WRITE_NAND(0x00, dataaddr);
          setSmcOpEccType(SMC_ECC_INTERNAL);
        }
      else
        {
          /* De-activate the internal ECC controller */

          WRITE_NAND(0x00, dataaddr);
          WRITE_NAND(0x00, dataaddr);
          WRITE_NAND(0x00, dataaddr);
          WRITE_NAND(0x00, dataaddr);
        }

      return true;
    }

  return false;
}
Example #2
0
/**
 * \brief  Applet main entry. This function decodes received command and executes it.
 *
 * \param argc  always 1
 * \param argv  Address of the argument area..
 */
int main(int argc, char **argv)
{
    struct _Mailbox *pMailbox = (struct _Mailbox *) argv;
    uint32_t bufferSize, bufferAddr, memoryOffset, bytesToWrite;
    uint32_t bytesRead = 0;
    uint32_t nbBadBlocks = 0;
    uint32_t nbBlocks = 0;
    /* Temporary buffer used for non block aligned read / write  */
    uint32_t tempBufferAddr;
    uint16_t block, page, offset, i;
    /* Index in source buffer during buffer copy */
    uint32_t offsetInSourceBuff;
    /* Index in destination buffer during buffer copy */
    uint32_t offsetInTargetBuff;
    /* Errors returned by SkipNandFlash functions */
    uint8_t error = 0;
    /* current pmecc parameter header value */
    uint32_t currentPmeccHeaderValue;
    /* Index and value of pmecc command  */
    uint32_t nIndex, nValue;
    /* Number of ECC bits required */
    uint8_t eccBitReq2TT [5] = {2, 4, 8, 12, 24};
    /* Ecc mode to be swtich */
    uint32_t eccMode;
    uint32_t trimPage;
    /* Disable watchdog */
    WDT_Disable( WDT ) ;

    /* ---------------------------------------------------------- */
    /* INIT:                                                      */
    /* ---------------------------------------------------------- */
    if (pMailbox->command == APPLET_CMD_INIT) {
        /* Save communication link type */
        comType = pMailbox->argument.inputInit.comType;

#if (DYN_TRACES == 1)
        dwTraceLevel = pMailbox->argument.inputInit.traceLevel;
#endif
        TRACE_INFO("-- NandFlash SAM-BA applet %s --\n\r", SAM_BA_APPLETS_VERSION);
        TRACE_INFO("-- %s\n\r", BOARD_NAME);
        TRACE_INFO("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
        TRACE_INFO("INIT command\n\r");

        /* Configure SMC for Nandflash accesses (done each time applet is launched because of old ROM codes) */
        TRACE_INFO("BOARD_ConfigureNandFlash\n\r");
        BOARD_ConfigureNandFlash(nfBusWidth);
        Smc_OpConfigure(0);
        /* Device model */
        /* Tries to detect NAND Flash device connected to EBI CS3*/
        if (!NandEbiDetect()) {
            pMailbox->status = APPLET_DEV_UNKNOWN;
            TRACE_INFO("\tDevice Unknown\n\r");
            goto exit;
        }
        memset(&skipBlockNf, 0, sizeof(skipBlockNf));
        NandGetOnfiPageParam (&OnfiPageParameter);
        NandDisableInternalEcc();
        if (SkipBlockNandFlash_Initialize(&skipBlockNf,
                                         0,
                                         cmdBytesAddr,
                                         addrBytesAddr,
                                         dataBytesAddr,
                                         nfCePin,
                                         nfRbPin)) {
            pMailbox->status = APPLET_DEV_UNKNOWN;
            pMailbox->argument.outputInit.bufferSize = 0;
            pMailbox->argument.outputInit.memorySize = 0;
            TRACE_INFO("\tDevice Unknown\n\r");
        }
        else 
        {
            /* Check the data bus width of the NandFlash */
            nfBusWidth = NandFlashModel_GetDataBusWidth((struct NandFlashModel *)&skipBlockNf);
            /* Reconfigure bus width */
            if ( nfBusWidth != 8) {
                BOARD_ConfigureNandFlash(nfBusWidth);
            }
            TRACE_INFO("\tNandflash driver initialized\n\r");
            pMailbox->argument.outputInit.bufferAddress = (uint32_t) &_end;
            /* Get device parameters */
            memSize = NandFlashModel_GetDeviceSizeInBytes(&skipBlockNf.ecc.raw.model);
            blockSize = NandFlashModel_GetBlockSizeInBytes(&skipBlockNf.ecc.raw.model);
            numBlocks = NandFlashModel_GetDeviceSizeInBlocks(&skipBlockNf.ecc.raw.model);
            pageSize = NandFlashModel_GetPageDataSize(&skipBlockNf.ecc.raw.model);
            spareSize = NandFlashModel_GetPageSpareSize(&skipBlockNf.ecc.raw.model);
            numPagesPerBlock = NandFlashModel_GetBlockSizeInPages(&skipBlockNf.ecc.raw.model);

            pMailbox->status = APPLET_SUCCESS;
            pMailbox->argument.outputInit.bufferSize = blockSize;
            pMailbox->argument.outputInit.memorySize = memSize;
            pMailbox->argument.outputInit.pmeccParamHeader = 0;
            TRACE_INFO("\tpageSize : 0x%x blockSize : 0x%x blockNb : 0x%x \n\r",  
                        (unsigned int)pageSize, (unsigned int)blockSize, (unsigned int)numBlocks);
        }
        /* By default, we use pmecc, except MICRON MLC nand with internal ECC controller */
        eccOffset = 2;
        /* By defaut, 2 error bit correction, eccOffset = 2 */
        PMECC_Initialize(&pmeccDesc, 0, eccCorrectability, pageSize, spareSize, eccOffset, 0);
        TRACE_INFO("\tNandflash PMECC initialized\n\r");
        DMAD_Initialize( &dmad, POLLING_MODE ); 
        if ( NandFlashConfigureDmaChannels( &dmad )) {
            pMailbox->status =APPLET_DEV_UNKNOWN;
            goto exit;
        }
        /* Initialize current pmecc parameter header, This 32-bit word is configured below */
        currentPmeccHeader.usePmecc = 1;
        currentPmeccHeader.nbSectorPerPage = pmeccDesc.pageSize >> 8;
        currentPmeccHeader.spareSize = spareSize;
        currentPmeccHeader.eccBitReq = pmeccDesc.errBitNbrCapability;
        currentPmeccHeader.sectorSize = pmeccDesc.sectorSize;
        currentPmeccHeader.eccOffset = pmeccDesc.eccStartAddr;
        currentPmeccHeader.reserved = 0;
        currentPmeccHeader.key = 12;
        memcpy(&backupPmeccHeader, &currentPmeccHeader, sizeof(nfParamHeader_t));
        memcpy(&currentPmeccHeaderValue, &currentPmeccHeader, sizeof(nfParamHeader_t));
        pMailbox->argument.outputInit.pmeccParamHeader = currentPmeccHeaderValue;
        /* The Boot Program reads the first page without ECC check, to determine if the NAND parameter 
           header is present. The header is made of 52 times the same 32-bit word (for redundancy
           reasons) which must contain NAND and PMECC parameters used to correctly perform the read of the rest 
           of the data in the NAND. */
        for (i = 0; i< 52; i++) memcpy(&bootNfParamHeader[i], &currentPmeccHeader, sizeof(nfParamHeader_t));
        setSmcOpEccType(SMC_ECC_PMECC);
        pMailbox->status = APPLET_SUCCESS;
    }