ERROR_CODE GetSectorNumber( unsigned long ulAddr, int *pnSector ) { int nSector = 0; int i; int error_code = 1; unsigned long ulMask; //offset mask unsigned long ulOffset; //offset unsigned long ulStartOff; unsigned long ulEndOff; ulMask = 0x3fffff; ulOffset = ulAddr & ulMask; for(i = 0; i < gNumSectors; i++) { GetSectorStartEnd(&ulStartOff, &ulEndOff, i); if ( (ulOffset >= ulStartOff) && (ulOffset <= ulEndOff) ) { error_code = 0; nSector = i; break; } } // if it is a valid sector, set it if (error_code == 0) *pnSector = nSector; // else it is an invalid sector else return INVALID_SECTOR; // ok return NO_ERR; }
ERROR_CODE EraseBlock( int nBlock, unsigned long ulAddr ) { ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash unsigned long ulSectStart = 0x0; //stores the sector start offset unsigned long ulSectEnd = 0x0; //stores the sector end offset(however we do not use it here) unsigned long ulFlashStartAddr; //flash start address // get flash start address from absolute address // The ulAddr should ideally be pointing to the flash start // address. However we just verify it here again. ulFlashStartAddr = GetFlashStartAddress(ulAddr); // Get the sector start offset // we get the end offset too however we do not actually use it for Erase sector GetSectorStartEnd( &ulSectStart, &ulSectEnd, nBlock ); // send the erase block command to the flash WriteFlash( (ulFlashStartAddr + 0x0AAA), 0xaa ); WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 ); WriteFlash( (ulFlashStartAddr + 0x0AAA), 0x80 ); WriteFlash( (ulFlashStartAddr + 0x0AAA), 0xaa ); WriteFlash( (ulFlashStartAddr + 0x0554), 0x55 ); // the last write has to be at an address in the block WriteFlash( (ulFlashStartAddr + ulSectStart), 0x30 ); // poll until the command has completed ErrorCode = PollToggleBit(ulFlashStartAddr + ulSectStart); // block erase should be complete return ErrorCode; }
unsigned long GetFlashStartAddress( unsigned long ulAddr) { ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash unsigned long ulFlashStartAddr; //flash start address unsigned long ulSectStartAddr; //sector start address unsigned long ulSectEndAddr; //sector end address unsigned long ulMask; //offset mask // get flash start address from absolute address GetSectorStartEnd( &ulSectStartAddr, &ulSectEndAddr, (gNumSectors-1)); ulMask = ~(ulSectEndAddr); ulFlashStartAddr = ulAddr & ulMask; return(ulFlashStartAddr); }
ERROR_CODE EraseBlock( int nBlock, unsigned long ulAddr ) { ERROR_CODE ErrorCode = NO_ERR; //tells us if there was an error erasing flash unsigned long ulSectStart = 0x0; //stores the sector start offset unsigned long ulSectEnd = 0x0; //stores the sector end offset(however we do not use it here) #ifdef LOCK_MAC_ADDR_SECTOR if ( (nBlock < 0) || (nBlock > gNumSectors) ) return INVALID_BLOCK; // we do not allow an erase of the last sector because the // MAC address is stored at this location if ( nBlock == (gNumSectors - 1) ) return NO_ACCESS_SECTOR; #else if ( (nBlock < 0) || (nBlock > gNumSectors) ) return INVALID_BLOCK; #endif // Get the sector start offset // we get the end offset too however we do not actually use it for Erase sector GetSectorStartEnd( &ulSectStart, &ulSectEnd, nBlock ); // send the erase block command to the flash WriteFlash( (ulAddr + 0x0AAA), 0xaa ); WriteFlash( (ulAddr + 0x0554), 0x55 ); WriteFlash( (ulAddr + 0x0AAA), 0x80 ); WriteFlash( (ulAddr + 0x0AAA), 0xaa ); WriteFlash( (ulAddr + 0x0554), 0x55 ); // the last write has to be at an address in the block WriteFlash( (ulAddr + ulSectStart), 0x30 ); // poll until the command has completed ErrorCode = PollToggleBit(ulAddr + ulSectStart); // block erase should be complete return ErrorCode; }
u32 adi_pdd_Control( ADI_DEV_PDD_HANDLE PDDHandle, u32 Command, void *pArg) { ERROR_CODE ErrorCode = NO_ERR; COMMAND_STRUCT *pCmdStruct = (COMMAND_STRUCT *)pArg; // switch on the command switch ( Command ) { // erase all case CNTRL_ERASE_ALL: ErrorCode = EraseFlash(pCmdStruct->SEraseAll.ulFlashStartAddr); break; // erase sector case CNTRL_ERASE_SECT: ErrorCode = EraseBlock( pCmdStruct->SEraseSect.nSectorNum, pCmdStruct->SEraseSect.ulFlashStartAddr ); break; // get manufacturer and device codes case CNTRL_GET_CODES: ErrorCode = GetCodes((int *)pCmdStruct->SGetCodes.pManCode, (int *)pCmdStruct->SGetCodes.pDevCode, (unsigned long)pCmdStruct->SGetCodes.ulFlashStartAddr); break; case CNTRL_GET_DESC: //Filling the contents with data pCmdStruct->SGetDesc.pDesc = pFlashDesc; pCmdStruct->SGetDesc.pFlashCompany = pDeviceCompany; break; // get sector number based on address case CNTRL_GET_SECTNUM: ErrorCode = GetSectorNumber( pCmdStruct->SGetSectNum.ulOffset, (int *)pCmdStruct->SGetSectNum.pSectorNum ); break; // get sector number start and end offset case CNTRL_GET_SECSTARTEND: ErrorCode = GetSectorStartEnd( pCmdStruct->SSectStartEnd.pStartOffset, pCmdStruct->SSectStartEnd.pEndOffset, pCmdStruct->SSectStartEnd.nSectorNum ); break; // get the number of sectors case CNTRL_GETNUM_SECTORS: pCmdStruct->SGetNumSectors.pnNumSectors[0] = gNumSectors; break; // reset case CNTRL_RESET: ErrorCode = ResetFlash(pCmdStruct->SReset.ulFlashStartAddr); break; // turn on dataflow (command required of all device drivers) case ADI_DEV_CMD_SET_DATAFLOW: ErrorCode = NO_ERR; break; case ADI_DEV_CMD_SET_DATAFLOW_METHOD: // Do nothing & simply return back for these commands break; // get peripheral DMA support (command required of all device drivers) case ADI_DEV_CMD_GET_PERIPHERAL_DMA_SUPPORT: (*(u32 *)pArg) = FALSE; // no, this device is not supported by peripheral DMA break; // no command or unknown command do nothing default: // set our error ErrorCode = UNKNOWN_COMMAND; break; } // return return(ErrorCode); }
u32 adi_pdd_Control( ADI_DEV_PDD_HANDLE PDDHandle, u32 Command, void *pArg) { ERROR_CODE ErrorCode = NO_ERR; COMMAND_STRUCT *pCmdStruct = (COMMAND_STRUCT *)pArg; // switch on the command switch ( Command ) { // erase all case CNTRL_ERASE_ALL: ErrorCode = EraseFlash(pCmdStruct->SEraseAll.ulFlashStartAddr); break; // erase sector case CNTRL_ERASE_SECT: ErrorCode = EraseBlock( pCmdStruct->SEraseSect.nSectorNum, pCmdStruct->SEraseSect.ulFlashStartAddr ); break; // get manufacturer and device codes case CNTRL_GET_CODES: ErrorCode = GetCodes((int *)pCmdStruct->SGetCodes.pManCode, (int *)pCmdStruct->SGetCodes.pDevCode, (unsigned long)pCmdStruct->SGetCodes.ulFlashStartAddr); break; //Filling the contents with data case CNTRL_GET_DESC: pCmdStruct->SGetDesc.pTitle = pEzKitTitle; pCmdStruct->SGetDesc.pDesc = pFlashDesc; pCmdStruct->SGetDesc.pFlashCompany = pDeviceCompany; break; // get sector number based on address case CNTRL_GET_SECTNUM: ErrorCode = GetSectorNumber( pCmdStruct->SGetSectNum.ulOffset, (int *)pCmdStruct->SGetSectNum.pSectorNum ); break; // get sector number start and end offset case CNTRL_GET_SECSTARTEND: ErrorCode = GetSectorStartEnd( pCmdStruct->SSectStartEnd.pStartOffset, pCmdStruct->SSectStartEnd.pEndOffset, pCmdStruct->SSectStartEnd.nSectorNum ); break; // get the number of sectors case CNTRL_GETNUM_SECTORS: pCmdStruct->SGetNumSectors.pnNumSectors[0] = NUM_SECTORS; break; // reset case CNTRL_RESET: ErrorCode = ResetFlash(pCmdStruct->SReset.ulFlashStartAddr); break; // no command or unknown command do nothing default: // set our error ErrorCode = UNKNOWN_COMMAND; break; } // return return(ErrorCode); }