/****************************************************************************** * * Title : flashUtility.c * Version 0.0 * * Description: flashUtility routines. * Related files: * * Author: Lukas Tomasek, tomasekl@fzu.cz * ******************************************************************************/ /****************************************************************************** * Header files * ******************************************************************************/ #include #include #include "flashUtility.h" #include "vmeAddressMap.h" #include "errorHandler.h" #include "vmeHpiUtility.h" #include "hostUtility.h" #include "threadUtility.h" #include "uirUtility.h" #include "globalDefinitions.h" #include "fpgaUir.h" #define I_AM_MASTER_DSP #undef IDREGS_BASE #include "memoryPartitions.h" //dspf: BOOT_ROM_BASE => use memory map. #undef I_AM_MASTER_DSP /****************************************************************************** * Definitions * ******************************************************************************/ #define READ_HANDSHAKE_BIT 0 #define WRITE_COMMAND_HANDSHAKE_BIT 1 #define WRITE_DATA_HANDSHAKE_BIT 2 /****************************************************************************** * Static Function Declarations * ******************************************************************************/ static ERROR_ID commonEraseCommands(unsigned char slotNumber, UINT32 flashBaseAddr); static ERROR_ID commonEraseCommandsHpi(unsigned char slotNumber, UINT32 flashBaseAddr); static ERROR_ID vmeWriteElementFlash(unsigned char slotNumber, UINT8 value, UINT32 address, int handshakeBit); static ERROR_ID returnBaseFpgaFlashAddress(UINT32 flashAddress, UINT32 *baseAddress); /****************************************************************************** * Global functions * ******************************************************************************/ /*============================================================================= * chipErase() *============================================================================= * * Fpga flashes * */ ERROR_ID chipErase(unsigned char slotNumber, unsigned int flashBaseAddr, int newFlashLoc){ ERROR_ID errorId; UINT32 fpgaStatusReg4; /* commands 1 to 5 */ errorId= commonEraseCommands(slotNumber, flashBaseAddr); ERROR_CHECK(errorId, commonEraseCommands()); if(errorId != SUCCESS){ return(errorId); } /* 6th command */ errorId= vmeWriteElementFlash(slotNumber, 0x10 , flashBaseAddr+0x5555, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElement()); if(errorId != SUCCESS){ return(errorId); } /* * Wait for operation completed */ if (newFlashLoc) { while(1) { /* poll BUSY */ errorId= RWvmeBlock(READ, BASE_ADDRESS(slotNumber)+FPGA_STATUS_4_REL_ADDR, &fpgaStatusReg4, 1, sizeof(UINT32), VME_ADDR_AUTOINCREMENT, BLOCK_ACCESS, 0); ERROR_CHECK(errorId, RWvmeBlock(READ)); if(errorId != SUCCESS) { break; } if(READ_BIT(fpgaStatusReg4, 3)==0) break; } } else{ Sleep(CHIP_ERASE_TIME_ms); } return(SUCCESS); } /*============================================================================= * chipEraseHpi() *============================================================================= * * MDSP flash * */ ERROR_ID chipEraseHpi(unsigned char slotNumber){ ERROR_ID errorId; unsigned int value; /* commands 1 to 5 */ errorId=commonEraseCommandsHpi(slotNumber, MDSP_FLASH_BOTTOM_REL_ADDR); ERROR_CHECK(errorId, commonEraseCommands); if(errorId!=SUCCESS){ return(errorId); } /* 6th command */ value=0x10; errorId=RWmaster(WRITE, slotNumber, MDSP_FLASH_BOTTOM_REL_ADDR+(0x5555<<2), &value, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } /* * Wait for operation completed */ Sleep(CHIP_ERASE_TIME_ms); return(SUCCESS); } /*============================================================================= * sectorErase() *============================================================================= * * Fpga flashes * */ ERROR_ID sectorErase(unsigned char slotNumber, unsigned int sectorBaseAddr, int newFlashLoc){ ERROR_ID errorId; UINT32 flashBaseAddr; UINT32 fpgaStatusReg4; if (newFlashLoc) { flashBaseAddr= FPGA_FLASH_REL_ADDR_revE; } else { errorId= returnBaseFpgaFlashAddress(sectorBaseAddr, &flashBaseAddr); ERROR_CHECK(errorId, returnBaseFpgaFlashAddress()); if(errorId != SUCCESS){ return(errorId); } } /* commands 1 to 5 */ errorId= commonEraseCommands(slotNumber, flashBaseAddr); ERROR_CHECK(errorId, commonEraseCommands()); if(errorId != SUCCESS){ return(errorId); } /* set write bit */ errorId= vmeWriteElementFlash(slotNumber, 0x30, sectorBaseAddr, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElement()); if(errorId != SUCCESS){ return(errorId); } /* * Wait for operation completed */ if(newFlashLoc) { while(1){ /* poll BUSY */ errorId= RWvmeBlock(READ, BASE_ADDRESS(slotNumber)+FPGA_STATUS_4_REL_ADDR, &fpgaStatusReg4, 1, sizeof(UINT32), VME_ADDR_AUTOINCREMENT, BLOCK_ACCESS, 0); ERROR_CHECK(errorId, RWvmeBlock(READ)); if(errorId != SUCCESS) { break; } if(READ_BIT(fpgaStatusReg4, 3)==0) break; } } else { Sleep(SECTOR_ERASE_TIME_ms); } return(SUCCESS); } /*============================================================================= * sectorEraseHpi() *============================================================================= * * MDSP flash * */ ERROR_ID sectorEraseHpi(unsigned char slotNumber, unsigned int sectorBaseAddr){ ERROR_ID errorId; UINT32 sectorAddr; UINT32 data; /* commands 1 to 5 */ errorId= commonEraseCommandsHpi(slotNumber, MDSP_FLASH_BOTTOM_REL_ADDR); ERROR_CHECK(errorId, commonEraseCommandsHpi()); if(errorId != SUCCESS){ return(errorId); } /* 6th command */ sectorAddr= MDSP_FLASH_BOTTOM_REL_ADDR+((sectorBaseAddr-MDSP_FLASH_BOTTOM_REL_ADDR)<<2); data= 0x30; errorId= RWmaster(WRITE, slotNumber, sectorAddr, &data, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId != SUCCESS){ return(errorId); } /* * Wait for operation completed */ Sleep(SECTOR_ERASE_TIME_ms); return(SUCCESS); } /*============================================================================= * writeByteToFlash() *============================================================================= * * Fpga flashes - with data verification * */ ERROR_ID writeByteToFlash(unsigned char slotNumber, UINT32 address, UINT8 data){ ERROR_ID errorId; UINT8 readData; int updateAddress; int i; if(data!=0xFF){ /* if erased don't rewrite; 0xFF is default value after erasing */ /* write data */ errorId= vmeWriteElementFlash(slotNumber, data, address, WRITE_DATA_HANDSHAKE_BIT); if(errorId != SUCCESS){ ERROR_CHECK(errorId, vmeWriteElementFlashProg()); return(errorId); } updateAddress= 0; }else{ updateAddress= 1; } /* * Wait for operation completed - data pooling (rev C) */ for(i=0; ; i++) { errorId= readByteFromFlash(slotNumber, address, &readData, updateAddress); if(errorId != SUCCESS){ ERROR_CHECK(errorId, readByteFromFlash()); return(errorId); } if(readData == data){ return(SUCCESS); } if(i>100){ errorId= FLASH_TIMEOUT_ERROR; ERROR_CHECK(errorId, Data pooling timeout!); return(errorId); } } } /*============================================================================= * writeByteToFlashHpi() *============================================================================= * * MDSP flash - no data verification * */ ERROR_ID writeByteToFlashHpi(unsigned char slotNumber, UINT32 address, UINT8 data){ ERROR_ID errorId; const UINT32 data1= 0xAA; const UINT32 data2= 0x55; const UINT32 data3= 0xA0; const UINT32 addr1= MDSP_FLASH_BOTTOM_REL_ADDR+(0x5555<<2); const UINT32 addr2= MDSP_FLASH_BOTTOM_REL_ADDR+(0x2AAA<<2); const UINT32 byteRelAddr= (address -MDSP_FLASH_BOTTOM_REL_ADDR); if(data!=0xFF){ /* if erased don't rewrite */ /* 1st command */ errorId= RWmaster(WRITE, slotNumber, addr1, (UINT32*)&data1, 1, NO_HPIA_AUTOINCREMENT, 0); if(errorId != SUCCESS){ ERROR_CHECK(errorId, RWmaster()); return(errorId); } /* 2nd command */ errorId= RWmaster(WRITE, slotNumber, addr2, (UINT32*)&data2, 1, NO_HPIA_AUTOINCREMENT, 0); if(errorId != SUCCESS){ ERROR_CHECK(errorId, RWmaster()); return(errorId); } /* 3rd command */ errorId= RWmaster(WRITE, slotNumber, addr1, (UINT32*)&data3, 1, NO_HPIA_AUTOINCREMENT, 0); if(errorId != SUCCESS){ ERROR_CHECK(errorId, RWmaster()); return(errorId); } /* write data */ errorId= RWmaster(WRITE, slotNumber, MDSP_FLASH_BOTTOM_REL_ADDR+(byteRelAddr<<2), (UINT32*)&data, 1, NO_HPIA_AUTOINCREMENT, 0); if(errorId != SUCCESS){ ERROR_CHECK(errorId, RWmaster()); return(errorId); } } /* no verification here !!!*/ return(SUCCESS); } /*============================================================================= * writeBlockToFlash() *============================================================================= * * Fpga flashes - with data verification * */ ERROR_ID writeBlockToFlash(unsigned char slotNumber, UINT32 address, UINT8 *data, unsigned int numberOfBytes, int newFlashLoc){ ERROR_ID errorId; unsigned int index; int status; unsigned int sectorSize; if(newFlashLoc) sectorSize= FLASH_SECTOR_SIZE_revE; else sectorSize= FLASH_SECTOR_SIZE; for(index=0; index100){ errorId=TIMEOUT_ERROR; ERROR_CHECK(errorId, timeout); return(errorId); } } /* read valid data */ errorId=vmeReadElement(slotAddr+FPGA_STATUS_7_REL_ADDR, &valueD32, sizeof(UINT32)); *value=(UINT8)(valueD32&0xFF); if(errorId!=SUCCESS){ ERROR_CHECK(errorId, vmeReadElement()); return(errorId); } return(SUCCESS); } /*============================================================================= * readBlockFromFlash() *============================================================================= * * Fpga flashes * */ ERROR_ID readBlockFromFlash(unsigned char slotNumber, UINT32 address, UINT8 *buffer, unsigned int numberOfBytes, int newFlashLoc){ ERROR_ID errorId; unsigned int index; int status; unsigned int sectorSize; if(newFlashLoc) sectorSize= FLASH_SECTOR_SIZE_revE; else sectorSize= FLASH_SECTOR_SIZE; for(index=0; index < numberOfBytes; ++index) { if((index%sectorSize) == 0) { SetCtrlVal(global.panel.flashInfo, FLASH_INFO_SECTOR, (index/sectorSize)); } errorId= readByteFromFlash(slotNumber, address+index, buffer+index, 1); if(errorId != SUCCESS){ ERROR_CHECK(errorId, readByteFromFlash()); return(errorId); } } return(SUCCESS); } /****************************************************************************** * Static functions * ******************************************************************************/ /*============================================================================= * vmeWriteElementFlash() *============================================================================= * * Fpga flashes * */ static ERROR_ID vmeWriteElementFlash(unsigned char slotNumber, UINT8 value, UINT32 address, int handshakeBit){ ERROR_ID errorId; UINT32 slotAddr=BASE_ADDRESS(slotNumber); UINT32 ctrlReg4_value; /* address(23:0) + data(31:24) */ UINT32 commandReg; UINT32 handshakeBitValue=0; int i; ctrlReg4_value=address; *(((UINT8*)&ctrlReg4_value)+3)=value; errorId=vmeWriteElement(ctrlReg4_value, slotAddr+FPGA_CONTROL_4_REL_ADDR, sizeof(UINT32)); if(errorId!=SUCCESS){ ERROR_CHECK(errorId, vmeWriteElement()); return(errorId); } /* set wr bit*/ SET_BIT(handshakeBitValue, handshakeBit); errorId=vmeWriteElement(handshakeBitValue, slotAddr+FPGA_CONTROL_3_REL_ADDR, sizeof(UINT32)); if(errorId!=SUCCESS){ ERROR_CHECK(errorId, vmeWriteElement()); return(errorId); } /* wait for ack */ for(i=0; ; i++){ errorId=vmeReadElement(slotAddr+FPGA_CONTROL_3_REL_ADDR, &commandReg, sizeof(UINT32)); if(errorId!=SUCCESS){ ERROR_CHECK(errorId, vmeReadElement()); return(errorId); } if(READ_BIT(commandReg, handshakeBit)==0){ return(SUCCESS); } if(i>100){ errorId=TIMEOUT_ERROR; ERROR_CHECK(errorId, timeout); return(errorId); } } } /*============================================================================= * commonEraseCommands() *============================================================================= * * Fpga flashes * */ static ERROR_ID commonEraseCommands(unsigned char slotNumber, UINT32 flashBaseAddr){ ERROR_ID errorId; const UINT32 addr1=flashBaseAddr+0x5555; const UINT32 addr2=flashBaseAddr+0x2AAA; /* 1st command */ errorId=vmeWriteElementFlash(slotNumber, 0xAA, addr1, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElementFlash()); if(errorId!=SUCCESS){ return(errorId); } /* 2nd command */ errorId=vmeWriteElementFlash(slotNumber, 0x55 ,addr2, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElementFlash()); if(errorId!=SUCCESS){ return(errorId); } /* 3rd command */ errorId=vmeWriteElementFlash(slotNumber, 0x80 , addr1, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElementFlash()); if(errorId!=SUCCESS){ return(errorId); } /* 4th command */ errorId=vmeWriteElementFlash(slotNumber, 0xAA , addr1, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElementFlash()); if(errorId!=SUCCESS){ return(errorId); } /* 5th command */ errorId=vmeWriteElementFlash(slotNumber, 0x55, addr2, WRITE_COMMAND_HANDSHAKE_BIT); ERROR_CHECK(errorId, vmeWriteElementFlash()); if(errorId!=SUCCESS){ return(errorId); } return(SUCCESS); } /*============================================================================= * commonEraseCommandsHpi() *============================================================================= * * MDSP flash * */ static ERROR_ID commonEraseCommandsHpi(unsigned char slotNumber, UINT32 flashBaseAddr){ ERROR_ID errorId; UINT32 buffer; const UINT32 addr1=flashBaseAddr+(0x5555<<2); const UINT32 addr2=flashBaseAddr+(0x2AAA<<2); /* 1st command */ buffer=0xAA; errorId=RWmaster(WRITE, slotNumber, addr1, &buffer, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } /* 2nd command */ buffer=0x55; errorId=RWmaster(WRITE, slotNumber, addr2, &buffer, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } /* 3rd command */ buffer=0x80; errorId=RWmaster(WRITE, slotNumber, addr1, &buffer, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } /* 4th command */ buffer=0xAA; errorId=RWmaster(WRITE, slotNumber, addr1, &buffer, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } /* 5th command */ buffer=0x55; errorId=RWmaster(WRITE, slotNumber, addr2, &buffer, 1, NO_HPIA_AUTOINCREMENT, 0); ERROR_CHECK(errorId, RWmaster()); if(errorId!=SUCCESS){ return(errorId); } return(errorId); } /*============================================================================= * returnBaseFpgaFlashAddress() *============================================================================= * * FPGA flashes - returns flash base address * */ static ERROR_ID returnBaseFpgaFlashAddress(UINT32 flashAddress, UINT32 *baseAddress){ ERROR_ID errorId= 0; //check limits if((flashAddress(FPGA_FLASH_2_BOTTOM_REL_ADDR+FLASH_MEMORY_SIZE))){ ERROR_CHECK(errorId, Wrong flash address!!); return(FATAL_ERROR); } if(flashAddress