Untitled
unknown
plain_text
5 months ago
12 kB
2
Indexable
public class PROMFlasher { private const int CmdUnlock = 0x556E6C6B; // Unlock command private const int CmdErase = 0x45726173; // Erase command private const int CmdProgram = 0x50726F67; // Program command private const int CmdStartAddress = 0x5341; // Start Address command private const int CmdEndAddress = 0x45; // End Address command //Check for bit 7 of the program status register. A value of 1 indicates Program ready. private const int ProgramEraseControllerStatusMask = 0x000003FC; private const int ProgrammerStatusReady = 0x00000200; // Check bit 4 of program status register. A value of 1 indicates error. private const int ProgramErrorStatusMask = 0x00000040; private const int ProgramStatusError = 0x00000040; // Bit 0 of the FPGA status register. If set indicates FIFO is full. private const int FifoFullStatusMask = 0x00000001; private const int FifoFullValue = 0x00000001; // Bit 1 of the FPGA status register. private const int ProgReadyBitMask = 0x00000002; private const int ProgReadyValue = 0x00000002; // The default timeout when waiting for the programmer status in msec. // Change here to increase or decrease the waiting period. //jcpm 50000 was ok for smaller FPGA (315T), but 60000 is needed for larger FPGA (475T) private const int DefaultTimeoutForStatusCheckInMs = 60000; // Number of successive words prograamed before checking programmer status. // Each word is 32 bits. private const int ProgramChunkSizeInWords = 16; // Start and End addresses of the PROM, used for erasing all blocks. private const int StartAddressForPROMErase = 0x000000; private const int EndAddressForPROMErase = 0x7E0000; private string _statusMsg = string.Empty; public int _UpgradePercentage; /// <summary> /// Initializes a new instance of the <see cref="PROMFlasher"/> class. /// </summary> public PROMFlasher() { } /// <summary> /// Flashes the PROM. /// </summary> /// <param name="filename">Name of the file with entire path.</param> /// <returns>Status of PROM flashing</returns> public bool FlashPROM(MCSFile mcsFile) { // Set up for programming if (!this.SetUpForProgramming(mcsFile)) { // Set up failed. return false; } // program PROM. if (!this.Program(mcsFile)) { return false; } return true; } /// <summary> /// Sets up for programming. /// </summary> /// <param name="mcsFile">The MCS file.</param> /// <returns>Ststus of set up.</returns> private bool SetUpForProgramming(MCSFile mcsFile) { // Check Prg_Ready bit status. if (!this.CheckPrgReadyAndWait(PROMFlasher.DefaultTimeoutForStatusCheckInMs)) { return false; } // Set the start and end addresses and unlock the PROM. this.SetStartAndEndAddress(mcsFile.StartAddress, mcsFile.EndAddress); // Write Unlock Command to Buffer FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, PROMFlasher.CmdUnlock); // Write Erase Command to Buffer FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, PROMFlasher.CmdErase); // Write Program Command to Buffer. FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, PROMFlasher.CmdProgram); return true; } /// <summary> /// Sets the start and end addresses. /// </summary> /// <param name="mcsFile">The MCS file.</param> private void SetStartAndEndAddress(int startAddress, int endAddress) { StringBuilder startAddressCmdString = new StringBuilder(); startAddressCmdString.AppendFormat("{0:X4}", PROMFlasher.CmdStartAddress); startAddressCmdString.AppendFormat("{0:X4}", startAddress); // Write StartAddr to Buffer FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, Convert.ToInt32(startAddressCmdString.ToString(), 16)); // Build end address command string StringBuilder endAddressCmdString = new StringBuilder(); endAddressCmdString.AppendFormat("{0:X2}", PROMFlasher.CmdEndAddress); endAddressCmdString.AppendFormat("{0:X6}", endAddress); // Write EndAddr to Buffer FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, Convert.ToInt32(endAddressCmdString.ToString(), 16)); } /// <summary> /// Programs the PROM. /// </summary> /// <param name="mcsFile">The MCS file.</param> /// <returns> /// Status of programming. <c>true</c> if successful; otherwise <c>false</c>. /// </returns> private bool Program(MCSFile mcsFile) { System.Threading.Thread.Sleep(500); // Start writing data for programming. int wordCounter = 0; double TotalWordsSentToFPGA = 0; _UpgradePercentage = 0; foreach (UInt32 dataWord in mcsFile.DataInWords) { if (wordCounter < PROMFlasher.ProgramChunkSizeInWords) { // Chunksize of words not written yet. Continue writing without status check. FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, (int)dataWord); wordCounter++; TotalWordsSentToFPGA++; } else { if (!this.CheckAndWaitForProgramReadyAndProgramError(PROMFlasher.DefaultTimeoutForStatusCheckInMs)) { // First time this is failing System.Threading.Thread.Sleep(5000); if (!this.CheckAndWaitForProgramReadyAndProgramError(PROMFlasher.DefaultTimeoutForStatusCheckInMs)) { return false; } } // Wait for FIFO availability if it is full. if (!this.CheckFifoFullStatusAndWait(PROMFlasher.DefaultTimeoutForStatusCheckInMs)) { return false; } wordCounter = 0; TotalWordsSentToFPGA++; // Write the next word. FPGACommunicationHandler.FPGAInstance.WriteToFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_DATA_REGISTER, (int)dataWord); wordCounter++; } _UpgradePercentage = (int)((TotalWordsSentToFPGA / (mcsFile.DataInWords.Count))* 100 ); } _UpgradePercentage = (int)((TotalWordsSentToFPGA / (mcsFile.DataInWords.Count)) * 100); // Final check for programming completed. int statusWord = -1; FPGACommunicationHandler.FPGAInstance.ReadFromFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_COMMAND_REGISTER, ref statusWord); // Check Program error. if ((Convert.ToInt32(statusWord) & PROMFlasher.ProgramErrorStatusMask) == PROMFlasher.ProgramStatusError) { return false; } return true; } /// <summary> /// Checks the and wait for programmer ready status. /// </summary> /// <param name="timeout">The timeout in milliseconds.</param> /// <returns>Status of the check. <c>true</c> if programmer is ready; <c>false</c>If the wait timed out.</returns> private bool CheckAndWaitForProgramReady(int timeout) { int statusWord = -1; bool isStatusReady = false; bool isTimedOut = false; Stopwatch timer = new Stopwatch(); timer.Start(); while ((!isStatusReady) && (!isTimedOut)) { FPGACommunicationHandler.FPGAInstance.ReadFromFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_COMMAND_REGISTER, ref statusWord); isStatusReady = ((Convert.ToInt32(statusWord) & PROMFlasher.ProgramEraseControllerStatusMask) == PROMFlasher.ProgrammerStatusReady); isTimedOut = (timer.ElapsedMilliseconds > timeout); } // return status. if (isTimedOut) { // Timed out before programmer was ready. return false; } return true; } /// <summary> /// Checks the and wait for ready status and program error. /// </summary> /// <param name="timeout">The timeout.</param> /// <returns>Status of check for Program Ready</returns> private bool CheckAndWaitForProgramReadyAndProgramError(int timeout) { int statusWord = -1; bool isStatusReady = false; bool isTimedOut = false; Stopwatch timer = new Stopwatch(); timer.Start(); while ((!isStatusReady) && (!isTimedOut)) { FPGACommunicationHandler.FPGAInstance.ReadFromFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_COMMAND_REGISTER, ref statusWord); isStatusReady = ((Convert.ToInt32(statusWord) & PROMFlasher.ProgramEraseControllerStatusMask) == PROMFlasher.ProgrammerStatusReady); isTimedOut = (timer.ElapsedMilliseconds > timeout); System.Threading.Thread.Sleep(5); // Check Program error. if ((Convert.ToInt32(statusWord) & PROMFlasher.ProgramErrorStatusMask) == PROMFlasher.ProgramStatusError) { return false; } } // return status. if (isTimedOut) { return false; } return true; } /// <summary> /// Checks the PRG_Ready bit and waits for it to be set. /// </summary> /// <param name="timeOut">The time out.</param> /// <returns>Satus of wait</returns> private bool CheckPrgReadyAndWait(int timeOut) { int statusWord = -1; bool isProgReady = false; bool isTimedOut = false; Stopwatch timer = new Stopwatch(); timer.Start(); while (!isProgReady && !isTimedOut) { FPGACommunicationHandler.FPGAInstance.ReadFromFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_COMMAND_REGISTER, ref statusWord); isProgReady = (statusWord & PROMFlasher.ProgReadyBitMask) == PROMFlasher.ProgReadyValue; isTimedOut = timer.ElapsedMilliseconds > timeOut; } if (isTimedOut) { return false; } return true; } /// <summary> /// Checks the FIFO full status and waits for it to be reset. /// </summary> /// <returns>Satus of wait</returns> private bool CheckFifoFullStatusAndWait(int timeOut) { int statusWord = -1; bool isFifoAvailable = false; bool isTimedOut = false; Stopwatch timer = new Stopwatch(); timer.Start(); while (!isFifoAvailable && !isTimedOut) { FPGACommunicationHandler.FPGAInstance.ReadFromFPGARegister(AnoleAPIConstants.BASE_ADDRESS, AnoleAPIConstants.FLASH_COMMAND_REGISTER, ref statusWord); isFifoAvailable = (statusWord & PROMFlasher.FifoFullStatusMask) != PROMFlasher.FifoFullValue; isTimedOut = timer.ElapsedMilliseconds > timeOut; } if (isTimedOut) { return false; } return true; } }
Editor is loading...
Leave a Comment