Jump to content

engrpetero

Members
  • Posts

    150
  • Joined

  • Last visited

Everything posted by engrpetero

  1. One more thing to add... I think the driver XSysMon_SetSeqInputMode() function description is incorrect. This function is for setting the channels to unipolar or bipolar mode. The function merely updates a single bit in the XSM_SEQ_04_OFFSET and XSM_SEQ05_OFFSET registers. The function description mixes differential and unipolar (which are not really related). For the 'system' channels (like the on-chip temp), it doesn't seem to matter whether the channel is defined as unipolar or bipolar (I imagine bipolar is just ignored). For my application, all aux channels are unipolar so I am calling XSysMon_SetSeqInputMode() with an InputModeMask value of 0. It seems the XSysMon_SetSeqChEnables() function is for setting the channels that should be used with the channel sequencer. And the initialization (for unipolar aux channels) should be // Disable the Channel Sequencer before configuring the Sequence registers. XSysMon_SetSequencerMode(ptrXSysMon, XSM_SEQ_MODE_SAFE); // Disable all alarms XSysMon_SetAlarmEnables(ptrXSysMon, 0x0); // Set averaging for all channels to 16 samples XSysMon_SetAvg(ptrXSysMon, XSM_AVG_16_SAMPLES); // Set unipolar mode for all sequence channels XSysMon_SetSeqInputMode(ptrXSysMon, 0); // Set seq channel enables XSysMon_SetSeqChEnables(ptrXSysMon, XSM_SEQ_CH_AUX06 | XSM_SEQ_CH_AUX07 | XSM_SEQ_CH_AUX14 | XSM_SEQ_CH_AUX15); // Set 6ADCCLK acquisition time in all channels XSysMon_SetSeqAcqTime(ptrXSysMon, XSM_SEQ_CHANNELS_MASK); // Disable averaging in all channels XSysMon_SetSeqAvgEnables(ptrXSysMon, XSM_SEQ_CHANNELS_MASK); // Enable all channels XSysMon_SetSeqChEnables(ptrXSysMon, XSM_SEQ_CHANNELS_MASK); // Set the ADCCLK frequency equal to 1/32 of System clock XSysMon_SetAdcClkDivisor(ptrXSysMon, 32); // Enable Calibration XSysMon_SetCalibEnables(ptrXSysMon, XSM_CFR1_CAL_PS_GAIN_OFFSET_MASK | XSM_CFR1_CAL_ADC_GAIN_OFFSET_MASK); // Enable the Channel Sequencer in continuous sequencer cycling mode XSysMon_SetSequencerMode(ptrXSysMon, XSM_SEQ_MODE_CONTINPASS);
  2. well, @artvvb - your application works on my hardware. So I know the hardware is built correctly. And thank you for a working example! Unfortunately, my app (in which I *think* I'm doing the exact same thing as you are) does not. Back to troubleshooting! Edit to add... Hmmm, as expected, mine did not exactly match your example. I was mistakenly using the bit-mask values intended for the channel sequencer masking as the actual ADC channels instead of the actual ADC channel number. E.g., Aux14 is ADC channel 30 (XSM_SEQ_CH_AUX_SHIFT + 14) and NOT XSM_SEQ_CH_AUX14 (which is actually 0x40000000 and intended to be used as a bit mask).
  3. Wow, I totally missed this when looking at UG480. in my design XADC is instantiated on the PL side but I was using the XAdcPs drivers (I should have suspected something with the 'Ps' in the name). As always, your help greatly appreciated. I'll review the SysMon v7.8 and go that route since that makes more sense with my design.
  4. Thanks for your hard work on this item. I *should* be able to take what you've presented and get this working. One question since I don't see these items defined either in the Cora app or in the XAdcPs V2.6 driver files. Where are XSysMon_GetStatus() (or XAdcPs_GetStatus()) and XSM_SR_EOS_MASK (or XADCPS_SR_EOS_MASK) defined, please? It also *seems* since the last in the setup function calls was to setup up for continuous sequencer cycling that there is no need to clear the status and then 'wait' for the status mask to be set (though I'll certainly do that if that's what it takes. :-)). // Enable the Channel Sequencer in continuous sequencer cycling mode XSysMon_SetSequencerMode(InstancePtr, XSM_SEQ_MODE_CONTINPASS); And with these pins representing Aux 14, 7, 15, 6...
  5. Any chance you got anywhere, @artvvb? I did play around with this a bit more today and the raw numbers are non-zero (it's the 10 MSBs of the 16 bit returned number). They don't seem to change (however, with nothing connected to the JA pins, the values I read are different when reading Aux6, Aux7, Aux14, and Aux15. I'll be back on it tomorrow but was just wondering if you learned anything new.
  6. The values were not 0s. I'm at a different site today and don't have my hardware but can determine exact values tomorrow. I played around with many of the 'Set' functions the driver defines to understand how they work/what they are intended to do. I can explicitly call all the Set functions shown in the linked Cora example to see if that has any effect then as well. Edit to add... Looks like I should have more carefully followed your initial advice and studied the Cora example more carefully. Converting the functions in the Cora example init to the Zybo differential channels and otherwise only using the onboard temperature channel, It seems the init should include these function calls (where #define XADCPS_SEQ_CHANNELS 0x03030010 // temp channel, aux 6, 7, 14, 15 (all aux are differential)... // Disable the Channel Sequencer before configuring the Sequence registers. XAdcPs_SetSequencerMode(ptrXAdc, XADCPS_SEQ_MODE_SAFE); // Disable all alarms XAdcPs_SetAlarmEnables(ptrXAdc, 0x0); // Set averaging for all channels to 16 samples XAdcPs_SetAvg(ptrXAdc, XADCPS_AVG_16_SAMPLES); // Set differential input mode for channels AUX6, AUX7, AUX14, AUX15 and unipolar input mode for the rest XAdcPs_SetSeqInputMode(ptrXAdc, XADCPS_SEQ_CH_AUX06 | XADCPS_SEQ_CH_AUX07 | XADCPS_SEQ_CH_AUX14 | XADCPS_SEQ_CH_AUX15); // Set 6ADCCLK acquisition time in all channels XAdcPs_SetSeqAcqTime(ptrXAdc, XADCPS_SEQ_CHANNELS); // Disable averaging in all channels XAdcPs_SetSeqAvgEnables(ptrXAdc, XADCPS_SEQ_CHANNELS); // Enable all channels XAdcPs_SetSeqChEnables(ptrXAdc, XADCPS_SEQ_CHANNELS); // Set the ADCCLK frequency equal to 1/32 of System clock XAdcPs_SetAdcClkDivisor(ptrXAdc, 32); // Enable Calibration XAdcPs_SetCalibEnables(ptrXAdc, XADCPS_CFR1_CAL_PS_GAIN_OFFSET_MASK | XADCPS_CFR1_CAL_ADC_GAIN_OFFSET_MASK); // Enable the Channel Sequencer in continuous sequencer cycling mode XAdcPs_SetSequencerMode(ptrXAdc, XADCPS_SEQ_MODE_CONTINPASS);
  7. Well, I'm not getting the result I want. Perhaps some additional help, please? I do read a believable value on for the chip temperature (~45C) but not on any of the aux channels for the ADC. The Vivado XADC items is setup for channel sequencing (continuous) with the appropriate channels (those shown in the first pic) in the channel sequence list. I have a 10:1 voltage divider of the 3.3V power going to pin 2 of the JA header. pin 7 of the JA header is connected to DC common (JA pin 11). I physically measure 0.33V between pins 2-7 so I'm confident the voltage is present on the pin. I am using the BSP driver software and have defined XADCPS_CH_BATTERY_CHARGE_CURRENT as XADCPS_CH_AUX_MIN + 7U. The software always reports 0.790V on pin 1 (using the BSP driver XAdcPs_GetAdcData() and XAdcPs_RawToVoltage() functions). Five pictures below: 1) my Vivado block; 2) XADc basic setup; 3) the constraints file showing the Vaux_p and _n items; 4) The Zybo schematic portion showing the inputs; 5) my Vitis function that calls the BSP functions (and is based off the BSP example). float GetBatteryChargeCurrent(XAdcPs *ptrXAdc) { u32 rawData; float voltage; float resistance = 1.0f; // the hardware circuit uses a 1.0 ohm current sense resistor float chargeCurrent; rawData = XAdcPs_GetAdcData(ptrXAdc, XADCPS_CH_BATTERY_CHARGE_CURRENT); voltage = XAdcPs_RawToVoltage(rawData); chargeCurrent = voltage / resistance; return chargeCurrent; }
  8. (I posted over at the Xilinx fora as well). I'm in need of some design assistance with PCB layout and config of a XC7Z010-1CLG400C (the same Zynq part used on the Zybo Z7-10). We use Altium. I believe I can work out a contracting arrangement as necessary. Anyone here have such experience? (this is for an in-house electronics, a substantial update to one of our systems and is in no way competing with Digilent nor Xilinx)
  9. That's good info - I didn't see that note about the channel numbers. Thanks. I expect to have time to work on this tomorrow so again, I'll try to report back.
  10. On second look, it appears that the Zybo XADC port (JA) if used for analog inputs must use the 4 differential pairs so that only 4 actual analog inputs can be digitized? So even if the analog signals are not truly differential (well, if all four share one common voltage), only 4 signals can be monitored, and not the 8 that *might* be available with a single-ended scheme. (which by the way is fine, just trying to confirm my understanding)
  11. Thanks for the reply, @artvvb. This link was also helpful as it also showed I was creating ports the wrong way (or at least it gives me more info about the external ports). Surely with your link and this one, I can figure this out. I'll report back later.
  12. I've got a Zybo Z7-10 and am trying to use the JA port to monitor some 0-1V voltages (looking at the Zybo product page, it looks like I could monitor 8 single ended voltages?). I've downloaded the XADC example project (which was made some time ago and doesn't contain a Vivado block diagram - or at least if it does, I'm not setting up the project correctly with my Vivado version) but I have looked at the project's constraints file. FWIW - it doesn't look much different than the xdc 'base' file I download for the Zybo. In my test project, I instantiate the XADC Wizard customize the component for my test purposes, including use of the channel sequencer and 2 of the aux channels (as well as the calibration and temperature channels). I'm at a loss as to how to connect my external ports to the XADC IP though. In my constraints file... Implementation produces errors... I continue to do online research to address the error but thought someone here might point me to a helpful article/link...
  13. Thanks for those suggestions, @artvvb. I've done a good amount of googling and reading various questions/answers. I'd certainly do well with a stronger base knowledge so your links are appreciated.
  14. engrpetero

    PL Timing analysis

    I've completed a few designs and feel like I'm making a lot of progress with both the PL and PS side of the Zynq devices. Lots more to learn though. In Vivado, when I open the implemented design, I can look at the content in the tree but I confess I know very little about what I'm seeing and am unsure how to address concerns (Warnings, Bad Practice, etc.), I see in the 'Violations'. Can anyone point me to good documentation sources to read to continue learning, please?
  15. Thanks @artvvb. This suggestion in the linked thread was helpful and I'll try next time the issue shows up (and of course, now I understand what you mean by just starting fresh packaging the IP).
  16. FWIW - the disable stuff in the IP (including port signals) and then re-enable (by commenting and uncommenting) eventually caused an update to happen. Still would be nice to know how (if?) to be able to force an update...
  17. Thanks for the reply, @D@n. When you say, 'force Vivado to repackage their IP from scratch', what do you mean? 😃 I can't seem to find a way to force this and googling didn't help. I guess I could try something like commenting out much of the project and putting in a very new simple port list and see if Vivado responds...
  18. I've been working with one custom IP project for several weeks now. It's getting close to finished. Only today, I've had an issue show up I've never experienced before. I added two ports to the IP - one input and one output (not that the directions matter) - and then added appropriate code to deal with the two ports. When I go to repackage IP, the Package IP Settings dialog (which normally provides a link to 'Merge Changes') doesn't show and the IP indicates with a check mark that the Ports are 'good'. Since I've never seen Vivado NOT detect when the ports have changed, I've never needed to figure out how to 'force' a port upgrade. So two questions... Why does Vivado NOT recognize the ports have changed? How do I force Vivado to 'learn' (or determine or scan, etc.) that port changes have occurred before I repackage?
  19. engrpetero

    Zynq SPI0 - EMIO

    Thanks for the reply, @Richm. I do agree with you on the same experience studying/debugging the provided code. The biggest benefit I've found from studying the provided code was to learn how those developers provided a (in most cases) very parallel way of doing things. And it helped me to make appropriate modifications for my use. For the character display, I don't disagree with you that the this might have better been done by just addressing it with a new AXI lite IP design. I'd like to still do that sometime (as a learning exercise as much as anything). I don't think that would be as easy with the graphical display - perhaps I'm wrong there too though. The PS does make it very easy to make changes but I do understand there are tradeoffs (the PS can get loaded up for one). With functional SPI frequencies of up to 1MHz for the char display and 25MHz for the graphical display, the PS is sufficient for use.
  20. engrpetero

    Zynq SPI0 - EMIO

    For anyone that makes it to the bottom of this thread, when using the xspi_polled_example example program for the V3.2 driver of the V4.9 AXI QSPI peripheral, to run this example with an actual slave on the first slave bit, simply make the two changes enumerated below. It is of course a very good idea to step through the XSpi_Transfer() function to clearly understand what it is doing (which will also allow modifying it to be more useful to a particular application). Remove the Loopback mode bit mask from the XSpi_SetOptions() function (this is pretty obvious as we just want to use normal mode). The line SpiInstancePtr->SlaveSelectReg = 0x02;. My AXI QSPI has two slaves so the SlaveSelectMask is 0x03. The SlaveSelectReg needs to have exactly one '0' and it should be in the bit position for the slave you want to use. The example does not have this line as it only uses loopback mode. /* * Set the Spi device as a master and in loopback mode. * Note: Remove Loopback mode for normal operation (obviously) */ Status = XSpi_SetOptions(SpiInstancePtr, XSP_MASTER_OPTION);// | XSP_LOOPBACK_OPTION); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the SPI driver so that the device is enabled. */ XSpi_Start(SpiInstancePtr); /* * For the slave to make active, set the SlaveSelectReg to have a value * where the bit corresponding to the desired slave is a '0' and all * other bits are '1'. */ SpiInstancePtr->SlaveSelectReg = 0x02; // ZZZ /* * Disable Global interrupt to use polled mode operation */ XSpi_IntrGlobalDisable(SpiInstancePtr); /* * Initialize the write buffer with pattern to write, initialize the * read buffer to zero so it can be verified after the read, the * Test value that is added to the unique value allows the value to be * changed in a debug environment. */ Test = 0x10; for (Count = 0; Count < BUFFER_SIZE; Count++) { WriteBuffer[Count] = (u8)(Count + Test); ReadBuffer[Count] = 0; } /* * Transmit the data. */ XSpi_Transfer(SpiInstancePtr, WriteBuffer, ReadBuffer, BUFFER_SIZE);
  21. engrpetero

    Zynq SPI0 - EMIO

    Yes, my real question was about the source for the initial 50MHz clock. The Frequency ratio divisor of 2, 8, 16 shows that it works exactly as the IP documentation suggests and uses a 50MHz clock as its source. I was curious the 50MHz clock hence my pic of the Zynq clocks posted above. The block diagram - which I should have looked at earlier - makes this abundantly clear. As usual, the solution to this problem turned out to be shockingly simple. But the driver docs could certainly be updated to make it easier for people to figure out in the future. This took a little longer as well due to my learning how to use the Digital Discovery to look at SPI signals. I am very happy with all the Digilent products I have and am very thankful to the Digilent folks who help out on the message board. However, I think the helpful DD/Waveforms documentation could be augmented with some examples (or perhaps I've just missed them).
  22. engrpetero

    Zynq SPI0 - EMIO

    Thank you very much for sharing. I'll certainly take a look!
  23. engrpetero

    Zynq SPI0 - EMIO

    Interesting, @Viktor Nikolov. I changed the value in the Vivado IP dialog (first pic) from 16 (my successful test above) to 8 and the clock frequency I measure with the DD (essentially a scope) is twice as fast and still results in a undivided clock frequency of 50MHz (second pic). I'm currently only using a slightly modified version of the xspi_polled_example project so there is (at least no obvious) modifying of any clock. On the vivado side, I've just 'run automation' to connect the zynq to all axi peripherals.
  24. engrpetero

    Zynq SPI0 - EMIO

    Well good gracious. I finally got something working - at least I'm seeing transmissions on the original QSPI now. I'd almost like to offer to update the Xilinx docs! :-) I'll trouble you gents for a few more pieces of info though, please, if you have answers or experience. For the AXI Quad SPI (version 3.2), looking at the documentation, it seems the SPI output clock frequency is the AXI clock frequency divided by the 'Frequency Ratio'. If I use a Frequency ration of 16, it appears the output clock pulses happen about every .332 us which would correspond to an undivided frequency of 50MHz. From my review, it *seems* the AXI clock frequency is this one?
  25. engrpetero

    Zynq SPI0 - EMIO

    I had not seen this on the Zynq block. Thanks for pointing it out. I really intended to just do a test to see if I could see ANYTHING on the Zynq SPI_0. I'll try that anyway with a simple new project that just includes the interface pins CS, SCK, MISO, MOSI for the SPI port on the Zybo I have. I also just realized that I'll still be using Xilinx drivers from Vitis. Maybe they will be easier to use. I'd love to see an SPI transmission received on the DD just so I know what to expect. Then I can go back to the QSPI driver and continue plodding. Thanks @artvvb!
×
×
  • Create New...