Nystflame

Members
  • Content Count

    13
  • Joined

  • Last visited

About Nystflame

  • Rank
    Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. @jpeyron After looking further into this, I had finally figured out what the issue was but forgot to post what I had found on here. I managed to get the ILA working, and had observed the AXI interaction between the DMA and some of the other IP in my project. What I had found was that the DMA had not be 'setup' with enough time before actual data had been streaming. The AXI DMA Product guide explains it better by this quote: This explains why the first 4 ADC samples I had seemed off, and after those samples the data was good. In the end, I've learned yet again that most questions I have can be answered in these user guides, I just don't have enough experience yet to know where to always look Cheers, nystflame
  2. Nystflame

    AXI DMA and Microblaze

    Hello All, I seem to be having an issue that I cannot quite track down the cause of... My overall goal is that I would like to write ADC samples into DDR memory via a DMA. I am able to DMA samples into the DDR successfully, except that the first couple values in DDR are incorrect. I've noticed that if I aquire some samples, and read the DDR, the first 4 are old samples which seem to update the next time I do an acquisition of ADC samples. I've also noticed that after the first DMA transfer, if I read the s2mm_length register, it seems to be a few transfers short of what I programmed the transfer length to be. But if I do another transfer, and all subsequent transfers from then on, they seem to be equal to the length which was programmed. I initially thought that this was a caching issue (and still may be), but I've since disabled caching in the software. I've also provided an image below of my Microblaze, and to my understanding there is no caching enabled (i've disabled cache when configuring the Microblaze in vivado). The type of DMA transfer that I am using is just a register direct transfer, not scatter gather. The M_AXI_DP is connected to an AXI Interconnect, of which the M_AXI port of the interconnect is connected to the S_AXI_LITE port of the DMA. Another interesting thing I've noticed is that, if I do an acquisition of ADC samples, read the DDR starting at address 0, and perform another read of DDR starting at address 0, it looks like the data at address 0 updates, but the following data is the same as the first read. P.S. I am still new to Digital Design, sorry if I've omitted any crucial information.
  3. @D@n , I appreciate all of the help. I've changed from pins[0] to *pins, and declared two registers and initialized them to 0 and 1, but it doesn't seem to have had any affect on the speed. Maybe it is the I/O speed as you suggested. Also, the microblaze is currently configured for "performance" mode, which enables the 5 stage pipeline. I've attached the new assembly code, and it looks like it's still the same number of instructions. Best Regards, nystflame newAsmCode.txt
  4. Thank you both for your responses, i'll try my best to answer them individually: @jpeyron : Attached is a image of my block diagram. @D@n : Please see attached for assembly code. 1. I configured the microblaze with 32KB of instruction cache and data cache, and my program is running from the block memory onboard. 2. I hadn't turned on optimizations, but I believe I have that "-O3" option enabled now in the makefile. It increased the speed from 1.333MHz to 1.538MHz. 3. I've made them constants and the speed is still the same. 4. Setting the pin to 1 and then to 0 does actually speed up the program from 1.538MHz to 3.571MHz, so that's a pretty big improvement. 5. I've attached the assembly code (from the .elf file) which has the program within it. It seems like prior to setting the pin manually to 1 or 0, the xor command took 6 assembly instructions. With the manual setting of the pin, it takes 6 assembly instructions as well. (Both of these are including branching to the top of the loop). When stepping through the look in the SDK, it only highlights 3 assembly instructions though for setting the pin which is load word immediate (2, one or setting the pin to 1 and another for setting back to 0), and the 3rd instruction is branching immediate (to the top of the loop) Thank you both very much for the help! here is an update of my current code: #include "platform.h" #include "xil_printf.h" #include "xgpio.h" XGpio Gpio; /* The Instance of the GPIO Driver */ int main(void) { int Status; Status = XGpio_Initialize(&Gpio, 0); if (Status != XST_SUCCESS) { xil_printf("Gpio Initialization Failed\r\n"); return XST_FAILURE; } XGpio_SetDataDirection(&Gpio, 1, ~0x01); init_platform(); volatile unsigned* const pins = (volatile unsigned* const) 0x40000000; for(;;){ //pins[0] = pins[0] ^ 0x01; pins[0] = 1; pins[0] = 0; } cleanup_platform(); } Best Regards, nystflame assemblyCode.txt
  5. Hello, Without implementing a timer, I had thought that toggling a GPIO pin and observing the result via a logic analyzer(has 100Megasample/sec). The Microblaze input clock is coming from the "ui_clk" from the MIG, which seems to be 83 MHz, but when observing the pin toggle the frequency is ~37 kHz. My method for toggling the pin is just an infinite while loop with two Xil_Out32 commands, one for turning the pin on, and the other command turns it off. Any debugging methods I should try as to why the frequency of this switching is so low? p.s. I've since moved from toggling via the xil_out function and am targeting the address of the GPIO pins directly, the frequency I'm seeing now is 130.7kHz, still nowhere near the 80MHz I had been expecting. p.s.s. I've enabled caches and tried block ram vs ddr and the max i've gotten to is 1.3Mhz The following is all of the code in my program for this test: #include "platform.h" int main(void) { init_platform(); volatile unsigned int *pins = (volatile unsigned int *) 0x40000000; for(;;){ pins[0] ^= 0x1; } cleanup_platform(); } Best Regards, nystflame
  6. @jpeyron Thank you very much for all of his help! It's working great now for me after following what you had done. The voltage readings were off on the A0-A5 inputs because the function in the code you provided for calculating the raw to voltage is using 1.0V instead of 3.3V as the circuit suggests in the schematic you provided above.
  7. Hello, I am using the microblaze system with the xadc on an Arty board. I'm able to successfully read the internal voltages and temperatures of the chip, and I made some external pins (such as the VP/VN and Vauxp0 and Vauxn0). The pins which are external have been connected in a constraints file. My power supply positive terminal is hooked into the A0 port on my arty board, and the negative terminal is hooked into a gnd port. The XADC is attached to the AXI lite bus, controlled by the microblaze. Please let me know if any of this is unclear. P.S. I've looked into the spec sheets but am still a beginner so I'm not always successful finding the right information. Greatly appreciate the help! Nystflame
  8. @jpeyron, okay, thank you for the help! Best Regards, nystflame
  9. @jpeyron , I have since followed the steps outlined in the quad spi reference guide, and have had better success with transfers. Also, the core is configured in slave mode. I do have one main question now though.. Is the data transmit register double buffered? It doesn't say that it is in the IP quad spi reference guide, it only says the receive register is double buffered... It seems though that the transmit register loads two of the 16 bit half words that i'm trying to transfer.
  10. @jpeyron , Thanks for the info! I also managed to get the j6 header working... I hadn't made the correct pins external in the block designer and created the appropriate constraints file to attach the external pins to the physical pins on the header.
  11. Hello, I'm having some issues with multiple (16bit) transactions while holding slave select low. I'm using the example master polling spi code from the xilinx SDK, and have manual slave select working where it holds the SS line low while performing the multiple transactions, and once finish it goes high again. My issue is that i'm trying to make a simple slave which can write to a register continuously if it receives a write command from the master, and then if a read command is sent from the master, the slave will send back whatever is in the designated register requested by the master. Is the data transmit register also a double buffer? My main objectve is to receive the read command, and start transferring the data on the next group of SCK pulses but right now it seems to be delayed by two transactions. The image attached shows more of what i'm trying to accomplish. the high bit of the 16 bits is a read/write(1 is write, 0 is read) command, and the lower bits are a register address. so the final result of the first 3 transactions should result in register 5 having the value (0x8009), which it does, but when the next transfer happens, the 0x0005 command should be indicating a read of register 5 and output on the miso line 0x8009 on the 2nd transaction (i.e. when MOSI is 0x0007 i want MISO to have 0x8009). Also this is my current code: /***************************** Include Files **********************************/ #include "xparameters.h" #include "xstatus.h" #include "xspi_l.h" #include "xil_printf.h" /************************** Constant Definitions ******************************/ /* * The following constants map to the XPAR parameters created in the * xparameters.h file. They are defined here such that a user can easily * change all the needed parameters in one place. */ #define SPI_BASEADDR XPAR_SPI_0_BASEADDR /**************************** Type Definitions ********************************/ /***************** Macros (Inline Functions) Definitions **********************/ /************************** Function Prototypes *******************************/ /************************** Variable Definitions ******************************/ /* * This is the size of the buffer to be transmitted/received in this example. */ #define BUFFER_SIZE 16 /* * The buffer used for Transmission/Reception of the SPI test data */ u16 Buffer[BUFFER_SIZE]; /* * This buffer is used to simulate a register bank. */ u16 regBank[64]; /******************************************************************************/ /** * This function is the main function of the SPI Low Level example. * * @param None * * @return XST_SUCCESS to indicate success, else XST_FAILURE to indicate * Failure. * * @note None * *******************************************************************************/ int main(void) { //int transferCounter = 0; u32 BaseAddress = SPI_BASEADDR; u16 addressMask = 0; u32 StatusReg = 0; u32 NumBytesRcvd = 0; u32 NumBytesSent = 0; u8 addressFlag = 0; u16 tester = 0; //Enable GIER XSpi_WriteReg(BaseAddress, XSP_DGIER_OFFSET, 0x0/*XSP_GINTR_ENABLE_MASK*/); for(int i = 0; i < 65; i++){ regBank = 0xBEEF; } for(int i = 0; i < BUFFER_SIZE; i++){ Buffer = 0x0; } //Configure IPIER XSpi_WriteReg(BaseAddress, XSP_IIER_OFFSET, 0x0 /*XSP_INTR_SLAVE_MODE_MASK | XSP_INTR_RX_OVERRUN_MASK | XSP_INTR_RX_FULL_MASK | XSP_INTR_TX_UNDERRUN_MASK | XSP_INTR_TX_EMPTY_MASK | XSP_INTR_SLAVE_MODE_FAULT_MASK | XSP_INTR_MODE_FAULT_MASK*/); //Configure SPICR XSpi_WriteReg(BaseAddress, XSP_CR_OFFSET, XSP_CR_ENABLE_MASK); //Write data to the SPI DTR XSpi_WriteReg(BaseAddress, XSP_DTR_OFFSET, 0xDEAD); xil_printf("setup registers hi\r\n"); while(1){ if(NumBytesRcvd == 4){ for(int i = 0; i < BUFFER_SIZE; i++){ xil_printf("buffer: 0x%x regBank: 0x%x addressmask: %d\r\n", Buffer, regBank , addressMask); } } NumBytesSent = 0; NumBytesRcvd = 0; addressMask = 0; if((XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) & XSP_SR_SLAVE_MODE_MASK) == 0){ /* * Fill up the transmitter with data, assuming the receiver can hold * the same amount of data. */ while ((XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) & XSP_SR_TX_FULL_MASK) == 0) { XSpi_WriteReg((BaseAddress), XSP_DTR_OFFSET, Buffer[NumBytesSent++]); } /* * Wait for the transmit FIFO to transition to empty before checking * the receive FIFO, this prevents a fast processor from seeing the * receive FIFO as empty */ while (!(XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) & XSP_SR_TX_EMPTY_MASK)); /* * Transmitter is full, now receive the data just looped back until * the receiver is empty. */ while ((XSpi_ReadReg(BaseAddress, XSP_SR_OFFSET) & XSP_SR_RX_EMPTY_MASK) == 0) { Buffer[NumBytesRcvd++] = XSpi_ReadReg((BaseAddress), XSP_DRR_OFFSET); } if(Buffer[0] & 0x8000){ addressMask = Buffer[0] & 0x00FF; regBank[addressMask] = Buffer[0]; }else{ addressMask = Buffer[0] & 0x00FF; XSpi_WriteReg((BaseAddress), XSP_DTR_OFFSET, regBank[addressMask]); } } } for(int i = 0; i < BUFFER_SIZE; i++){ xil_printf("buffer: 0x%x regBank: 0x%x addressmask: %d\r\n", Buffer, regBank , addressMask); } } Greatly appreciate the help! Nystflame
  12. Hi @jpeyron, I appreciate you looking into this with me. I look forward to what you find, and am looking into what you've posted. Still no luck on my end though. Regards, Nystflame
  13. Hello, I'm having trouble understanding how to address the J6 header on the Arty board. I've been able to interact with the GPIO registers to toggle other ChipKit shield pins as well as toggle all of the led's. When generating the project, I see that the base address for SPI in my project is at 0x44a00000 with high address being 0x44a0FFFF. I don't understand where in that memory the J6 header is, and am unable to find any resources with the answer. It might also be good to note that I generated the IP block by dragging and dropping the "SPI connector J6" from the Board section of the IP design. I've looked into the implemented design and see that the spi_io0_io, spi_io1_io, spi_ss_io, and spi_sck_io are connected correctly according to the arty schematic, I'm just unsure how to do SPI transfers over these pins (my logic analyzer doesn't show any activity when doing transfers). Regards, Nystflame