Jump to content

malexander

Technical Forum Moderator
  • Posts

    224
  • Joined

  • Last visited

Everything posted by malexander

  1. @AA_TO Can you provide the following: 1. A screenshot of the Windows error message. 2. A screenshot of the devices as they appear in device manager. 3. A snippet of the schematic that includes all connects to the JTAG SMT4. Thanks, Michael
  2. @sgk I think Xilinx's suggestion to scope the JTAG signals is reasonable - it's good to look at the rise and fall times, setup time, hold time, and the AC overshoot/undershoot. That's something I always do as part of the board bring up/validation process. From a software testing perspective I would do the following with fTCK = 30 MHz: 1. Navigate through test logic reset to Shift-DR (the IDCODE instruction is loaded) 2. Generate N bits of random data, where N is a large number 3. shift N + 32 bits of data 4. compare the first 32 bits against the known IDCODE of the device 5. compare the N bits of received TDO data against the N bits of TDI data that you shifted out 6. repeat the above steps X times, where X is a very large number. If you want to be even more thorough you could first navigate to shift IR and manually shift in the IDCODE instruction, then navigate to shift-dr and perform the remaining steps. I don't think there's a public application that does this type of thorough testing... you'd have to write one use the Adept 2 SDK DMGR and DJTG libraries. I don't know how to perform this type of testing through TCL scripts or the Xilinx tools.
  3. @sgk From my contact: "We did not come up with any reasonable explanation other than there may have been some signal integrity issue (ex glitch) that occurred during the efuse programming. Given that the ramp on the edges of the dlc10 cable are quite slow, we have observed that this cable ends up being more immune to ringing or other signal integrity related issues. So our hypothesis is that there may be some marginal case where their JTAG signals is more sensitive due to board load or other PCB related issues that may make the JTAG signals more sensitive when programming their efueses with the digilent cable. Thought it is hard to say definitively this is the case, one thing they could try is to take a failing board and then scope out the jtag signals when connected with a digilent cable and compare them to what they see with a platform cable."
  4. @sgk I asked for a status update and will let you know when I hear something. Thanks, Michael
  5. @gojisan Does the problem return if you boot back into standard (non-Linux) mode? I wonder if the issues related to the thumb drives are related to current consumption. Two of the host ports are limited to 500mA each, while the other two are capable of providing 1 amp. I've never paid any attention to which ones I use when using a thumb drive but I'm also using a Sandisk drive. I have noticed that some of the supported wifi dongles will brown out on the 500mA ports when transmitting and are only usable on the 1 amp ports. It may be worth trying the 1amp ports the next time you use the Sony or IO data thumb drives. The 1 amp ports are the ones with the white square around them. Thanks, Michael
  6. @michael Inbar Which Spartan 6 board are you attempting to communicate with using a JTAG-HS2? To the best of my knowledge all of our Spartan 6 FPGA boards ship with an onboard JTAG programmer. Also - have you tried using the Xilinx tools? Since you are targeting a Spartan 6 you'd need to use ISE and iMPACT, which are no longer supported in Window ?
  7. @sgk Xilinx is still investigating the issue but the feedback I received is that this should be working with 2018.2 of Vivado. You can try a newer version of Vivado, but I'm unaware of any additional firmware versions or timing margin adjustments for eFuse programming.
  8. @Erik Hartwig I'm unable to replicate the issue on an M1 Mac Mini running Mac OS 11.5.2 using Waveforms 3.16.36 with the latest standard mode firmware, Linux image, and adept-bridge software. Can you please upgrade to the latest Linux image and adept-bridge application and see if the intermittent issue goes away in Linux? This is a two step process at the moment that requires a thumb drive with a FAT32 file system: 1. Download ADP3450/ADP3250 Linux Image version 9: here 2. Extract the zip file 3. Copy "deploy.env", "emmc.img", and "usb-image.ub" to the root of a FAT32 USB thumb drive. 4. Download adept-bridge version 0.7.0 to the root of the same FAT32 USB thumb drive. Download here 5. Unmount the thumb drive and then connect it to one of the four host ports on the back of the ADP3450/ADP3250 6. Connect ADP3450/ADP3250 to your MAC through USB 7. Open Waveforms, in the device manager select the ADP3450/ADP3250, click on "Boot", select "Linux Recovery", then click "Apply & Reboot". Close Waveforms. 8. In a terminal connected to the ADP3450/ADP3250 login using "root" as both the user name and password. 9. In the terminal type "deploy-to-emmc" and press enter. Wait for the operation to complete. 10. Open Waveforms, in the device manager select the ADP3450/ADP3250, click on "Boot", select "Linux", then click "Apply & Reboot". Close Waveforms. 11. In the terminal login with "digilent" as the user and password. 12. In the terminal execute "sudo mkdir /mnt/usb" 13. In the terminal execute "sudo mount /dev/sda1 /mnt/usb" 14. In the terminal execute "sudo dpkg -i /mnt/usb/digilent.adept.bridge_0.7.0_armhf.deb" I believe that it will automatically stop the service to install the update and then restart it. 15. Open Waveforms and check to see if the ADP3450 is visible through USB and Ethernet. If it's not visible then it's likely that the service didn't get restarted. In the terminal execute "sudo systemctl start adept-bridge.service". If that doesn't work then execute "sudo reboot". Can you please try using the Linux hosted Ethernet connection for a while and let me know if you are still seeing intermittent problems? Also, is there a wireless connection involved anywhere along the way or is this purely a wired connection? Thanks, Michael
  9. @sgk No, the SMT3 and DLC10 use different USB controllers and run completely different pieces of software so it's not possible to downgrade or upgrade to the DLC10 firmware. The firmware images are included alongside the Vivado installation. You can check to see which version you have by searching the Vivado installation directory for "FTDIFW_57*": find /opt/Xilinx/Vivado/2019.1/data -iname FTDIFW_57* /opt/Xilinx/Vivado/2019.1/data/xicom/cable_data/digilent/lnx64/firmware/FTDIFW_57_00000001_00000000_010A-64bit.so The naming scheme is as follows: FTDIFW_<fwid>_<public_capabilities>_<private_capabilities>_<firmware_version_number>-<architecture>.so The <firmware_version_number> field is a 16-bit hexadecimal field where the MSB is the major version and the LSB is the minor revision. The build number isn't included in the filename and the minor or major version number is bumped any time a change is made to the firmware's source code. The version number associated with the above example is 1.10, which is the most recent version. We haven't made any changes for several years so any recent version of Vivado should included 1.10
  10. @sgk It's being investigated by Xilinx but there's no update.
  11. @sgkXilinx is investigating this. Can you please tell me approximately how many units passed and how many failed programming? Thanks, Michael
  12. @sgk Can you tell me the full part number for the Virtex 7 device that you are targeting? Thanks, Michael
  13. @BryanS These are the ones with fixed names: "/tmp/digilent-adept2-shm-dvtbl" "/tmp/digilent-adept2-shm-dvtopn" "/tmp/digilent-adept2-shm-ftdevcmg" "/tmp/digilent-adept2-shm-ftdmgr" "/tmp/digilent-adept2-mtx-dvtopn" "/tmp/digilent-adept2-mtx-dvtbl" "/tmp/digilent-adept2-mtx-ftdevcmg" "/tmp/digilent-adept2-mtx-otinit" This last one has a variable name based on an index that can have a value between 0 and 63. "/tmp/digilent-adept2-mtx-devlock%2.2X" It's in hexadecimal so if the index was 63 decimal then the file name would be "/tmp/digilent-adept2-mtx-devlock3F" I'd expect the index to remain small and unless you plan on having a ton of devices connected to the same PC simultaneously you shouldn't need to create more than the first 10 files: "/tmp/digilent-adept2-mtx-devlock00" "/tmp/digilent-adept2-mtx-devlock01" "/tmp/digilent-adept2-mtx-devlock02" "/tmp/digilent-adept2-mtx-devlock03" "/tmp/digilent-adept2-mtx-devlock04" "/tmp/digilent-adept2-mtx-devlock05" "/tmp/digilent-adept2-mtx-devlock06" "/tmp/digilent-adept2-mtx-devlock07" "/tmp/digilent-adept2-mtx-devlock08" "/tmp/digilent-adept2-mtx-devlock09" "/tmp/digilent-adept2-mtx-devlock0A"
  14. @BryanS @attila I spent some time debugging this and discovered that the Adept Runtime is receiving EACCES when trying to open files with read/write permission in "/tmp". The following call results in -1 being returned when the file already exists and was created by another user, other than root: open("/tmp/digilent-adept2-shm-dvtbl", O_CREAT | O_RDWR, S_IRWXU | S_IRWXG | S_IRWXO ); This will ultimately lead to error code 3090 (initialization failed) because we use these files for locking while performing certain operations and if they can't be opened then the system won't function correctly. The "/tmp" directory has permissions 1777, meaning the sticky bit is set. This means that all users have read, write, and execute permissions for all files in "/tmp" but only root or the user that created a file in "/tmp" may delete it. This is fine since our software doesn't delete the files that it creates in "/tmp". After seeing the EACCES error I decided to run some experiments using 3 different user accounts: "malexander", "adept", and "root". Test 1: Ubuntu 20 LTS with sticky bit set for "/tmp" 1. As user "adept" execute "touch /tmp/blah.txt" 2. As user "adept" execute "chmod 777 /tmp/blah.txt" 3. As user "malexander" execute "echo "test" > /tmp/blah.txt" and receive "-bash: /tmp/blah.txt: Permission denied" 4. As user "root" execute "echo "test" > /tmp/blah.txt" and receive "-bash: /tmp/blah.txt: Permission denied" 5. As user "adept" execute "rm /tmp/blah.txt" to remove the file 6. As user "root" execute "touch /tmp/blah.txt" and "chmod 777 /tmp/blah.txt" 7. As user "malexander" execute "echo "test" > /tmp/blah.txt" and receive no error. 8. As user "adept" execute "echo "test2" >> /tmp/blah.txt" and receive no error. 9. As user "adept" cat file "/tmp/blah.txt" and see the expected text: test test2 10. As "root" execute "rm /tmp/blah.txt" Test 2: Ubuntu 20 LTS with sticky bit cleared for "/tmp" 1. As user "root" execute "chmod 777 /tmp" to remove sticky bit 2. As user "adept" execute "touch /tmp/blah.txt" followed by "adept" execute "chmod 777 /tmp/blah.txt" 3. As user "malexander" execute "echo "test" > /tmp/blah.txt" and receive no error. 4. As user "root" execute "echo "test2" >> /tmp/blah.txt" and receive no error. 5. As user "adept" cat file "/tmp/blah.txt" and see the expected text: test test2 Test 3: On Ubuntu 20 LTS run Adept test suite DmgrEnumExt test from multiple user accounts without removing the files in "/tmp" between runs with sticky bit off. 1. First make sure that no adept files are presently in the /tmp dir by executing "rm /tmp/digilent*" as root 2. As user "adept" execute "./test DmgrEnumEx -w 2000" and get expected result: 0: ADP3450-1 Transport Type: TCPIP Hostname: 10.1.112.148 IP Address: 10.1.112.148 Port: 33890 Account: Password: UsrName: ADP3450-1 ProdName: Analog Discovery Pro 3450 SN: SN:210018AFF319 MAC Address: MAC:00-18-3E-03-94-5E DCAP: 00000008 PDID: 40720410 PASS 3. As user "malexander" execute "./test DmgrEnumEx -w 2000" and get expected result: 0: ADP3450-1 Transport Type: TCPIP Hostname: 10.1.112.148 IP Address: 10.1.112.148 Port: 33890 Account: Password: UsrName: ADP3450-1 ProdName: Analog Discovery Pro 3450 SN: SN:210018AFF319 MAC Address: MAC:00-18-3E-03-94-5E DCAP: 00000008 PDID: 40720410 PASS Test 4: On Ubuntu 18 repeat test 1 with the sticky bit enabled (default on startup). The results under Ubuntu 18 were different. Any user can write a file that was created by another user in "/tmp" as long as the permissions for the file are set to 777. This is the behavior I expected. Test 5: On Ubuntu 16 repeat test 1 with the sticky bit enabled (default on startup). The results under Ubuntu 18 were different. Any user can write a file that was created by another user in "/tmp" as long as the permissions for the file are set to 777. This is the behavior I expected. Conclusion: I think this issue is the result of a bug in Ubuntu 20. Sure, it's possible that the behavior in Ubuntu 16 and Ubuntu 18 is the result of a bug that was fixed in Ubuntu 20. However, I think that's unlikely since we've never received reports of this issue on any other distribution. Further, the code that's being executed hasn't changed in years. I'm not sure who to contact about this issue to get it fixed upstream in Ubuntu 20 but I'll try to find someone. For now the only workaround I can suggest for people running Ubuntu 20 is to execute "chmod 777 /tmp" as root on startup to remove the sticky bit.
  15. Hi @BryanS @attila Error code 3090 means that something failed during initialization. It works for me in Ubuntu 16 and Ubuntu 18 but I was able to replicate the issue in Ubuntu 20. It has something to do with the file locks that are created in /tmp. If I run the DmgrEnumEx with my standard account (malexander) it works fine and I can run it as many times as I want. If I run it as root then I get error code 3090. If I then execute "rm /tmp/digilent-adept2-*" to remove the files that we create in /tmp then it works again without error even if I run it with a non-root account. What's weird is that the files are all created with 777 permissions so I wouldn't expect any issue opening or locking them from another account. What's also weird is that error code 3090 doesn't show up on any other distribution that I've tested on. I'll work on finding a solution and hopefully have it fixed in the next release, which is scheduled for later this month. Thanks, Michael
  16. @Daniel Carrasco IC8 is an inverter powered at 2.3V so if you are measuring 3.3V at R5 (the input, pulled up) and 2.3V at output (R35, pull down to ground) then the inverter is not working correctly. Maybe IC8 was somehow damaged or there is a solder bridge underneath. How many modules do you have experiencing this behavior? Can you look at IC8 on the boards that work with a magnifying glass or microscope and see if it appears visibly different than the ones that don't? Thanks, Michael
  17. @Daniel Carrasco That's not good because it means that the DIR pin of the level translator sees a logic '1' when it should be receiving a '0' when the module isn't open in the Xilinx tools. This causes the level translator to be in output mode and it should only be in output mode when open in the Xilinx tools. Can you please verify that R5 is present on your board and measure the voltage of the OEGIO2 net at the location shown in the attached image? Thanks, Michael
  18. @Daniel Carrasco By default the level translator that drives the GPIO2 pin should be configured as an input, meaning it should appear as high-z and allow GPIO2 to be pulled or driven by another source. Can you please measure the voltage of the direction net after power on (before opening the device in Hardware Manager) and report back? I've attached an image that shows where to perform the measurement. Thanks, Michael
  19. @Daniel Carrasco It sounds to me like R4 may be cold soldered on some of the modules (may have happened during the reflow process when mounting SMT2). If I were debugging this I would try soldering a 10K ohm resistor between DIG_TRST and 3V3 on one of the boards that was measuring ~30mV after power up and repeat the DIG_TRST voltage measurements. If it measures closer to 3.3V than 30mV prior to opening the device in Vivado then R4 is likely cold soldered. Please try this experiment and report back your findings. Thanks, Michael
  20. We've updated our procedures to ensure that the modules will be easily identifiable whenever a change to form, fit, or function is made. There will also be a PCN issued before new modules go into distribution.
  21. @Kyle_Jackson I was able to get the SREC bootloader working on a Cmod A7 - 35T that has the Macronix flash using Vivado 2019.1. To get this to work you have to include the Xilinx QSPI controller in your Microblaze block design and in the IP configuration either select "Standard" for the mode (SPI x1 mode) or if you select "QUAD" then make sure to select "Macronix" for Slave Device. Once you are in SDK and have created the SREC bootloader project (and associated BSP) you need to open "bootloader.c" from the sources and scroll down until you find the call to "XIsf_Initialize". Double click the function name to highlight it, right click and select "Open Declaration". Once you have "xilisf.c" open do the following: 1. Somewhere near the top of xilisf.c add the following: #define XISF_MACRONIX_DEV_MX25L3233F 0x2016 /**< Device ID for MX25L3233F */ 2. In xilisf.c find the definition for IntelStmDevices[] and add the following: {XISF_MANUFACTURER_ID_MACRONIX, XISF_MACRONIX_DEV_MX25L3233F, XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR, XISF_NUM_OF_SECTORS64}, 3. Save xilisf.c, which should rebuild the project. Once you've completed the above steps you need to go through the process of generating a download.bit that has integrated the bootloader elf with the bitstream, program that to the flash at offset 0, and then program your application SREC to the flash at the appropriate offset. I placed my SREC at offset 0x00180000 (same offset I set in blconfig.h of the srec bootloader project) since my bitstream was only ~1100KB. You may need to use a different offset depending on the size of your bitstream+bootloader elf combination. I suggest that anyone who is unfamiliar with the SREC bootloader process follow the guide linked below but select "Macronix" for the Slave Device and perform the xilisf.c modifications. https://reference.digilentinc.com/learn/programmable-logic/tutorials/htsspisf/start Thanks Michael
  22. We will investigate if there is an easy way to get the Macronix Flash to work with the SREC bootloader that does not require end user modification.
  23. To Zygot's point R&D did test Macronix flash with end applications and was aware that the Macronix part is not a drop in replacement. Programming the part from within the Xilinx tools requires different steps (selecting a different IC) and accessing it from an application using Xilinx's QSPI core requires different and/or extra steps. That's why a flash memory rarely gets swapped out on a Digilent product, even when procurement or marketing come to R&D wanting to replace a part for cost reduction and/or joint marketing opportunities. We try to avoid switching out flash unless there's no other option. In this particular case procurement notified R&D that the original Micron flash was EOL and that soon it would no longer be possible to purchase that component. At that time the Macronix part was the only one identified that would fit within the physical space constraints of the Cmod A7 and thus we chose to use that part. I just looked through the manufacturing test and see that it was updated to support multiple flash memory options, including Macronix, on September 8 of 2017. So there has been quite a bit of delay between when procurement asked R&D to replace the flash and when customers started receiving modules with the Macronix flash. The fact that this forum thread exists means that we failed to properly document the changes required to use the Macronix flash, and I'm sorry for any hardship that has caused anyone. The following code snippet was adapted from an Xilinx example project for their QSPI core and should work with Micron, Spansion, and Macronix flash. As far as I can remember the main difference between communicating with Micron and Macronix flash is related to the number of dummy cycles required when performing dual and quad read operations. Spansion and Macronix flash use the same dummy count, while Spansion flash also requires an extra step (sending a command to explicitly enable quad mode). Please note that cbDualReadDummy, cbQuadReadDummy, cbDualIOReadDummy, cbDualIOReadDummy, and cbQuadIOReadDummy are global variables used by the read function when performing a read operation of a specific type. #define cmdReadID 0x9F /* Read manufacturer ID of SPI Flash */ #define cbDualReadDummyMicron 2 #define cbQuadReadDummyMicron 4 #define cbDualIOReadDummyMicron 2 #define cbQuadIOReadDummyMicron 5 #define cbDualReadDummySpansion 4 #define cbDualIOReadDummySpansion 2 #define cbQuadReadDummySpansion 4 #define cbQuadIOReadDummySpansion 3 /* Read the manufacturer ID from the SPI Flash. */ if ( ! FSpiFlashGetManufactureID(pxspiFlash) ) { if (fVerbose ) { xil_printf("Error: failed to read manufacturer ID!\r\n"); } return fFalse; } if ( 0x01 == rgbRead[1] ) { if (fVerbose ) { xil_printf("Spansion Flash!\r\n"); } fSpansionFlash = fTrue; cbDualReadDummy = cbDualReadDummySpansion; cbQuadReadDummy = cbQuadReadDummySpansion; cbDualIOReadDummy = cbDualIOReadDummySpansion; cbQuadIOReadDummy = cbQuadIOReadDummySpansion; } else if ( 0x20 == rgbRead[1] ) { if (fVerbose ) { xil_printf("Micron Flash!\r\n"); } fSpansionFlash = fFalse; cbDualReadDummy = cbDualReadDummyMicron; cbQuadReadDummy = cbQuadReadDummyMicron; cbDualIOReadDummy = cbDualIOReadDummyMicron; cbQuadIOReadDummy = cbQuadIOReadDummyMicron; } else if ( 0xC2 == rgbRead[1] ) { if (fVerbose ) { xil_printf("Macronix Flash!\r\n"); } fSpansionFlash = fFalse; cbDualReadDummy = cbDualReadDummySpansion; cbQuadReadDummy = cbQuadReadDummySpansion; cbDualIOReadDummy = cbDualIOReadDummySpansion; cbQuadIOReadDummy = cbQuadIOReadDummySpansion; } else { if (fVerbose ) { xil_printf("Unknown Flash!\r\n"); } fSpansionFlash = fFalse; return fFalse; } BOOL FSpiFlashGetManufactureID(XSpi* pxspiFlash) { /* Wait until the flash is ready to accept the next command. */ if ( ! FSpiFlashWaitForFlashReady(pxspiFlash) ) { return fFalse; } rgbWrite[0] = cmdReadID; fTransferring = fTrue; if ( XST_SUCCESS != XSpi_Transfer(pxspiFlash, rgbWrite, rgbRead, cbStsRead) ) { return fFalse; } /* Wait for the transfer to complete and then check for errors. */ while ( fTransferring ) { asm("nop"); } if( 0 != cerrTrans ) { cerrTrans = 0; return fFalse; } return fTrue; } BOOL FSpiFlashRead(XSpi* pxspiFlash, u32 addrRead, u32 cbRead, u8 cmdRead) { /* Wait until the flash is ready to accept the next command. */ if ( ! FSpiFlashWaitForFlashReady(pxspiFlash) ) { return fFalse; } /* Populate the buffer with the read command and starting address. */ rgbWrite[0] = cmdRead; rgbWrite[1] = (u8) (addrRead >> 16); rgbWrite[2] = (u8) (addrRead >> 8); rgbWrite[3] = (u8) addrRead; rgbWrite[4] = 0; /* Certain read commands require additional bytes to be transferred. ** Extend the read byte count if required for the specified command. */ if ( cmdDualRead == cmdRead ) { cbRead += cbDualReadDummy; } else if ( cmdDualIORead == cmdRead ) { cbRead += cbDualIOReadDummy; } else if ( cmdQuadIORead == cmdRead ) { cbRead += cbQuadIOReadDummy; } else if ( cmdQuadRead == cmdRead ) { cbRead += cbQuadReadDummy; } /* Transfer the write command and the data to the flash and perform ** the requested read. */ fTransferring = fTrue; if ( XST_SUCCESS != XSpi_Transfer(pxspiFlash, rgbWrite, rgbRead, (cbRead + cbRWExtra)) ) { return fFalse; } /* Wait for the transfer to complete and then check for errors. */ while ( fTransferring ) { asm("nop"); } if( 0 != cerrTrans ) { cerrTrans = 0; return fFalse; } return fTrue; } I hope these code snippets are helpful for anyone having issues reading from the Macronix flash. @Kyle_Jackson I don't think we will change to the Alliance Memory part because doing so would likely cause more issues, with a mix of Macronix boards already in the field. However, I would appreciate it if you can provide the part number for the IC that used so that I can note it just in case we do decide to make a change. Thanks, Michael
  24. @anshumantech If you look at the top left corner of sheet 6 you will find header J8 attached to the TMS, TDI_FPGA, TCK, and TDO_FPGA nets through resistors R163, R164, R165, and R166. Those resistors are present to help prevent damage from any drive conflicts that may occur when both an external and onboard programmer are active. However, JTAG programming can't function correctly when both an onboard and external programmer are active. There are tri-state buffers between the onboard USB controller and the TMS, TDI_FPGA, and TCK nets. These buffers are held in tri-state when the programmer isn't open in Adept or Vivado/Vitis. The tri-state buffers are what allows you to use an external programmer with J8 (JTAG-HS1 or JTAG-HS2 recommended for 6-pin header) - just be sure that you haven't opened the onboard interface in Adept or Vivado/Vitis. Thanks, Michael
  25. @attila There's a lock associated with each interface that gets acquired when the enable command is executed and released when disable is executed. The lock has to be shared across processes so it doesn't go away until all applications referencing the runtime libraries are closed. The type of lock I'm using should be recoverable from a dead thread/process but perhaps that's not working correctly. I'll look into this while I'm working on the next release. Thanks, Michael
×
×
  • Create New...