Exemplo n.º 1
0
// See flash.h for documentation of this function.
status_t flash_verify_erase(flash_driver_t * driver, uint32_t start, uint32_t lengthInBytes, flash_margin_value_t margin)
{
    // Check arguments.
    status_t returnCode = flash_check_range(driver, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT);
    if (returnCode)
    {
        return returnCode;
    }

    uint32_t blockSize = driver->PFlashTotalSize / driver->PFlashBlockCount;
    uint32_t nextBlockStartAddress = ALIGN_UP(start, blockSize);
    if (nextBlockStartAddress == start)
    {
        nextBlockStartAddress += blockSize;
    }


    uint32_t remainingBytes = lengthInBytes;

    while (remainingBytes)
    {
        uint32_t verifyLength = nextBlockStartAddress - start;
        if (verifyLength > remainingBytes)
        {
            verifyLength = remainingBytes;
        }

        uint32_t numberOfPhrases = verifyLength / FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT;

        // Fill in verify section command parameters.
        kFCCOBx[0] = start;
        FTFx_FCCOBx_WR(FTFx, 0, FTFx_VERIFY_SECTION);
        FTFx_FCCOBx_WR(FTFx, 4, numberOfPhrases >> 8);
        FTFx_FCCOBx_WR(FTFx, 5, numberOfPhrases & 0xFF);
        FTFx_FCCOBx_WR(FTFx, 6, margin);

        // calling flash command sequence function to execute the command
        returnCode = flash_command_sequence();
        if (returnCode)
        {
            return returnCode;
        }

        remainingBytes -= verifyLength;
        start += verifyLength;
        nextBlockStartAddress += blockSize;
    }

    return kStatus_Success;
}
Exemplo n.º 2
0
// See flash.h for documentation of this function.
status_t flash_erase(flash_driver_t * driver, uint32_t start, uint32_t lengthInBytes)
{
    // Check the supplied address range.
    status_t returnCode = flash_check_range(driver, start, lengthInBytes);
    if (returnCode)
    {
        return returnCode;
    }

    uint32_t endAddress;      // storing end address
    uint32_t numberOfSectors;  // number of sectors calculated by endAddress

    // calculating Flash end address
    endAddress = start + lengthInBytes - 1;

    // re-calculate the endAddress and align it to the start of the next sector
    // which will be used in the comparison below
    if (endAddress % FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE)
    {
        numberOfSectors = endAddress / FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE + 1;
        endAddress = numberOfSectors * FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE - 1;
    }

    // the start address will increment to the next sector address
    // until it reaches the endAdddress
    while (start <= endAddress)
    {
        // preparing passing parameter to erase a flash block
        kFCCOBx[0] = start;
        HW_FTFx_FCCOBx_WR(0, FTFx_ERASE_SECTOR);

        // calling flash command sequence function to execute the command
        returnCode = flash_command_sequence();

        // checking the success of command execution
        if (kStatus_Success != returnCode)
        {
            break;
        }
        else
        {
            // Increment to the next sector
            start += FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE;
        }
    }

    return(returnCode);
}
Exemplo n.º 3
0
// See flash.h for documentation of this function.
status_t flash_program_section(flash_driver_t * driver, uint32_t start, uint32_t * src, uint32_t lengthInBytes)
{
#if (!FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD)
    {
        return kStatus_FlashCommandNotSupported;
    }

#else
    if (src == NULL)
    {
        return kStatus_InvalidArgument;
    }

    // Check the supplied address range.
    status_t returnCode = flash_check_range(driver, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT);
    if (returnCode)
    {
        return returnCode;
    }

#if FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
    // Switch function of FlexRAM if needed
    bool needSwitchFlexRamMode = false;
    if (!(FTFx->FCNFG & BM_FTFx_FCNFG_RAMRDY))
    {
        needSwitchFlexRamMode = true;

        returnCode = flash_set_flexram_function(driver, kFlash_FlexRAM_Available_As_RAM);
        if (returnCode != kStatus_Success)
        {
            return returnCode;
        }
    }
#endif // FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD

    while(lengthInBytes > 0)
    {
        // Make sure the write operation doesn't span two sectors
        uint32_t endAddressOfCurrentSector = ALIGN_UP(start, driver->PFlashSectorSize);
        uint32_t lengthTobeProgrammedOfCurrentSector;
        if (lengthInBytes + start > endAddressOfCurrentSector)
        {
            lengthTobeProgrammedOfCurrentSector = endAddressOfCurrentSector - start;
        }
        else
        {
            lengthTobeProgrammedOfCurrentSector = lengthInBytes;
        }

        uint32_t currentOffset = 0;
        // Program Current Sector
        while(lengthTobeProgrammedOfCurrentSector > 0)
        {
            // Make sure the program size doesn't exceeds Accelearating RAM size
            uint32_t programSizeCurrentPass;
            if(lengthTobeProgrammedOfCurrentSector > kFlash_AccelerateRam_Size)
            {
                programSizeCurrentPass = kFlash_AccelerateRam_Size;
            }
            else
            {
                programSizeCurrentPass = lengthTobeProgrammedOfCurrentSector;
            }

            // Copy data to FlexRAM
            memcpy((void*)FSL_FEATURE_FLASH_FLEX_RAM_START_ADDRESS,
                   (void*)(start + currentOffset), programSizeCurrentPass);
            // Set start address of the data to be programmed
            kFCCOBx[0] = start + currentOffset;
            // Set program size in terms of 128bits
            kFCCOBx[1] = programSizeCurrentPass / FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT;
            // Set FTFx Command to PSEC
            HW_FTFx_FCCOBx_WR(FTFx_BASE, 0, FTFx_PROGRAM_SECTION);
            // Peform command sequence
            returnCode = flash_command_sequence();

            // calling flash callback function if it is available
            if (driver->PFlashCallback)
            {
                driver->PFlashCallback();
            }

            if (returnCode != kStatus_Success)
            {
                break;
            }

            lengthTobeProgrammedOfCurrentSector -= programSizeCurrentPass;
            currentOffset += programSizeCurrentPass;
        }

        if (returnCode != kStatus_Success)
        {
            break;
        }

        start += currentOffset;
        lengthInBytes -= currentOffset;
    }

#if FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD
    // Restore function of FlexRAM if needed.
    if (needSwitchFlexRamMode)
    {
        returnCode = flash_set_flexram_function(driver, kFlash_FlexRAM_Available_For_EEPROM);
    }
#endif // FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD

    return returnCode;

#endif // FSL_FEATURE_FLASH_HAS_PROGRAM_SECTION_CMD
}
Exemplo n.º 4
0
// See flash.h for documentation of this function.
status_t flash_is_execute_only(flash_driver_t * driver, uint32_t start, uint32_t lengthInBytes,
                            flash_execute_only_access_state_t * access_state)
{
    if (access_state == NULL)
    {
        return kStatus_InvalidArgument;
    }

    // Check the supplied address range.
    status_t returnCode = flash_check_range(driver, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE);
    if (returnCode)
    {
        return returnCode;
    }

#if !FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL
    *access_state = kFlashAccess_UnLimited;
#else
    uint32_t executeOnlySegmentCounter = 0;

    // calculating end address
    uint32_t endAddress = start + lengthInBytes;

    // Aligning start address and end address
    uint32_t alignedStartAddress = ALIGN_DOWN(start, driver->PFlashAccessSegmentSize);
    uint32_t alignedEndAddress = ALIGN_UP(endAddress, driver->PFlashAccessSegmentSize);

    uint32_t segmentIndex = 0;
    uint32_t maxSupportedExecuteOnlySegmentCount = (alignedEndAddress - alignedStartAddress) / driver->PFlashAccessSegmentSize;

    while (start < endAddress)
    {
        segmentIndex = start / driver->PFlashAccessSegmentSize;

        uint32_t xacc;
        if ( segmentIndex < 32)
        {
            xacc = *(uint32_t*)&FTFx->XACCL3;
        }
        else if (segmentIndex < driver->PFlashAccessSegmentCount)
        {
            xacc = *(uint32_t*)&FTFx->XACCH3;
            segmentIndex -= 32;
        }
        else
        {
            break;
        }

        // Determine if this address range is in a execute-only protection flash segment.
        if ( (~xacc) & (1 << segmentIndex))
        {
             executeOnlySegmentCounter ++;
        }

        start += driver->PFlashAccessSegmentSize;
    }

    if (executeOnlySegmentCounter < 1)
    {
        *access_state = kFlashAccess_UnLimited;
    }
    else if(executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount)
    {
        *access_state = kFlashAccess_Mixed;
    }
    else
    {
        *access_state = kFlashAccess_ExecuteOnly;
    }

#endif // FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL

  return(returnCode);
}
Exemplo n.º 5
0
// See flash.h for documentation of this function.
status_t flash_verify_program(flash_driver_t * driver,
                              uint32_t start,
                              uint32_t lengthInBytes,
                              const uint8_t * expectedData,
                              flash_margin_value_t margin,
                              uint32_t * failedAddress,
                              uint8_t * failedData)
{
    if (expectedData == NULL)
    {
        return kStatus_InvalidArgument;
    }

    status_t returnCode = flash_check_range(driver, start, lengthInBytes, FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT);
    if (returnCode)
    {
        return returnCode;
    }

    while (lengthInBytes)
    {
        // preparing passing parameter to program check the flash block
        kFCCOBx[0] = start;
        FTFx_WR_FCCOBx(FTFx, 0, FTFx_PROGRAM_CHECK);
        FTFx_WR_FCCOBx(FTFx, 4, margin);
        kFCCOBx[2] = *(uint32_t *)expectedData;

        // calling flash command sequence function to execute the command
        returnCode = flash_command_sequence();

        // checking for the success of command execution
        if (kStatus_Success != returnCode)
        {
            if (failedAddress)
            {
                *failedAddress  =  start;
            }
            if (failedData)
            {
                *(uint32_t *)failedData = 0;
            }

        // Read fail returned data: if K70, Nevis2, L1PT, L2K are selected
        //! @todo Use a feature macro to determine whether this is supported.
// #if ((FTFx_KX_512K_512K_16K_4K_4K == FLASH_DERIVATIVE) || (FTFx_KX_1024K_0K_16K_4K_0K == FLASH_DERIVATIVE)\
//         ||(FTFx_NX_256K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_128K_32K_2K_2K_1K == FLASH_DERIVATIVE)\
//         ||(FTFx_NX_96K_32K_2K_2K_1K == FLASH_DERIVATIVE)||(FTFx_NX_64K_32K_2K_2K_1K == FLASH_DERIVATIVE)\
//         ||(FTFx_LX_128K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_96K_0K_0K_1K_0K == FLASH_DERIVATIVE)\
//         ||(FTFx_LX_64K_0K_0K_1K_0K == FLASH_DERIVATIVE)||(FTFx_LX_32K_0K_0K_1K_0K == FLASH_DERIVATIVE)\
//         ||(FTFx_LX_8K_0K_0K_1K_0K == FLASH_DERIVATIVE))
//                 *failedData     = 0x0;
//                 *(failedData+1) = 0x0;
//                 *(failedData+2) = 0x0;
//                 *(failedData+3) = 0x0;
// #else //other derivative
// #if (ENDIANNESS == BIG_ENDIAN)  // Big Endian
//                 *(failedData)   = FTFA->FCCOB4;
//                 *(failedData+1) = FTFA->FCCOB5;
//                 *(failedData+2) = FTFA->FCCOB6;
//                 *(failedData+3) = FTFA->FCCOB7;
// #else // Little Endian
//                 *(failedData+3) = FTFA->FCCOB4;
//                 *(failedData+2) = FTFA->FCCOB5;
//                 *(failedData+1) = FTFA->FCCOB6;
//                 *(failedData)   = FTFA->FCCOB7;
// #endif //of ENDIANNESS
// #endif // of FLASH_DERIVATIVE

            break;
        }

        lengthInBytes -= FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT;
        expectedData += FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT;
        start += FSL_FEATURE_FLASH_PFLASH_CHECK_CMD_ADDRESS_ALIGMENT;
    }

    return(returnCode);
}