static char* test_spi_stream_read_rx_packet(void) { CircularBuffer* mybuf = cbuffer_new(); uint32_t my_pkt_expected[10] = {0xBEEF, 5, 1, 2, 3, 4, 5, 0xDEADBEEF, 0xDEADBEEF, -1}; uint32_t my_pkt_expected_2[10] = {0xBEEF, 7, 1, 2, 3, 4, 5, 1, 2, -1}; add_checksum(my_pkt_expected, 10); add_checksum(my_pkt_expected_2, 10); uint32_t my_data[7] = {1, 2, 3, 4, 5, 1, 2}; // read with non-full buffer int ret = spi_stream_read_rx_packet(my_pkt_expected, mybuf); mu_assert_eq("okay1", ret, 1); mu_assert_eq("data1", memcmp(my_data, mybuf->data, 5 * sizeof(uint32_t)), 0); mybuf->tail = 0; // read with full buffer ret = spi_stream_read_rx_packet(my_pkt_expected_2, mybuf); mu_assert_eq("okay2", ret, 1); mu_assert_eq("data2", memcmp(my_data, mybuf->data, 7 * sizeof(uint32_t)), 0); // overflowing local buffer mybuf->tail = IO_BUFFER_SIZE - 5; mu_assert_eq("its too small", cbuffer_freespace(mybuf), 4); ret = spi_stream_read_rx_packet(my_pkt_expected_2, mybuf); mu_assert_eq("overflow err", ret, 0); mu_assert_eq("unmodified", cbuffer_freespace(mybuf), 4); return 0; }
static char* test_cbuffer_freespace(void) { CircularBuffer* mybuf = cbuffer_new(); mybuf->tail = IO_BUFFER_SIZE - 5; mu_assert_eq("freespace", cbuffer_freespace(mybuf), 4); mu_assert_eq("size", cbuffer_size(mybuf), IO_BUFFER_SIZE - 5); for (int i = 1; i < 5; ++i) { cbuffer_push_back(mybuf, i); mu_assert_eq("freespace", cbuffer_freespace(mybuf), 4 - i); } cbuffer_free(mybuf); return 0; }
int main() { xil_printf("Master SPI oRSC echo test\n"); // initialize stdout. init_platform(); tx_buffer = cbuffer_new(); rx_buffer = cbuffer_new(); vme_stream = vmestream_initialize_mem( rx_buffer, tx_buffer, (uint32_t*)ORSC_2_PC_SIZE, (uint32_t*)PC_2_ORSC_SIZE, (uint32_t*)ORSC_2_PC_DATA, (uint32_t*)PC_2_ORSC_DATA, VMERAMSIZE); //printf("Master SPI oRSC echo test\n"); while (1) { // transfer data vmestream_transfer_data(vme_stream); // now echo the data while (cbuffer_size(rx_buffer) && cbuffer_freespace(tx_buffer)) { cbuffer_push_back(tx_buffer, cbuffer_pop_front(rx_buffer)); } } return 0; }
static char* test_cbuffer_new(void) { CircularBuffer* mybuf = cbuffer_new(); mu_assert_eq("size", cbuffer_size(mybuf), 0); mu_assert_eq("pos", mybuf->pos, 0); mu_assert_eq("freespace", cbuffer_freespace(mybuf), IO_BUFFER_SIZE - 1); mu_assert_eq("init is zero", (mybuf->data[0]), 0); cbuffer_free(mybuf); return 0; }
/* * Make sure cbuffer_fd_read handles the edge case where cbuffer->tail returns * to the front of buffer->data */ static char* test_cbuffer_fd_read_edge(void) { int pipefd[2]; pipe(pipefd); fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); int in = pipefd[1]; int out = pipefd[0]; CircularBuffer* mybuf = cbuffer_new(); // completely fill buffer while (cbuffer_freespace(mybuf) > 0) { mu_assert_eq("mybuf overflow", cbuffer_push_back(mybuf, 0xDEADBEEF), 0); } mu_assert_eq("mybuf still has free space", cbuffer_freespace(mybuf), 0); // clear a single space in the cbuffer // free space should be at the front of cbuffer->data cbuffer_deletefront(mybuf, 1); uint32_t inbuf[] = {0xCAFEBABE}; write(in, inbuf, sizeof(uint32_t)); // read a single word into the free slot in the buffer mu_assert_eq("Could not read data", cbuffer_read_fd(mybuf, out, 1), 1); // check the content of the cbuffer while (cbuffer_size(mybuf) > 1) { mu_assert_eq("Content should be 0xDEADBEEF", cbuffer_pop_front(mybuf), 0xDEADBEEF); } mu_assert_eq("Content should be 0xCAFEBABE", cbuffer_pop_front(mybuf), 0xCAFEBABE); cbuffer_free(mybuf); return 0; }
static char* test_cbuffer_fd_full(void) { // make sure we can stop reading if our read buffer is full // make pipes int pipefd[2]; pipe(pipefd); // make txpipe nonblocking, so we can check if it's empty. fcntl(pipefd[0], F_SETFL, fcntl(pipefd[0], F_GETFL) | O_NONBLOCK); int in = pipefd[1]; int out = pipefd[0]; CircularBuffer* frombuf = cbuffer_new(); for (int i = 0; i < 200; ++i) { cbuffer_push_back(frombuf, i); } mu_assert_eq("from size", cbuffer_size(frombuf), 200); CircularBuffer* tobuf = cbuffer_new(); tobuf->pos = IO_BUFFER_SIZE - 100; tobuf->tail = IO_BUFFER_SIZE - 100; ssize_t written = cbuffer_write_fd(frombuf, in, 200); mu_assert_eq("wrote to pipe", written, 200); mu_assert_eq("from size after", cbuffer_size(frombuf), 0); tobuf->tail += IO_BUFFER_SIZE - 100; mu_assert_eq("to freespace", cbuffer_freespace(tobuf), 99); ssize_t read = cbuffer_read_fd(tobuf, out, 200); ssize_t exp = 99; mu_assert_eq("read from pipe", (int)read, (int)exp); cbuffer_free(frombuf); cbuffer_free(tobuf); return 0; }
int main() { xil_printf("Master SPI oRSC echo test\n"); // initialize stdout. init_platform(); tx_buffer = cbuffer_new(); rx_buffer = cbuffer_new(); spi_stream = spi_stream_init( tx_buffer, rx_buffer, DoSpiTransfer, // callback which triggers a SPI transfer 0); int Status; XSpi_Config *ConfigPtr; /* Pointer to Configuration data */ /* * Initialize the SPI driver so that it is ready to use. */ ConfigPtr = XSpi_LookupConfig(SPI_DEVICE_ID); if (ConfigPtr == NULL) { xil_printf ("Error: could not lookup SPI configuration\n"); return XST_DEVICE_NOT_FOUND; } Status = XSpi_CfgInitialize(&SpiInstance, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { xil_printf("Error: could not initialize the SPI device\n"); return XST_FAILURE; } Status = XSpi_SelfTest(&SpiInstance); if (Status != XST_SUCCESS) { xil_printf("Error: The SPI self test failed.\n"); return XST_FAILURE; } /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific. */ Status = SpiSetupIntrSystem(&IntcInstance, &SpiInstance, SPI_IRPT_INTR); if (Status != XST_SUCCESS) { xil_printf("Error: Could not setup interrupt system.\n"); return XST_FAILURE; } /* * Set the Spi device as a master. */ Status = XSpi_SetOptions(&SpiInstance, XSP_MASTER_OPTION); if (Status != XST_SUCCESS) { xil_printf("Error: Could not set as master\n"); return XST_FAILURE; } // Go! XSpi_Start(&SpiInstance); // Note: to disable interrupt, do: XIntc_Disconnect(&IntcInstance, // SPI_IRPT_INTR); u32 expected_rx = 0; u32 current_tx = 0; while (1) { // fill up the transmit buffer while (cbuffer_freespace(tx_buffer)) { cbuffer_push_back(tx_buffer, current_tx++); } // check to make sure the received buffer is what we expect while (cbuffer_size(rx_buffer)) { u32 front = cbuffer_value_at(rx_buffer, 0); if (front != expected_rx) { //xil_printf("Error: expected %lx, got %lx!\n", expected_rx, front); xil_printf("Error: data value\n"); } expected_rx++; cbuffer_deletefront(rx_buffer, 1); } } return 0; }
/** * Overload buffer test */ static char *test_buf() { // local application buffers CircularBuffer *tx1 = cbuffer_new(); CircularBuffer *rx1 = cbuffer_new(); CircularBuffer *tx2 = cbuffer_new(); CircularBuffer *rx2 = cbuffer_new(); VMEStream *test1 = vmestream_initialize(tx1, rx1, 32); VMEStream *test2 = malloc(sizeof(VMEStream)); test2->input = tx2; test2->output = rx2; test2->rx_size = test1->tx_size; test2->tx_size = test1->rx_size; test2->rx_data = test1->tx_data; test2->tx_data = test1->rx_data; test2->MAXRAM = test1->MAXRAM; cbuffer_push_back(rx2, 0xDEADBEEF); for (int i = 0; i < 510; i++) { cbuffer_push_back(rx2, 0xBEEFCAFE); } cbuffer_push_back(tx1, 0xBEEFCAFE + 1); cbuffer_push_back(tx1, 0xBEEFCAFE + 2); cbuffer_push_back(tx1, 0xBEEFCAFE + 3); cbuffer_push_back(tx1, 0xBEEFCAFE + 4); mu_assert("Error: rx2 should have no space left", cbuffer_freespace(rx2) == 0); // sanity check mu_assert_eq("Error: output size != 4", cbuffer_size(tx1), 4); // do several transfers vmestream_transfer_data(test1); vmestream_transfer_data(test2); vmestream_transfer_data(test1); vmestream_transfer_data(test2); // no data should have been transferred mu_assert_eq("Error: tx_size != 4", *(test1->tx_size), 4); mu_assert("Error: rx2.pop != 0xDEADBEEF", 0xDEADBEEF == cbuffer_pop_front(rx2)); cbuffer_pop_front(rx2); cbuffer_pop_front(rx2); // popping off rx2 should have freed 3 words, but not enough to transfer all // four vmestream_transfer_data(test1); vmestream_transfer_data(test2); mu_assert_eq("Error: tx_size != 4", *(test1->tx_size), 4); mu_assert("Errrr: rx2.pop not 0xBEEFCAFE", 0xBEEFCAFE == cbuffer_pop_front(rx2)); cbuffer_pop_front(rx2); // now there is enough room for all the limbo data to be transferred to rx2 vmestream_transfer_data(test1); vmestream_transfer_data(test2); mu_assert("Error: tx_size != 0", *(test1->tx_size) == 0); mu_assert("Error: tx1 not empty", 0 == cbuffer_size(tx1)); for (int i = 0; i < 4; ++i) { mu_assert_eq("Unexpected data transferred", cbuffer_value_at(rx2, cbuffer_size(rx2) - 4 + i), 0xBEEFCAFE + i + 1); } // free memory vmestream_destroy(test1); free(test2); cbuffer_free(tx1); cbuffer_free(rx1); cbuffer_free(tx2); cbuffer_free(rx2); return 0; }
int main(void) { LOG_INFO("UART CTP FE echo test\n"); init_platform(); tx_buffer = cbuffer_new(); rx_buffer = cbuffer_new(); int Status; u16 DeviceId = UARTLITE_DEVICE_ID; /* * Initialize the UartLite driver so that it's ready to use. */ Status = XUartLite_Initialize(&UartLite, DeviceId); if (Status != XST_SUCCESS) { LOG_ERROR ("Error: could not initialize UART\n"); return XST_FAILURE; } XUartLite_ResetFifos(&UartLite); /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XUartLite_SelfTest(&UartLite); if (Status != XST_SUCCESS) { LOG_ERROR ("Error: self test failed\n"); return XST_FAILURE; } /* * Connect the UartLite to the interrupt subsystem such that interrupts can * occur. This function is application specific. */ Status = SetupInterruptSystem(&UartLite); if (Status != XST_SUCCESS) { LOG_ERROR ("Error: could not setup interrupts\n"); return XST_FAILURE; } /* * Setup the handlers for the UartLite that will be called from the * interrupt context when data has been sent and received, specify a * pointer to the UartLite driver instance as the callback reference so * that the handlers are able to access the instance data. */ XUartLite_SetSendHandler(&UartLite, SendHandler, &UartLite); XUartLite_SetRecvHandler(&UartLite, RecvHandler, &UartLite); /* * Enable the interrupt of the UartLite so that interrupts will occur. */ XUartLite_EnableInterrupt(&UartLite); // bootstrap the READ LOG_DEBUG("Bootstrapping READ\n"); XUartLite_Recv(&UartLite, (u8*)&rx_tmp_buffer, sizeof(uint32_t)); LOG_INFO("Starting loop\n"); /* LOG_DEBUG("Sending 'wtf!'\n"); currently_sending = 1; char help[4] = "wtf!"; unsigned int ret = XUartLite_Send(&UartLite, (u8*)help, 4); LOG_DEBUG("WTF send complete return: %x\n", ret); */ /* echo received data forever */ unsigned int heartbeat = 0; while (1) { if (heartbeat++ % (1 << 8)) { //LOG_DEBUG("bump %x\n", heartbeat); } while (cbuffer_size(rx_buffer) && cbuffer_freespace(tx_buffer)) { uint32_t data = cbuffer_pop_front(rx_buffer); //LOG_DEBUG("Echoing data word %x\n", data); cbuffer_push_back(tx_buffer, data); } if (!currently_sending && cbuffer_size(tx_buffer)) { LOG_DEBUG("\nREINT SEND\n"); currently_sending = 1; /* if (XUartLite_IsSending(&UartLite)) { LOG_DEBUG("UART STAT: sending\n"); } else { LOG_DEBUG("UART STAT: idle\n"); } */ unsigned int to_send = cbuffer_contiguous_data_size(tx_buffer) * sizeof(uint32_t); u8* output_ptr = (u8*)&(tx_buffer->data[tx_buffer->pos]); //LOG_DEBUG("REINIT %x\n", to_send); //LOG_DEBUG("SENDADDR %x\n", output_ptr); XUartLite_Send(&UartLite, output_ptr, to_send); } } }