static char* test_ipbus_stream_state() { int swapbytes = 2; CircularBuffer* test_buffer = cbuffer_new(); cbuffer_push_back_net(test_buffer, ipbus_packet_header(0xBEEF, 2)); cbuffer_push_back_net(test_buffer, 0xBADD); // garbage, shouldn't matter mu_assert_eq("hdr in stream", ipbus_stream_state(test_buffer, &swapbytes), IPBUS_ISTREAM_PACKET); mu_assert_eq("hdr endianness detect", swapbytes, 0); cbuffer_deletefront(test_buffer, 2); // A read request cbuffer_push_back_net(test_buffer, ipbus_transaction_header(2, 0xEEF, 2, IPBUS_READ, IPBUS_INFO_REQUEST)); cbuffer_push_back_net(test_buffer, 0xDEADBEEF); // We expect one extra word (the base addr) mu_assert_eq("read length", ipbus_transaction_payload_size(2, IPBUS_READ, IPBUS_INFO_REQUEST), 1); mu_assert_eq("trns in stream", ipbus_stream_state(test_buffer, &swapbytes), IPBUS_ISTREAM_FULL_TRANS); cbuffer_deletefront(test_buffer, 2); // A write request of 8 words, that isn't fully buffered cbuffer_push_back_net(test_buffer, ipbus_transaction_header(2, 0xEEF, 8, IPBUS_WRITE, IPBUS_INFO_REQUEST)); // a base addr + 8 data words mu_assert_eq("write length", ipbus_transaction_payload_size(8, IPBUS_WRITE, IPBUS_INFO_REQUEST), 9); mu_assert_eq("trns partial", ipbus_stream_state(test_buffer, &swapbytes), IPBUS_ISTREAM_PARTIAL_TRANS); cbuffer_deletefront(test_buffer, 1); mu_assert_eq("empty", ipbus_stream_state(test_buffer, &swapbytes), IPBUS_ISTREAM_EMPTY); return 0; }
static char* test_cbuffer_delete_front_wraps(void) { CircularBuffer* mybuf = cbuffer_new(); uint32_t test_data[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // put us at the end of the buffer mybuf->pos = IO_BUFFER_SIZE - 5; mybuf->tail = IO_BUFFER_SIZE - 5; cbuffer_append(mybuf, test_data, 11); mu_assert_eq("content", memcmp(&(mybuf->data[mybuf->pos]), test_data, 5 * sizeof(uint32_t)), 0); int deleted = cbuffer_deletefront(mybuf, 5); mu_assert_eq("deleted", deleted, 5); mu_assert_eq("pos", mybuf->pos, 0); mu_assert_eq("size", cbuffer_size(mybuf), 6); mu_assert_eq("item0", mybuf->data[mybuf->pos], 5); mu_assert_eq("item1", mybuf->data[mybuf->pos+1], 6); mu_assert_eq("item2", mybuf->data[mybuf->pos+2], 7); mu_assert_eq("remaining content in cbuffer", memcmp( &(mybuf->data[0]), test_data + 5, 6 * sizeof(uint32_t)), 0); Buffer* readout = buffer_new(NULL, 6); cbuffer_read(mybuf, readout->data, 6); mu_assert_eq("remaining content", memcmp( readout->data, (test_data + 5), 6 * sizeof(uint32_t)), 0); // if we ask to delete everything, just return what was actually deleted. int deleted_just_to_end = cbuffer_deletefront(mybuf, 100); mu_assert_eq("deleted just to end", deleted_just_to_end, 6); mu_assert_eq("pos2", mybuf->pos, 6); mu_assert_eq("size2", cbuffer_size(mybuf), 0); cbuffer_free(mybuf); buffer_free(readout); return 0; }
void SendHandler(void *CallBackRef, unsigned int EventData) { // delete the bytes which were sent previously if (EventData % sizeof(uint32_t)) { LOG_DEBUG("ERROR: sent data not word aligned!!!\n"); } cbuffer_deletefront(tx_buffer, EventData / sizeof(uint32_t)); if (cbuffer_size(tx_buffer)) { unsigned int to_send = cbuffer_contiguous_data_size(tx_buffer) * sizeof(uint32_t); XUartLite_Send(&UartLite, (u8*)&(tx_buffer->data[tx_buffer->pos]), to_send); LOG_DEBUG("SendHandler _Send %x\n", to_send); currently_sending = 1; } else { LOG_DEBUG("SendHandler Idling\n"); currently_sending = 0; } LOG_DEBUG("SendHandler SENT INTR %x\n", EventData); }
/* * 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; }
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; }