int main(void) { u32 *vgaPtr[DISPLAY_NUM_FRAMES]; u32 *hdmiPtr[DISPLAY_NUM_FRAMES]; int i; char userInput = 0; for (i = 0; i < DISPLAY_NUM_FRAMES; i++) { vgaPtr[i] = vgaBuf[i]; hdmiPtr[i] = hdmiBuf[i]; } DisplayDemoInitialize(&vgaCtrl, VGA_VDMA_ID, SCU_TIMER_ID, VGA_BASEADDR, DISPLAY_NOT_HDMI, vgaPtr); DisplayDemoInitialize(&hdmiCtrl, HDMI_VDMA_ID, SCU_TIMER_ID, HDMI_BASEADDR, DISPLAY_HDMI, hdmiPtr); AudioInitialize(SCU_TIMER_ID, AUDIO_IIC_ID, AUDIO_CTRL_BASEADDR); TimerInitialize(SCU_TIMER_ID); /* Flush UART FIFO */ while (XUartPs_IsReceiveData(UART_BASEADDR)) { XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET); } while (userInput != 'q') { MainDemoPrintMenu(); /* Wait for data on UART */ while (!XUartPs_IsReceiveData(UART_BASEADDR)) {} /* Store the first character in the UART recieve FIFO and echo it */ userInput = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET); xil_printf("%c", userInput); switch (userInput) { case '1': AudioRunDemo(AUDIO_CTRL_BASEADDR, UART_BASEADDR, SW_BASEADDR, BTN_BASEADDR); break; case '2': DisplayDemoRun(&vgaCtrl, UART_BASEADDR); break; case '3': DisplayDemoRun(&hdmiCtrl, UART_BASEADDR); break; case 'q': break; default : xil_printf("\n\rInvalid Selection"); TimerDelay(500000); } } return 0; }
/** * * This function is the interrupt handler for the driver. * It must be connected to an interrupt system by the application such that it * can be called when an interrupt occurs. * * @param InstancePtr contains a pointer to the driver instance * * @return None. * * @note None. * ******************************************************************************/ void XUartPs_InterruptHandler(XUartPs *InstancePtr) { u32 IsrStatus; Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the interrupt ID register to determine which * interrupt is active */ IsrStatus = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET); IsrStatus &= XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET); /* * Dispatch an appropriate handler. */ if((IsrStatus & ((u32)XUARTPS_IXR_RXOVR | (u32)XUARTPS_IXR_RXEMPTY | (u32)XUARTPS_IXR_RXFULL)) != (u32)0) { /* Received data interrupt */ ReceiveDataHandler(InstancePtr); } if((IsrStatus & ((u32)XUARTPS_IXR_TXEMPTY | (u32)XUARTPS_IXR_TXFULL)) != (u32)0) { /* Transmit data interrupt */ SendDataHandler(InstancePtr, IsrStatus); } if((IsrStatus & ((u32)XUARTPS_IXR_OVER | (u32)XUARTPS_IXR_FRAMING | (u32)XUARTPS_IXR_PARITY)) != (u32)0) { /* Received Error Status interrupt */ ReceiveErrorHandler(InstancePtr); } if((IsrStatus & ((u32)XUARTPS_IXR_TOUT)) != (u32)0) { /* Received Timeout interrupt */ ReceiveTimeoutHandler(InstancePtr); } if((IsrStatus & ((u32)XUARTPS_IXR_DMS)) != (u32)0) { /* Modem status interrupt */ ModemHandler(InstancePtr); } /* * Clear the interrupt status. */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_ISR_OFFSET, IsrStatus); }
u32 XUartPs_IsReceiving(XUartPs *InstancePtr) { u32 ChanStatRegister; u32 ChanTmpSRegister; u32 ActiveResult; u32 EmptyResult; /* Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Read the channel status register to determine if the receiver is * active */ ChanStatRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET); /* * If the receiver is active, or the RX FIFO is not empty, then indicate * that the UART is still receiving some data */ ActiveResult = ChanStatRegister & ((u32)XUARTPS_SR_RACTIVE); EmptyResult = ChanStatRegister & ((u32)XUARTPS_SR_RXEMPTY); ChanTmpSRegister = (((u32)XUARTPS_SR_RACTIVE) == ActiveResult) || (((u32)XUARTPS_SR_RXEMPTY) != EmptyResult); return ChanTmpSRegister; }
/** * * This function gets the interrupt mask * * @param InstancePtr is a pointer to the XUartPs instance. * * @return * The current interrupt mask. The mask indicates which interupts * are enabled. * * @note None. * *****************************************************************************/ u32 XUartPs_GetInterruptMask(XUartPs *InstancePtr) { /* Assert validates the input argument */ Xil_AssertNonvoid(InstancePtr != NULL); /* Read the Interrupt Mask register */ return (XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET)); }
/* ---------------------------------------------------------------------------- * * menu() * * ---------------------------------------------------------------------------- * * Presented at system startup. Allows the user to select between three * options by pressing certain keys on the keyboard: * 's' - Audio loopback streaming * 'n' - Tonal noise is generated by an NCO and added to the audio * being captured from the audio codec. * 'f' - The audio + tonal noise is passed to an adaptive LMS noise * cancellation filter which will use the tonal noise estimate * to remove the noise from the audio. * * This menu is shown upon exiting from any of the above options. * ---------------------------------------------------------------------------- */ void menu(){ u8 inp = 0x00; u32 CntrlRegister; /* Turn off all LEDs */ Xil_Out32(LED_BASE, 0); CntrlRegister = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_CR_OFFSET); XUartPs_WriteReg(UART_BASEADDR, XUARTPS_CR_OFFSET, ((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) | XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN)); xil_printf("\r\n\r\n"); xil_printf("Embedded LMS Filtering Demo\r\n"); xil_printf("Enter 's' to stream pure audio, 'n' to add tonal noise and 'f' to adaptively filter\r\n"); xil_printf("----------------------------------------\r\n"); // Wait for input from UART via the terminal while (!XUartPs_IsReceiveData(UART_BASEADDR)); inp = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET); // Select function based on UART input switch(inp){ case 's': xil_printf("STREAMING AUDIO\r\n"); xil_printf("Press 'q' to return to the main menu\r\n"); audio_stream(); break; case 'n': xil_printf("ENTERING NOISE GENERATION OPERATION\r\n"); xil_printf("Select step size via the DIP switches...\r\n\n"); xil_printf("Press 'q' to return to the main menu\r\n"); tonal_noise(); break; case 'f': xil_printf("ENTERING LMS FILTERING OPERATION\r\n"); xil_printf("Press 'q' to return to the main menu\r\n"); lms_filter(); break; default: menu(); break; } // switch } // menu()
char readUART(u32 uartAddress){ char userInput; /* Wait for data on UART */ while (!XUartPs_IsReceiveData(uartAddress)) {} /* Store the first character in the UART recieve FIFO and echo it */ userInput = XUartPs_ReadReg(uartAddress, XUARTPS_FIFO_OFFSET); xil_printf("%c", userInput); return userInput; }
/* * * This function receives a buffer that has been previously specified by setting * up the instance variables of the instance. This function is an internal * function, and it may be called from a shell function that sets up the buffer * or from an interrupt handler. * * This function attempts to receive a specified number of bytes from the * device and store it into the specified buffer. This function works for * either polled or interrupt driven modes. It is non-blocking. * * In polled mode, this function only receives as much data as in the RX FIFO. * The application may need to call it repeatedly to receive the entire buffer. * Polled mode is the default mode for the driver. * * In interrupt mode, this function starts the receiving, if not the entire * buffer has been received, the interrupt handler will continue until the * entire buffer has been received. A callback function, as specified by the * application, will be called to indicate the completion of the receiving or * error conditions. * * @param InstancePtr is a pointer to the XUartPs instance * * @return The number of bytes received. * * @note None. * *****************************************************************************/ u32 XUartPs_ReceiveBuffer(XUartPs *InstancePtr) { u32 CsrRegister; u32 ReceivedCount = 0U; /* * Read the Channel Status Register to determine if there is any data in * the RX FIFO */ CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET); /* * Loop until there is no more data in RX FIFO or the specified * number of bytes has been received */ while((ReceivedCount < InstancePtr->ReceiveBuffer.RemainingBytes)&& (((CsrRegister & XUARTPS_SR_RXEMPTY) == (u32)0))){ InstancePtr->ReceiveBuffer.NextBytePtr[ReceivedCount] = XUartPs_ReadReg(InstancePtr->Config. BaseAddress, XUARTPS_FIFO_OFFSET); ReceivedCount++; CsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_SR_OFFSET); } /* * Update the receive buffer to reflect the number of bytes just * received */ if(InstancePtr->ReceiveBuffer.NextBytePtr != NULL){ InstancePtr->ReceiveBuffer.NextBytePtr += ReceivedCount; } InstancePtr->ReceiveBuffer.RemainingBytes -= ReceivedCount; return ReceivedCount; }
/** * * This function receives a byte from the device. It operates in polled mode * and blocks until a byte has received. * * @param BaseAddress contains the base address of the device. * * @return The data byte received. * * @note None. * *****************************************************************************/ u8 XUartPs_RecvByte(u32 BaseAddress) { /* * Wait until there is data */ while (!XUartPs_IsReceiveData(BaseAddress)); /* * Return the byte received */ return (XUartPs_ReadReg(BaseAddress, XUARTPS_FIFO_OFFSET)); }
/* * * This function sends a buffer that has been previously specified by setting * up the instance variables of the instance. This function is an internal * function for the XUartPs driver such that it may be called from a shell * function that sets up the buffer or from an interrupt handler. * * This function sends the specified buffer in either polled or interrupt * driven modes. This function is non-blocking. * * In a polled mode, this function only sends as much data as the TX FIFO * can buffer. The application may need to call it repeatedly to send the * entire buffer. * * In interrupt mode, this function starts the sending of the buffer, if not * the entire buffer has been sent, then the interrupt handler continues the * sending until the entire buffer has been sent. A callback function, as * specified by the application, will be called to indicate the completion of * sending. * * @param InstancePtr is a pointer to the XUartPs instance * * @return The number of bytes actually sent * * @note None. * *****************************************************************************/ u32 XUartPs_SendBuffer(XUartPs *InstancePtr) { u32 SentCount = 0U; u32 ImrRegister; /* * If the TX FIFO is full, send nothing. * Otherwise put bytes into the TX FIFO unil it is full, or all of the * data has been put into the FIFO. */ while ((!XUartPs_IsTransmitFull(InstancePtr->Config.BaseAddress)) && (InstancePtr->SendBuffer.RemainingBytes > SentCount)) { /* * Fill the FIFO from the buffer */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_FIFO_OFFSET, ((u32)InstancePtr->SendBuffer. NextBytePtr[SentCount])); /* * Increment the send count. */ SentCount++; } /* * Update the buffer to reflect the bytes that were sent from it */ InstancePtr->SendBuffer.NextBytePtr += SentCount; InstancePtr->SendBuffer.RemainingBytes -= SentCount; /* * If interrupts are enabled as indicated by the receive interrupt, then * enable the TX FIFO empty interrupt, so further action can be taken * for this sending. */ ImrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET); if (((ImrRegister & XUARTPS_IXR_RXFULL) != (u32)0) || ((ImrRegister & XUARTPS_IXR_RXEMPTY) != (u32)0)|| ((ImrRegister & XUARTPS_IXR_RXOVR) != (u32)0)) { XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, ImrRegister | (u32)XUARTPS_IXR_TXEMPTY); } return SentCount; }
/** * * This function attempts to receive a specified number of bytes of data * from the device and store it into the specified buffer. This function works * for both polled or interrupt driven modes. It is non-blocking. * * In a polled mode, this function will only receive the data already in the * RX FIFO. The application may need to call it repeatedly to receive the * entire buffer. Polled mode is the default mode of operation for the device. * * In interrupt mode, this function will start the receiving, if not the entire * buffer has been received, the interrupt handler will continue receiving data * until the entire buffer has been received. A callback function, as specified * by the application, will be called to indicate the completion of the * receiving or error conditions. * * @param InstancePtr is a pointer to the XUartPs instance * @param BufferPtr is pointer to buffer for data to be received into * @param NumBytes is the number of bytes to be received. A value of zero * will stop a previous receive operation that is in progress in * interrupt mode. * * @return The number of bytes received. * * @note * * The number of bytes is not asserted so that this function may be called * with a value of zero to stop an operation that is already in progress. * *****************************************************************************/ 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); /* * 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; }
/** * * This function handles modem interrupts. It does not do any processing * except to call the application handler to indicate a modem event. * * @param InstancePtr is a pointer to the XUartPs instance * * @return None. * * @note None. * *****************************************************************************/ static void ModemHandler(XUartPs *InstancePtr) { u32 MsrRegister; /* * Read the modem status register so that the interrupt is acknowledged * and it can be passed to the callback handler with the event */ MsrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_MODEMSR_OFFSET); /* * Call the application handler to indicate the modem status changed, * passing the modem status and the event data in the call */ InstancePtr->Handler(InstancePtr->CallBackRef, XUARTPS_EVENT_MODEM, MsrRegister); }
/** * * This function does a minimal test on the UART device using the hardware * interface. * * @param UartBaseAddress is the base address of the device * * @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful * * @note None. * **************************************************************************/ int UartPsEchoExample(u32 UartBaseAddress) { int Index; u32 Running; u8 RecvChar; u32 CntrlRegister; CntrlRegister = XUartPs_ReadReg(UartBaseAddress, XUARTPS_CR_OFFSET); /* * Enable TX and RX for the device */ XUartPs_WriteReg(UartBaseAddress, XUARTPS_CR_OFFSET, ((CntrlRegister & ~XUARTPS_CR_EN_DIS_MASK) | XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN)); /* * Initialize the send buffer bytes with a pattern to send and the * the receive buffer bytes to zero */ for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { SendBuffer[Index] = Index + '0'; } /* * Send the entire transmit buffer. */ for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { /* * Wait until there is space in TX FIFO */ while (XUartPs_IsTransmitFull(UartBaseAddress)); /* * Write the byte into the TX FIFO */ XUartPs_WriteReg(UartBaseAddress, XUARTPS_FIFO_OFFSET, SendBuffer[Index]); } Running = TRUE; while (Running) { /* * Wait until there is data */ while (!XUartPs_IsReceiveData(UartBaseAddress)); RecvChar = XUartPs_ReadReg(UartBaseAddress, XUARTPS_FIFO_OFFSET); /* Change the capitalization */ if (('a' <= RecvChar) && ('z' >= RecvChar)) { // Convert the Capital letter to a small. RecvChar = RecvChar - 'a' + 'A'; } else if (('A' <= RecvChar) && ('Z' >= RecvChar)) { // Convert the small letter to a Capital. RecvChar = RecvChar - 'A' + 'a'; } else if (CHAR_ESC == RecvChar) { Running = FALSE; } /* Echo the character back */ XUartPs_WriteReg(UartBaseAddress, XUARTPS_FIFO_OFFSET, RecvChar); } return XST_SUCCESS; }
/** * * This function runs a self-test on the driver and hardware device. This self * test performs a local loopback and verifies data can be sent and received. * * The time for this test is proportional to the baud rate that has been set * prior to calling this function. * * The mode and control registers are restored before return. * * @param InstancePtr is a pointer to the XUartPs instance * * @return * - XST_SUCCESS if the test was successful * - XST_UART_TEST_FAIL if the test failed looping back the data * * @note * * This function can hang if the hardware is not functioning properly. * ******************************************************************************/ s32 XUartPs_SelfTest(XUartPs *InstancePtr) { s32 Status = XST_SUCCESS; u32 IntrRegister; u32 ModeRegister; u8 Index; u32 ReceiveDataResult; /* * Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Disable all interrupts in the interrupt disable register */ IntrRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_IMR_OFFSET); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK); /* * Setup for local loopback */ ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, ((ModeRegister & (u32)(~XUARTPS_MR_CHMODE_MASK)) | (u32)XUARTPS_MR_CHMODE_L_LOOP)); /* * Send a number of bytes and receive them, one at a time. */ for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) { /* * Send out the byte and if it was not sent then the failure * will be caught in the comparison at the end */ (void)XUartPs_Send(InstancePtr, &TestString[Index], 1U); /* * Wait until the byte is received. This can hang if the HW * is broken. Watch for the FIFO empty flag to be false. */ ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY; while (ReceiveDataResult == XUARTPS_SR_RXEMPTY ) { ReceiveDataResult = Xil_In32((InstancePtr->Config.BaseAddress) + XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY; } /* * Receive the byte */ (void)XUartPs_Recv(InstancePtr, &ReturnString[Index], 1U); } /* * Compare the bytes received to the bytes sent to verify the exact data * was received */ for (Index = 0U; Index < XUARTPS_TOTAL_BYTES; Index++) { if (TestString[Index] != ReturnString[Index]) { Status = XST_UART_TEST_FAIL; } } /* * Restore the registers which were altered to put into polling and * loopback modes so that this test is not destructive */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IER_OFFSET, IntrRegister); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, ModeRegister); return Status; }
void DisplayDemoChangeRes(DisplayCtrl *dispPtr, u32 uartAddr) { char userInput = 0; int fResSet = 0; int status; /* Flush UART FIFO */ while (XUartPs_IsReceiveData(uartAddr)) { XUartPs_ReadReg(uartAddr, XUARTPS_FIFO_OFFSET); } while (!fResSet) { DisplayDemoCRMenu(dispPtr); /* Wait for data on UART */ while (!XUartPs_IsReceiveData(uartAddr)) {} /* Store the first character in the UART recieve FIFO and echo it */ userInput = XUartPs_ReadReg(uartAddr, XUARTPS_FIFO_OFFSET); xil_printf("%c", userInput); status = XST_SUCCESS; switch (userInput) { case '1': status = DisplayStop(dispPtr); DisplaySetMode(dispPtr, &VMODE_640x480); DisplayStart(dispPtr); fResSet = 1; break; case '2': status = DisplayStop(dispPtr); DisplaySetMode(dispPtr, &VMODE_800x600); DisplayStart(dispPtr); fResSet = 1; break; case '3': status = DisplayStop(dispPtr); DisplaySetMode(dispPtr, &VMODE_1280x720); DisplayStart(dispPtr); fResSet = 1; break; case '4': status = DisplayStop(dispPtr); DisplaySetMode(dispPtr, &VMODE_1280x1024); DisplayStart(dispPtr); fResSet = 1; break; case '5': status = DisplayStop(dispPtr); DisplaySetMode(dispPtr, &VMODE_1920x1080); DisplayStart(dispPtr); fResSet = 1; break; case 'q': fResSet = 1; break; default : xil_printf("\n\rInvalid Selection"); TimerDelay(500000); } if (status == XST_DMA_ERROR) { xil_printf("\n\rWARNING: AXI VDMA Error detected and cleared\n\r"); } } }
int DisplayDemoRun(DisplayCtrl *dispPtr, u32 uartAddr) { char userInput = 0; int nextFrame = 0; /* Flush UART FIFO */ while (XUartPs_IsReceiveData(uartAddr)) { XUartPs_ReadReg(uartAddr, XUARTPS_FIFO_OFFSET); } while (userInput != 'q') { DisplayDemoPrintMenu(dispPtr); /* Wait for data on UART */ while (!XUartPs_IsReceiveData(uartAddr)) {} /* Store the first character in the UART recieve FIFO and echo it */ userInput = XUartPs_ReadReg(uartAddr, XUARTPS_FIFO_OFFSET); xil_printf("%c", userInput); switch (userInput) { case '1': DisplayDemoChangeRes(dispPtr, uartAddr); break; case '2': nextFrame = dispPtr->curFrame + 1; if (nextFrame >= DISPLAY_NUM_FRAMES) { nextFrame = 0; } DisplayChangeFrame(dispPtr, nextFrame); break; case '3': DisplayDemoPrintTest(dispPtr->framePtr[dispPtr->curFrame], dispPtr->vMode.width, dispPtr->vMode.height, dispPtr->stride, DISPLAYDEMO_PATTERN_0); break; case '4': DisplayDemoPrintTest(dispPtr->framePtr[dispPtr->curFrame], dispPtr->vMode.width, dispPtr->vMode.height, dispPtr->stride, DISPLAYDEMO_PATTERN_1); break; case '5': DisplayDemoInvertFrame(dispPtr->framePtr[dispPtr->curFrame], dispPtr->framePtr[dispPtr->curFrame], dispPtr->vMode.width, dispPtr->vMode.height, dispPtr->stride); break; case '6': nextFrame = dispPtr->curFrame + 1; if (nextFrame >= DISPLAY_NUM_FRAMES) { nextFrame = 0; } DisplayDemoInvertFrame(dispPtr->framePtr[dispPtr->curFrame], dispPtr->framePtr[nextFrame], dispPtr->vMode.width, dispPtr->vMode.height, dispPtr->stride); DisplayChangeFrame(dispPtr, nextFrame); break; case 'q': break; default : xil_printf("\n\rInvalid Selection"); TimerDelay(500000); } } return XST_SUCCESS; }
void prvUART_Handler( void *pvNotUsed ) { extern unsigned int XUartPs_SendBuffer( XUartPs *InstancePtr ); uint32_t ulActiveInterrupts, ulChannelStatusRegister; BaseType_t xHigherPriorityTaskWoken = pdFALSE; char cChar; configASSERT( pvNotUsed == &xUARTInstance ); /* Remove compile warnings if configASSERT() is not defined. */ ( void ) pvNotUsed; /* Read the interrupt ID register to see which interrupt is active. */ ulActiveInterrupts = XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_IMR_OFFSET); ulActiveInterrupts &= XUartPs_ReadReg(XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET); /* Are any receive events of interest active? */ if( ( ulActiveInterrupts & serRECEIVE_INTERRUPT_MASK ) != 0 ) { /* Read the Channel Status Register to determine if there is any data in the RX FIFO. */ ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); /* Move data from the Rx FIFO to the Rx queue. NOTE THE COMMENTS AT THE TOP OF THIS FILE ABOUT USING QUEUES FOR THIS PURPSOE. */ while( ( ulChannelStatusRegister & XUARTPS_SR_RXEMPTY ) == 0 ) { cChar = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_FIFO_OFFSET ); /* If writing to the queue unblocks a task, and the unblocked task has a priority above the currently running task (the task that this interrupt interrupted), then xHigherPriorityTaskWoken will be set to pdTRUE inside the xQueueSendFromISR() function. xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at the end of this interrupt handler to request a context switch so the interrupt returns directly to the (higher priority) unblocked task. */ xQueueSendFromISR( xRxQueue, &cChar, &xHigherPriorityTaskWoken ); ulChannelStatusRegister = XUartPs_ReadReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_SR_OFFSET ); } } /* Are any transmit events of interest active? */ if( ( ulActiveInterrupts & serTRANSMIT_IINTERRUPT_MASK ) != 0 ) { if( xUARTInstance.SendBuffer.RemainingBytes == 0 ) { /* Give back the semaphore to indicate that the tranmission is complete. If giving the semaphore unblocks a task, and the unblocked task has a priority above the currently running task (the task that this interrupt interrupted), then xHigherPriorityTaskWoken will be set to pdTRUE inside the xSemaphoreGiveFromISR() function. xHigherPriorityTaskWoken is then passed to portYIELD_FROM_ISR() at the end of this interrupt handler to request a context switch so the interrupt returns directly to the (higher priority) unblocked task. */ xSemaphoreGiveFromISR( xTxCompleteSemaphore, &xHigherPriorityTaskWoken ); /* No more data to transmit. */ XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_IDR_OFFSET, XUARTPS_IXR_TXEMPTY ); } else { /* More data to send. */ XUartPs_SendBuffer( &xUARTInstance ); } } /* portYIELD_FROM_ISR() will request a context switch if executing this interrupt handler caused a task to leave the blocked state, and the task that left the blocked state has a higher priority than the currently running task (the task this interrupt interrupted). See the comment above the calls to xSemaphoreGiveFromISR() and xQueueSendFromISR() within this function. */ portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); /* Clear the interrupt status. */ XUartPs_WriteReg( XPAR_PS7_UART_1_BASEADDR, XUARTPS_ISR_OFFSET, ulActiveInterrupts ); }
void DemoRun() { int nextFrame = 0; char userInput = 0; /* Flush UART FIFO */ while (XUartPs_IsReceiveData(UART_BASEADDR)) { XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET); } while (userInput != 'q') { DemoPrintMenu(); /* Wait for data on UART */ while (!XUartPs_IsReceiveData(UART_BASEADDR)) {} /* Store the first character in the UART receive FIFO and echo it */ if (XUartPs_IsReceiveData(UART_BASEADDR)) { userInput = XUartPs_ReadReg(UART_BASEADDR, XUARTPS_FIFO_OFFSET); xil_printf("%c", userInput); } switch (userInput) { case '1': DemoChangeRes(); break; case '2': nextFrame = dispCtrl.curFrame + 1; if (nextFrame >= DISPLAY_NUM_FRAMES) { nextFrame = 0; } DisplayChangeFrame(&dispCtrl, nextFrame); break; case '3': DemoPrintTest(pFrames[dispCtrl.curFrame], dispCtrl.vMode.width, dispCtrl.vMode.height, DEMO_STRIDE, DEMO_PATTERN_0); break; case '4': DemoPrintTest(pFrames[dispCtrl.curFrame], dispCtrl.vMode.width, dispCtrl.vMode.height, DEMO_STRIDE, DEMO_PATTERN_1); break; case '5': DemoInvertFrame(dispCtrl.framePtr[dispCtrl.curFrame], dispCtrl.framePtr[dispCtrl.curFrame], dispCtrl.vMode.width, dispCtrl.vMode.height, dispCtrl.stride); break; case '6': nextFrame = dispCtrl.curFrame + 1; if (nextFrame >= DISPLAY_NUM_FRAMES) { nextFrame = 0; } DemoInvertFrame(dispCtrl.framePtr[dispCtrl.curFrame], dispCtrl.framePtr[nextFrame], dispCtrl.vMode.width, dispCtrl.vMode.height, dispCtrl.stride); DisplayChangeFrame(&dispCtrl, nextFrame); break; case 'q': break; default : xil_printf("\n\rInvalid Selection"); TimerDelay(500000); } } return; }
/** * * Sets the baud rate for the device. Checks the input value for * validity and also verifies that the requested rate can be configured to * within the maximum error range specified by XUARTPS_MAX_BAUD_ERROR_RATE. * If the provided rate is not possible, the current setting is unchanged. * * @param InstancePtr is a pointer to the XUartPs instance * @param BaudRate to be set * * @return * - XST_SUCCESS if everything configured as expected * - XST_UART_BAUD_ERROR if the requested rate is not available * because there was too much error * * @note None. * *****************************************************************************/ s32 XUartPs_SetBaudRate(XUartPs *InstancePtr, u32 BaudRate) { u32 IterBAUDDIV; /* Iterator for available baud divisor values */ u32 BRGR_Value; /* Calculated value for baud rate generator */ u32 CalcBaudRate; /* Calculated baud rate */ u32 BaudError; /* Diff between calculated and requested baud rate */ u32 Best_BRGR = 0U; /* Best value for baud rate generator */ u8 Best_BAUDDIV = 0U; /* Best value for baud divisor */ u32 Best_Error = 0xFFFFFFFFU; u32 PercentError; u32 ModeReg; u32 InputClk; /* * Asserts validate the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(BaudRate <= (u32)XUARTPS_MAX_RATE); Xil_AssertNonvoid(BaudRate >= (u32)XUARTPS_MIN_RATE); /* * Make sure the baud rate is not impossilby large. * Fastest possible baud rate is Input Clock / 2. */ if ((BaudRate * 2) > InstancePtr->Config.InputClockHz) { return XST_UART_BAUD_ERROR; } /* * Check whether the input clock is divided by 8 */ ModeReg = XUartPs_ReadReg( InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET); InputClk = InstancePtr->Config.InputClockHz; if(ModeReg & XUARTPS_MR_CLKSEL) { InputClk = InstancePtr->Config.InputClockHz / 8; } /* * Determine the Baud divider. It can be 4to 254. * Loop through all possible combinations */ for (IterBAUDDIV = 4; IterBAUDDIV < 255; IterBAUDDIV++) { /* * Calculate the value for BRGR register */ BRGR_Value = InputClk / (BaudRate * (IterBAUDDIV + 1)); /* * Calculate the baud rate from the BRGR value */ CalcBaudRate = InputClk/ (BRGR_Value * (IterBAUDDIV + 1)); /* * Avoid unsigned integer underflow */ if (BaudRate > CalcBaudRate) { BaudError = BaudRate - CalcBaudRate; } else { BaudError = CalcBaudRate - BaudRate; } /* * Find the calculated baud rate closest to requested baud rate. */ if (Best_Error > BaudError) { Best_BRGR = BRGR_Value; Best_BAUDDIV = IterBAUDDIV; Best_Error = BaudError; } } /* * Make sure the best error is not too large. */ PercentError = (Best_Error * 100) / BaudRate; if (XUARTPS_MAX_BAUD_ERROR_RATE < PercentError) { return XST_UART_BAUD_ERROR; } /* * Disable TX and RX to avoid glitches when setting the baud rate. */ XUartPs_DisableUart(InstancePtr); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_BAUDGEN_OFFSET, Best_BRGR); XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_BAUDDIV_OFFSET, Best_BAUDDIV); /* * RX and TX SW reset */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_CR_OFFSET, XUARTPS_CR_TXRST | XUARTPS_CR_RXRST); /* * Enable device */ XUartPs_EnableUart(InstancePtr); InstancePtr->BaudRate = BaudRate; return XST_SUCCESS; }
/** * * Initializes a specific XUartPs instance such that it is ready to be used. * The data format of the device is setup for 8 data bits, 1 stop bit, and no * parity by default. The baud rate is set to a default value specified by * Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The * receive FIFO threshold is set for 8 bytes. The default operating mode of the * driver is polled mode. * * @param InstancePtr is a pointer to the XUartPs instance. * @param Config is a reference to a structure containing information * about a specific XUartPs driver. * @param EffectiveAddr is the device base address in the virtual memory * address space. The caller is responsible for keeping the address * mapping from EffectiveAddr to the device physical base address * unchanged once this function is invoked. Unexpected errors may * occur if the address mapping changes after this function is * called. If address translation is not used, pass in the physical * address instead. * * @return * * - XST_SUCCESS if initialization was successful * - XST_UART_BAUD_ERROR if the baud rate is not possible because * the inputclock frequency is not divisible with an acceptable * amount of error * * @note * * The default configuration for the UART after initialization is: * * - 19,200 bps or XPAR_DFT_BAUDRATE if defined * - 8 data bits * - 1 stop bit * - no parity * - FIFO's are enabled with a receive threshold of 8 bytes * - The RX timeout is enabled with a timeout of 1 (4 char times) * * All interrupts are disabled. * *****************************************************************************/ s32 XUartPs_CfgInitialize(XUartPs *InstancePtr, XUartPs_Config * Config, u32 EffectiveAddr) { s32 Status; u32 ModeRegister; u32 BaudRate; /* * Assert validates the input arguments */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(Config != NULL); /* * Setup the driver instance using passed in parameters */ InstancePtr->Config.BaseAddress = EffectiveAddr; InstancePtr->Config.InputClockHz = Config->InputClockHz; InstancePtr->Config.ModemPinsConnected = Config->ModemPinsConnected; /* * Initialize other instance data to default values */ InstancePtr->Handler = XUartPs_StubHandler; InstancePtr->SendBuffer.NextBytePtr = NULL; InstancePtr->SendBuffer.RemainingBytes = 0U; InstancePtr->SendBuffer.RequestedBytes = 0U; InstancePtr->ReceiveBuffer.NextBytePtr = NULL; InstancePtr->ReceiveBuffer.RemainingBytes = 0U; InstancePtr->ReceiveBuffer.RequestedBytes = 0U; /* * Flag that the driver instance is ready to use */ InstancePtr->IsReady = XIL_COMPONENT_IS_READY; /* * Set the default baud rate here, can be changed prior to * starting the device */ BaudRate = (u32)XUARTPS_DFT_BAUDRATE; Status = XUartPs_SetBaudRate(InstancePtr, BaudRate); if (Status != (s32)XST_SUCCESS) { InstancePtr->IsReady = 0U; } else { /* * Set up the default data format: 8 bit data, 1 stop bit, no * parity */ ModeRegister = XUartPs_ReadReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET); /* * Mask off what's already there */ ModeRegister &= (~((u32)XUARTPS_MR_CHARLEN_MASK | (u32)XUARTPS_MR_STOPMODE_MASK | (u32)XUARTPS_MR_PARITY_MASK)); /* * Set the register value to the desired data format */ ModeRegister |= ((u32)XUARTPS_MR_CHARLEN_8_BIT | (u32)XUARTPS_MR_STOPMODE_1_BIT | (u32)XUARTPS_MR_PARITY_NONE); /* * Write the mode register out */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_MR_OFFSET, ModeRegister); /* * Set the RX FIFO trigger at 8 data bytes. */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_RXWM_OFFSET, 0x08U); /* * Set the RX timeout to 1, which will be 4 character time */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_RXTOUT_OFFSET, 0x01U); /* * Disable all interrupts, polled mode is the default */ XUartPs_WriteReg(InstancePtr->Config.BaseAddress, XUARTPS_IDR_OFFSET, XUARTPS_IXR_MASK); Status = XST_SUCCESS; } return Status; }
void pong(DisplayCtrl *video ,u32 uartAddress, XGpio *btn, XGpio *sw){ u32 height = video->vMode.height, width = video->vMode.width, stride = video->stride, *frame, speed = 2, pause=false; char entrada; frame=video->framePtr[video->curFrame]; xil_printf("\x1B[H"); //Set cursor to top left of terminal xil_printf("\x1B[2J"); //Clear terminal Rectangulo bola=crearRectangulo(10,10,RED,ANCHO_BOLA,ALTO_BOLA); Rectangulo palaIzquierda = crearRectangulo(0,height/2-ALTO_PALA/2,GREEN,ANCHO_PALA,ALTO_PALA); Rectangulo palaDerecha = crearRectangulo(width-ANCHO_PALA,height/2-ALTO_PALA/2,GREEN,ANCHO_PALA,ALTO_PALA); int dir_x=true, dir_y=true, indice_frame=0,salir=0,pulsar=0,puntuacionA=0,puntuacionB=0; salir = XGpio_DiscreteRead(sw, 1); while(salir & 0x8){ if (salir & 0x1) // 0x1=0b0001=posicion de SW0 bola.color = WHITE; else bola.color = RED; //apunta a al siguente frame indice_frame=nextFrame(video,&frame); pintarFondo(frame, BLACK, width,height,stride); //movimiento y colision if(dir_x == DERECHA) if ((bola.x+ANCHO_BOLA > palaDerecha.x) && (bola.y >= palaDerecha.y && bola.y < palaDerecha.y+ALTO_PALA )){ bola.x-=speed; dir_x = IZQUIERDA; }else{ bola.x+=speed; } else if ((bola.x < palaIzquierda.x+ANCHO_PALA) && (bola.y >= palaIzquierda.y && bola.y < palaIzquierda.y+ALTO_PALA)){ bola.x+=speed; dir_x = DERECHA; }else{ bola.x-=speed; } if(dir_y == ABAJO) bola.y+=speed; else bola.y-=speed; //control de direccion if (bola.x<0){ bola.x=width/2; bola.y=height/2; dir_x=DERECHA; puntuacionB++; xil_printf("%d - %d\n\r",puntuacionA,puntuacionB); TimerDelay(1500000); }else if(bola.x>width - ANCHO_BOLA){ bola.x=width/2; bola.y=height/2; dir_x=IZQUIERDA; puntuacionA++; xil_printf("%d - %d\n\r",puntuacionA,puntuacionB); TimerDelay(1500000); } if (bola.y<0){ bola.y=0; dir_y=ABAJO; }else if(bola.y>height - ALTO_BOLA){ bola.y=height - ALTO_BOLA; dir_y=ARRIBA; } //pintar la pelota y las palas pintarRectangulo(frame,&bola,width,height,stride); pintarRectangulo(frame,&palaDerecha,width,height,stride); pintarRectangulo(frame,&palaIzquierda,width,height,stride); //flush Xil_DCacheFlushRange((unsigned int) frame, DISPLAY_MAX_FRAME * 4); DisplayChangeFrame(video,indice_frame); //TimerDelay(17000); salir = XGpio_DiscreteRead(sw, 1); pulsar = XGpio_DiscreteRead(btn, 1); //control de las palas if (pulsar & 0x1){ //Pala derecha if (palaDerecha.y+ALTO_PALA < height){ palaDerecha.y+=speed; } }else if(pulsar & 0x2){ if (palaDerecha.y >= 0){ palaDerecha.y-=speed; } } if (pulsar & 0x4 ){ //Pala izquierda if (palaIzquierda.y+ALTO_PALA < height){ palaIzquierda.y+=speed; } }else if(pulsar & 0x8){ if (palaIzquierda.y >= 0){ palaIzquierda.y-=speed; } } //recolocar las palas si se han salido fuera if (palaDerecha.y<0) palaDerecha.y=0; else if (palaDerecha.y+ALTO_PALA>height) palaDerecha.y=height-ALTO_PALA; if (palaIzquierda.y<0) palaIzquierda.y=0; else if (palaIzquierda.y+ALTO_PALA>height) palaIzquierda.y=height-ALTO_PALA; //leer pulsaciones de cambio de velocidad if (XUartPs_IsReceiveData(uartAddress)){ entrada=XUartPs_ReadReg(uartAddress, XUARTPS_FIFO_OFFSET); if (entrada==' '){ pause=true; while(pause){ if (XUartPs_IsReceiveData(uartAddress)){ entrada=XUartPs_ReadReg(uartAddress, XUARTPS_FIFO_OFFSET); if (entrada==' ') pause=false; else cambiarVelocidad(&speed,entrada); } } }else cambiarVelocidad(&speed,entrada); } } }