void cyg_hal_plf_serial_putc(channel_data_t *chan, cyg_uint8 c) { if (!chan->dev_ok) return; XUartNs550_Send(&chan->dev, &c, 1); // Wait for character to get out while (XUartNs550_IsSending(&chan->dev)) ; }
/** * * This functions 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 statistics are cleared at the end of the test. The time for this test * to execute is proportional to the baud rate that has been set prior to * calling this function. * * @param InstancePtr is a pointer to the XUartNs550 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. * ******************************************************************************/ int XUartNs550_SelfTest(XUartNs550 *InstancePtr) { int Status = XST_SUCCESS; u32 McrRegister; u32 LsrRegister; u32 IerRegister; u32 Index; /* * Assert validates the input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); /* * Setup for polling by disabling all interrupts in the interrupt enable * register */ IerRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, XUN_IER_OFFSET); XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, 0); /* * Setup for loopback by enabling the loopback in the modem control * register */ McrRegister = XUartNs550_ReadReg(InstancePtr->BaseAddress, XUN_MCR_OFFSET); XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_MCR_OFFSET, McrRegister | XUN_MCR_LOOP); /* * Send a number of bytes and receive them, one at a time so this * test will work for 450 and 550 */ for (Index = 0; Index < XUN_TOTAL_BYTES; Index++) { /* * Send out the byte and if it was not sent then the failure * will be caught in the compare at the end */ XUartNs550_Send(InstancePtr, &TestString[Index], 1); /* * Wait til the byte is received such that it should be waiting * in the receiver. This can hang if the HW is broken */ do { LsrRegister = XUartNs550_GetLineStatusReg(InstancePtr->BaseAddress); } while ((LsrRegister & XUN_LSR_DATA_READY) == 0); /* * Receive the byte that should have been received because of * the loopback, if it wasn't received then it will be caught * in the compare at the end */ XUartNs550_Recv(InstancePtr, &ReturnString[Index], 1); } /* * Clear the stats since they are corrupted by the test */ XUartNs550_ClearStats(InstancePtr); /* * Compare the bytes received to the bytes sent to verify the exact data * was received */ for (Index = 0; Index < XUN_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 */ XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_IER_OFFSET, IerRegister); XUartNs550_WriteReg(InstancePtr->BaseAddress, XUN_MCR_OFFSET, McrRegister); return Status; }
/** * * This function does a minimal test on the UartNs550 device and driver as a * design example. The purpose of this function is to illustrate how to use the * XUartNs550 component. * * This function transmits data and expects to receive the same data through the * UART using the local loopback of the hardware. * * This function uses interrupt driver mode of the UART. * * @param IntcInstancePtr is a pointer to the instance of the * Interrupt Controller. * @param UartInstancePtr is a pointer to the instance of the UART . * @param UartDeviceId is the device Id and is typically * XPAR_<UARTNS550_instance>_DEVICE_ID value from xparameters.h. * @param UartIntrId is the interrupt Id and is typically * XPAR_<INTC_instance>_<UARTNS550_instance>_IP2INTC_IRPT_INTR * value from xparameters.h. * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * * @note * * This function contains an infinite loop such that if interrupts are not * working it may never return. * *******************************************************************************/ int UartNs550IntrExample(XIntc *IntcInstancePtr, XUartNs550 *UartInstancePtr, u16 UartDeviceId, u16 UartIntrId) { int Status; u32 Index; u16 Options; u32 BadByteCount = 0; /* * Initialize the UART driver so that it's ready to use. */ Status = XUartNs550_Initialize(UartInstancePtr, UartDeviceId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XUartNs550_SelfTest(UartInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the UART to the interrupt subsystem such that interrupts can * occur. This function is application specific. */ Status = UartNs550SetupIntrSystem(IntcInstancePtr, UartInstancePtr, UartIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handlers for the UART that will be called from the * interrupt context when data has been sent and received, specify a * pointer to the UART driver instance as the callback reference so * the handlers are able to access the instance data. */ XUartNs550_SetHandler(UartInstancePtr, UartNs550IntrHandler, UartInstancePtr); /* * Enable the interrupt of the UART so interrupts will occur, setup * a local loopback so data that is sent will be received, and keep the * FIFOs enabled. */ Options = XUN_OPTION_DATA_INTR | XUN_OPTION_LOOPBACK | XUN_OPTION_FIFOS_ENABLE; XUartNs550_SetOptions(UartInstancePtr, Options); /* * Initialize the send buffer bytes with a pattern to send and the * the receive buffer bytes to zero to allow the receive data to be * verified. */ for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { SendBuffer[Index] = Index + 'A'; RecvBuffer[Index] = 0; } /* * Start receiving data before sending it since there is a loopback, * ignoring the number of bytes received as the return value since we * know it will be zero and we are using interrupt mode. */ XUartNs550_Recv(UartInstancePtr, RecvBuffer, TEST_BUFFER_SIZE); /* * Send the buffer using the UART and ignore the number of bytes sent * as the return value since we are using it in interrupt mode. */ XUartNs550_Send(UartInstancePtr, SendBuffer, TEST_BUFFER_SIZE); /* * Wait for the entire buffer to be received, letting the interrupt * processing work in the background, this function may get locked * up in this loop if the interrupts are not working correctly. */ while ((TotalReceivedCount != TEST_BUFFER_SIZE) || (TotalSentCount != TEST_BUFFER_SIZE)) { } /* * Verify the entire receive buffer was successfully received. */ for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { if (RecvBuffer[Index] != SendBuffer[Index]) { BadByteCount++; } } /* * Disable the UartNs550 interrupt. */ UartNs550DisableIntrSystem(IntcInstancePtr, UartIntrId); /* * If any bytes were not correct, return an error. */ if (BadByteCount != 0) { return XST_FAILURE; } return XST_SUCCESS; }
/** * * This function does a minimal test on the UART 16450/550 device and driver as a * design example. The purpose of this function is to illustrate how to use * the XUartNs550 component. * * This function sends data and expects to receive the data thru the UART * using the local loopback mode of the UART hardware. * * This function polls the UART and does not require the use of interrupts. * * @param DeviceId is the XPAR_<uartns550_instance>_DEVICE_ID value from * xparameters.h. * * @return XST_SUCCESS if successful, XST_FAILURE if unsuccessful. * * @note This function polls the UART such that it may be not return * if the hardware is not working correctly. * ****************************************************************************/ int UartNs550PolledExample(u16 DeviceId) { int Status; unsigned int SentCount; unsigned int ReceivedCount = 0; u16 Index; u16 Options; /* * Initialize the UART Lite driver so that it's ready to use, * specify the device ID that is generated in xparameters.h */ Status = XUartNs550_Initialize(&UartNs550, DeviceId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly */ Status = XUartNs550_SelfTest(&UartNs550); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable the local loopback so data that is sent will be received, * and keep the FIFOs enabled */ Options = XUN_OPTION_LOOPBACK | XUN_OPTION_FIFOS_ENABLE; XUartNs550_SetOptions(&UartNs550, Options); /* * 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] = '0' + Index; RecvBuffer[Index] = 0; } /* * Send the buffer thru the UART waiting till the data can be * sent (block), if the specified number of bytes was not sent * successfully, then an error occurred */ SentCount = XUartNs550_Send(&UartNs550, SendBuffer, TEST_BUFFER_SIZE); if (SentCount != TEST_BUFFER_SIZE) { return XST_FAILURE; } /* * Receive the number of bytes which is transfered. * Data may be received in fifo with some delay hence we continuously * check the receive fifo for valid data and update the receive buffer * accordingly. */ while (1) { ReceivedCount += XUartNs550_Recv(&UartNs550, RecvBuffer + ReceivedCount, TEST_BUFFER_SIZE - ReceivedCount); if (ReceivedCount == TEST_BUFFER_SIZE) { break; } } /* * Check the receive buffer data against the send buffer and verify the * data was correctly received */ for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) { if (SendBuffer[Index] != RecvBuffer[Index]) { return XST_FAILURE; } } /* * Clean up the options */ Options = XUartNs550_GetOptions(&UartNs550); Options = Options & ~(XUN_OPTION_LOOPBACK | XUN_OPTION_FIFOS_ENABLE); XUartNs550_SetOptions(&UartNs550, Options); return XST_SUCCESS; }