Jump to content

engrpetero

Members
  • Posts

    150
  • Joined

  • Last visited

Reputation Activity

  1. Like
    engrpetero got a reaction from artvvb in XADC Example with Vivado block diagram?   
    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.
     
     
  2. Like
    engrpetero got a reaction from artvvb in Multiple Displays   
    I never thanked you for the reply, @artvvb.  Certainly appreciate it.
     
  3. Like
    engrpetero got a reaction from attila in Digital Discovery - Zybo interaction   
    That sounds reasonable.  I was playing with many different items still learning how best to use the DD.  Thanks @attila.
  4. Like
    engrpetero got a reaction from attila in Digital Discovery - Script Question 2   
    Well, heck, I missed that.  Works now.  Thanks @attila. :-)
  5. Like
    engrpetero got a reaction from attila in Digital Discovery - Step Back   
    Excellent.  Making good progress now.  Thanks again for the help, @attila.
  6. Like
    engrpetero got a reaction from artvvb in Multiple PS Uart Interrupts not seen   
    Boy did I sorely misunderstand the intent of the Xilinx code related to interrupt processing on the Uarts.  Here's what I learned through debugging (though I still see a few odd things with the debugger).  Again, I imagine most people figured this out on their own but just in case someone is reading in the future, maybe they find this useful.  Much of the code is similar or identical to what is in the example interrupt application, but I may have formatted it differently or made minor changes (to the interrupt mask, for example).
    At the top of my file...
    #define TEST_BUFFER_SIZE 12 static u8 DebugRecvBuffer[TEST_BUFFER_SIZE]; /* Buffer for Receiving Data */ The first code window below is my function that initializes the Uart. 
    Note in step 4 the stuff to set the format that is commented out.  Those are the default settings anyway so they aren't needed, just there to show how to reset and to comment that the Uart needs to be disabled before changing the baud rate. Also note that mask that is being set which will interrupt on XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR (so when the receive FIFO is full or when the receive FIFO is above the interrupt threshold (which is set to 5 in the call to XUartPs_SetFifoThreshold)).  
    Note in step 5 that the XUartPs_InterruptHandler mentioned is part if the XUartPs software - not the user ISR and it this line shouldn't be changed.  Some comments about that function (XUartPs_InterruptHandler) later.
    Note in step 6 that this is where the user ISR is set (my ISR function is called UartISR).
    Finally note in step 8 that the function XUartPs_Recv() is called.  Calling this function resets the XUartPs ReceiveBuffer items (RequestedBytes, RemainingBytes, and NextPtr).  This is important because the user ISR is only called when the ReceiveBuffer is full.
    So with this init function, every time 5 bytes are received, the XUartPs_InterruptHandler is called by the processor.  And every time 12 bytes are received (TEST_BUFFER_SIZE), the user ISR is called (essentially by the XUartPs_InterruptHandler() function).
    int InitUart(XScuGic *ptrGic, XUartPs *ptrUart, u16 UartDeviceId, u16 UartInterruptId) { int Status; u32 IntrMask; XUartPs_Config *ptrConfig; /* --------------------------------------------------------------------- * ------------ STEP 1: DEVICE LOOK-UP ------------ * -------------------------------------------------------------------- */ ptrConfig = XUartPs_LookupConfig(UartDeviceId); if (ptrConfig == NULL) {return XST_FAILURE;} /* --------------------------------------------------------------------- * ------------ STEP 2: DRIVER INITIALIZATION ------------ * -------------------------------------------------------------------- */ Status = XUartPs_CfgInitialize(ptrUart, ptrConfig, ptrConfig->BaseAddress); if (Status != XST_SUCCESS) {return XST_FAILURE;} /* --------------------------------------------------------------------- * ------------ STEP 3: SELF TEST ------------ * -------------------------------------------------------------------- */ Status = XUartPs_SelfTest(ptrUart); if (Status != XST_SUCCESS) {return XST_FAILURE;} /* --------------------------------------------------------------------- * ------------ STEP 4: PROJECT-SPECIFIC CONFIGURATION ------------ * -------------------------------------------------------------------- */ XUartPs_DisableUart(ptrUart); // UG5985 says to make sure the UART is disabled before writing to baud rate gen // XUartPsFormat psFormat; // psFormat.BaudRate = 115200; // psFormat.DataBits = XUARTPS_FORMAT_8_BITS; // psFormat.Parity = XUARTPS_MR_PARITY_NONE; // psFormat.StopBits = XUARTPS_MR_STOPMODE_1_BIT; // XUartPs_SetDataFormat(ptrUart, &psFormat); //IntrMask = XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXEMPTY | XUARTPS_IXR_RXOVR; IntrMask = XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR; XUartPs_SetInterruptMask(ptrUart, IntrMask); XUartPs_SetOperMode(ptrUart, XUARTPS_OPER_MODE_NORMAL); XUartPs_SetFifoThreshold(ptrUart, 5); // After this value, the RXOVR interrupt will hit the XUartPs_InterruptHandler /* --------------------------------------------------------------------- * ------------ STEP 5: ADD TO INTERUPT SYSTEM ------------ * -------------------------------------------------------------------- */ Status = XScuGic_Connect(ptrGic, UartInterruptId, (Xil_ExceptionHandler)XUartPs_InterruptHandler, (void *)ptrUart); if (Status != XST_SUCCESS) {return Status;} /* --------------------------------------------------------------------- * ------------ STEP 6: SET A HANDLER TO BE CALLED(back) WHEN EVENT OCCURS ------------ * -------------------------------------------------------------------- */ XUartPs_SetHandler(ptrUart, (XUartPs_Handler)UartISR, (void *)ptrUart); /* --------------------------------------------------------------------- * ------------ STEP 7: ENABLE THE INTERRUPT ------------ * -------------------------------------------------------------------- */ XScuGic_Enable(ptrGic, UartInterruptId); /* --------------------------------------------------------------------- * ------------ STEP 8: ENABLE THE UART ------------ * -------------------------------------------------------------------- */ XUartPs_EnableUart(ptrUart); /* --------------------------------------------------------------------- * ------------ STEP 8: RESET RECEIVEBUFFER ITEMS ------------ * -------------------------------------------------------------------- */ // Reset the ptrUart.ReceiveBuffer items (RequestedBytes, RemainingBytes, and NextPtr) // This is needed to eventually allow the user ISR to be called. XUartPs_Recv(ptrUart, DebugRecvBuffer, TEST_BUFFER_SIZE); // After TEST_BUFFER_SIZE bytes are received, the user ISR will hit. return XST_SUCCESS; } Quick look at XUartPs_Recv()...  The main thing to note (at least to me) is that before calling the XUartPs_ReceiveBuffer() function, this function resets the RequestedBytes , RemainingBytes, and NextBytePtr values).  This is important because the user ISR is only called when the RemainingBytes counter reaches 0.
    u32 XUartPs_Recv(XUartPs *InstancePtr, u8 *BufferPtr, u32 NumBytes) { u32 ReceivedCount; u32 ImrRegister; /* Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(BufferPtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); #if defined (XCLOCKING) Xil_ClockEnable(InstancePtr->Config.RefClk); #endif /* * Disable all the interrupts. * This stops a previous operation that may be interrupt driven */ ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK); /* Setup the buffer parameters */ InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr; /* Receive the data from the device */ ReceivedCount = XUartPs_ReceiveBuffer(InstancePtr); /* Restore the interrupt state */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, ImrRegister); return ReceivedCount; } The XUartPs_ReceiveBuffer() function isn't that interesting.  It really just fills the buffer from the Uart's FIFO (and it will call the user ISR if there is a frame error) so I didn't post it here (easy enough to look at yourself).
    Similarly, the XUartPs_InterruptHandler() function isn't worth posting here - it's pretty straightforward and just looks at the interrupt that happened before calling one of several other functions depending on the interrupt type.  One of those functions I do show next though: ReceiveDataHandler().
    Note that this function - besides getting any characters that are new since the interrupt happened with the call to XUartPs_ReceiveBuffer() - is responsible for calling the user ISR once the remaining bytes int he user's receive buffer (size TEST_BUFFER_SIZE in my case) reaches 0.  Also to note that no additional calls to the user ISR will happen unless the ReceiveBuffer items are reset with a new call to XUartPs_Recv().  The skeleton of my user ISR is shown at the end.
    static void ReceiveDataHandler(XUartPs *InstancePtr) { /* * If there are bytes still to be received in the specified buffer * go ahead and receive them. Removing bytes from the RX FIFO will * clear the interrupt. */ if (InstancePtr->ReceiveBuffer.RemainingBytes != (u32)0) { (void)XUartPs_ReceiveBuffer(InstancePtr); } /* If the last byte of a message was received then call the application * handler, this code should not use an else from the previous check of * the number of bytes to receive because the call to receive the buffer * updates the bytes ramained */ if (InstancePtr->ReceiveBuffer.RemainingBytes == (u32)0) { InstancePtr->Handler(InstancePtr->CallBackRef, XUARTPS_EVENT_RECV_DATA, (InstancePtr->ReceiveBuffer.RequestedBytes - InstancePtr->ReceiveBuffer.RemainingBytes)); } } My user ISR skeleton.  Note the call at the end to XUartPs_Recv() to reset the ReceiveBuffer items so this ISR will eventually be called again.  Also note the //! lines which is the place something should be done with the info in the user ReceiveBuffer before we reset it.
    void UartISR(void *CallBackRef, u32 Event, unsigned int EventData) { XUartPs *ptrSenderXUart = (XUartPs *) CallBackRef; // Send some relevant info about the event to the stdio xil_printf("ISR: Event: %i, EventData: %i, Remaining: %i, NextPtr: 0x%X\r\n", Event, EventData, ptrSenderXUart->ReceiveBuffer.RemainingBytes, &ptrSenderXUart->ReceiveBuffer.NextBytePtr); // Do something with the DebugRecvBuffer because we are about to reset it... //! //! //! // Reset the ReceiveBuffer items so this ISR will be called again XUartPs_Recv(ptrSenderXUart, DebugRecvBuffer, TEST_BUFFER_SIZE); } Now I haven't yet decided how best to use this info for the circumstance I mentioned with my 5 and 27 byte expected messages.  But I'm closer.  I hope someone else finds this useful.  It was useful for me to type, either way. :-)
  7. Like
    engrpetero got a reaction from artvvb in putting pieces together and Vivado icons   
    Thanks, Arthur.  Adding the files to the File Groups as you suggested fixed the issue and allowed the instantiation and at least got by the initial errors with synthesis (I had already added them to the Sources but that hadn't fixed the problem).  There are other errors - but I can move on to tackling those.  Your help much appreciated.
  8. Like
    engrpetero got a reaction from drkome in Can UART communication be made from any pin of zybo z-7-10   
    This subject is near and dear to my Zybo learning exercise lately so I thought I'd add an additional comment.  The Zynq PS block does have an unused UART (mentioned by @zygot with the mentioned FIFO limitations) that can be connected to MIO pins exposed on the Zybo JF connector (bypassing the PL, if desired).  Of course, to use xil_printf for both UART0 and UART1, some Vitis code changes are needed (seemingly straightforward since the xil_printf functions are easy to duplicate).
×
×
  • Create New...