Update test program
Add test register. Wait for 4k data blocks when possible.
This commit is contained in:
parent
4abc2ee165
commit
131fe91c67
|
@ -38,6 +38,7 @@
|
|||
#define REG_DMA_ADDR_PTR 0x0210
|
||||
#define REG_DMA_CHANNEL_CTRL 0x0214
|
||||
#define REG_DMA_INTR_CTRL 0x0218
|
||||
#define REG_TEST_DIVIDER 0x0408
|
||||
|
||||
|
||||
struct puzzlefw_context {
|
||||
|
@ -434,6 +435,9 @@ static void show_status(struct puzzlefw_context *ctx)
|
|||
|
||||
v = puzzlefw_read_reg(ctx, REG_DMA_INTR_CTRL);
|
||||
printf(" dma_intr_ctrl = 0x%08x\n", v);
|
||||
|
||||
v = puzzlefw_read_reg(ctx, REG_TEST_DIVIDER);
|
||||
printf(" test_divider = 0x%08x\n", v);
|
||||
}
|
||||
|
||||
|
||||
|
@ -494,8 +498,11 @@ static void blast_dma(struct puzzlefw_context *ctx)
|
|||
// Set invalid limit to keep the writer blasting.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_ADDR_LIMIT, 0xffffffff);
|
||||
|
||||
// Initialize and enable DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 3);
|
||||
// Initialize DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 2);
|
||||
|
||||
// Enable DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 1);
|
||||
|
||||
struct timespec tp;
|
||||
tp.tv_sec = 10;
|
||||
|
@ -646,15 +653,15 @@ int transmit_dma_data(struct puzzlefw_context *ctx, int conn)
|
|||
// Maximum block size per TCP send() call.
|
||||
const uint32_t send_max_block = 65536;
|
||||
|
||||
// When buffer is empty, sleep until this amount becomes available.
|
||||
// Sleep until this number of bytes is available in the buffer.
|
||||
const uint32_t wait_block_size = 4096;
|
||||
|
||||
// Reserve this number of bytes in the buffer to avoid ambiguous pointers.
|
||||
const uint32_t pointer_margin = 1024;
|
||||
|
||||
// When buffer is empty, sleep at most this duration.
|
||||
// Sleep at most this duration if there is insufficient data in the buffer.
|
||||
const int timeout_ms = 10;
|
||||
|
||||
// Reserve this number of bytes in the buffer to avoid ambiguous pointers.
|
||||
const uint32_t pointer_margin = 4096;
|
||||
|
||||
assert(ctx->dma_buf_size >= 2 * wait_block_size);
|
||||
assert(send_max_block % ctx->dma_transfer_size == 0);
|
||||
assert(wait_block_size % ctx->dma_transfer_size == 0);
|
||||
|
@ -681,8 +688,11 @@ int transmit_dma_data(struct puzzlefw_context *ctx, int conn)
|
|||
// Enable AXI DMA.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_EN, 1);
|
||||
|
||||
// Initialize and enable DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 3);
|
||||
// Initialize DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 2);
|
||||
|
||||
// Enable DMA writer.
|
||||
puzzlefw_write_reg(ctx, REG_DMA_CHANNEL_CTRL, 1);
|
||||
|
||||
uint32_t read_pointer = 0;
|
||||
int ret;
|
||||
|
@ -698,12 +708,14 @@ int transmit_dma_data(struct puzzlefw_context *ctx, int conn)
|
|||
break;
|
||||
}
|
||||
|
||||
// Check for data in buffer.
|
||||
// Determine number of bytes available.
|
||||
uint32_t write_pointer = puzzlefw_read_reg(ctx, REG_DMA_ADDR_PTR);
|
||||
uint32_t navail = (write_pointer >= read_pointer) ?
|
||||
(write_pointer - read_pointer) :
|
||||
(ctx->dma_buf_size + write_pointer - read_pointer);
|
||||
|
||||
if (write_pointer == read_pointer) {
|
||||
|
||||
// Wait for new data.
|
||||
// Wait for enough data in the buffer, or timeout.
|
||||
if (navail < wait_block_size) {
|
||||
ret = wait_dma_data(ctx, conn,
|
||||
read_pointer,
|
||||
wait_block_size,
|
||||
|
@ -717,56 +729,56 @@ int transmit_dma_data(struct puzzlefw_context *ctx, int conn)
|
|||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
write_pointer = puzzlefw_read_reg(ctx, REG_DMA_ADDR_PTR);
|
||||
}
|
||||
|
||||
// Determine number of bytes available.
|
||||
// If the write pointer wrapped around the end of the buffer,
|
||||
// stop at the end of the buffer and process the rest in the next
|
||||
// pass through the loop.
|
||||
uint32_t navail =
|
||||
(write_pointer >= read_pointer) ?
|
||||
(write_pointer - read_pointer) :
|
||||
(ctx->dma_buf_size - read_pointer);
|
||||
// Determine number of bytes available.
|
||||
// If the write pointer wrapped around the end of the buffer,
|
||||
// stop at the end of the buffer and process the rest in the next
|
||||
// pass through the loop.
|
||||
navail = (write_pointer >= read_pointer) ?
|
||||
(write_pointer - read_pointer) :
|
||||
(ctx->dma_buf_size - read_pointer);
|
||||
|
||||
// Make sure the CPU view of the DMA buffer is up to date
|
||||
// relative to the state previously reported via registers.
|
||||
puzzlefw_sync_dma();
|
||||
// Make sure the CPU view of the DMA buffer is up to date
|
||||
// relative to the state previously reported via registers.
|
||||
puzzlefw_sync_dma();
|
||||
|
||||
// Transmit available data in blocks of 64 kB.
|
||||
while (navail > 0) {
|
||||
uint32_t block_size =
|
||||
(navail < send_max_block) ? navail : send_max_block;
|
||||
// Transmit available data in blocks of 64 kB.
|
||||
while (navail > 0) {
|
||||
uint32_t block_size =
|
||||
(navail < send_max_block) ? navail : send_max_block;
|
||||
|
||||
// Send data to socket.
|
||||
ret = send_all(conn,
|
||||
(void*)ctx->dma_buf + read_pointer, block_size);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Update read pointer and update DMA writer limit.
|
||||
read_pointer += block_size;
|
||||
if (read_pointer > pointer_margin) {
|
||||
puzzlefw_write_reg(ctx, REG_DMA_ADDR_LIMIT,
|
||||
read_pointer - pointer_margin);
|
||||
}
|
||||
|
||||
navail -= block_size;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
// Send data to socket.
|
||||
ret = send_all(conn,
|
||||
(void*)ctx->dma_buf + read_pointer, block_size);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 2) {
|
||||
// Connection closed.
|
||||
ret = 0;
|
||||
break;
|
||||
// Update read pointer and update DMA writer limit.
|
||||
read_pointer += block_size;
|
||||
if (read_pointer > pointer_margin) {
|
||||
puzzlefw_write_reg(ctx, REG_DMA_ADDR_LIMIT,
|
||||
read_pointer - pointer_margin);
|
||||
}
|
||||
|
||||
if (read_pointer == ctx->dma_buf_size) {
|
||||
read_pointer = 0;
|
||||
}
|
||||
navail -= block_size;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 2) {
|
||||
// Connection closed.
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Wrap read pointer at end of buffer.
|
||||
if (read_pointer == ctx->dma_buf_size) {
|
||||
read_pointer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,6 +860,8 @@ int main(int argc, char **argv)
|
|||
int dmaclear = 0;
|
||||
int blastdma = 0;
|
||||
int server = 0;
|
||||
int set_divider = 0;
|
||||
int divider;
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "show") == 0) {
|
||||
show = 1;
|
||||
|
@ -863,6 +877,9 @@ int main(int argc, char **argv)
|
|||
dmaclear = 1;
|
||||
} else if (argc == 2 && strcmp(argv[1], "blastdma") == 0) {
|
||||
blastdma = 1;
|
||||
} else if (argc == 3 && strcmp(argv[1], "divider") == 0) {
|
||||
set_divider = 1;
|
||||
divider = atoi(argv[2]);
|
||||
} else if (argc == 2 && strcmp(argv[1], "server") == 0) {
|
||||
server = 1;
|
||||
} else {
|
||||
|
@ -932,6 +949,10 @@ int main(int argc, char **argv)
|
|||
blast_dma(&ctx);
|
||||
}
|
||||
|
||||
if (set_divider) {
|
||||
puzzlefw_write_reg(&ctx, REG_TEST_DIVIDER, divider);
|
||||
}
|
||||
|
||||
if (server) {
|
||||
run_server(&ctx);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue