- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello all,
I implemented a data acquisition system on the DE4. In general, I grab a fixed number of samples (called A-line), store them on a RAM and then my SOPC reads the RAM contents (through PIO's) and then Nios sends data through ethernet to the PC (Matlab, with pnet http://www.mathworks.com/matlabcentral/fileexchange/345-tcpudpip-toolbox-2-0-6) I modified the example provided by Terasic, having 2 transfer modes: 1. Slow transfer: I send a command (ASCII 65) to the socket server and it sends one A-line to PC. Works fine, but terribly slow (~4.85 lines/sec). 2. Continuous transfer: I send another command (ASCII 67) and the socket server continuously sends A-lines (~1093 lines/sec), but they overlap each other. See attached picture. I wonder if anyone has an idea how to avoid data from overlapping :confused: I basically modified the function sss_exec_command in the code simple_socket_server.c:
.
.
.
/*sss_exec_command()*/
void sss_exec_command(SSSConn* conn)
{
int bytes_to_process = conn->rx_wr_pos - conn->rx_rd_pos;
INT8U tx_buf;
INT8U *tx_wr_pos = tx_buf;
int pos_ini = tx_wr_pos;
INT8U error_code;
/*
* "SSSCommand" is declared static so that the data will reside
* in the BSS segment. This is done because a pointer to the data in
* SSSCommand
* will be passed via SSSLedCommandQ to the LEDManagementTask.
* Therefore SSSCommand cannot be placed on the stack of the
* SSSSimpleSocketServerTask, since the LEDManagementTask does not
* have access to the stack of the SSSSimpleSocketServerTask.
*/
static INT32U SSSCommand;
SSSCommand = CMD_LEDS_BIT_0_TOGGLE;
while(bytes_to_process--)
{
SSSCommand = toupper(*(conn->rx_rd_pos++));
if(SSSCommand >= ' ' && SSSCommand <= '~')
{
tx_wr_pos += sprintf(tx_wr_pos,
"--> Simple Socket Server Command %c.\n\r",
(char)SSSCommand);
if (SSSCommand == CMD_QUIT)
{
tx_wr_pos += sprintf(tx_wr_pos,"Terminating connection.\n\n\r");
conn->close = 1;
} // END if (SSSCommand == CMD_QUIT)
else
{
if (SSSCommand == 65)
{// Read command A (ASCII code = 65)
//printf("--> Acquiring single %c-line...\n",(char)SSSCommand);
// Wait to finish writing acquired data to the RAM
do
{
acq_busy_signal = IORD_ALTERA_AVALON_PIO_DATA(ACQ_BUSY_PIO_BASE);
// look definitions in ..software\simple_socket_server\simple_socket_server_syslib\Debug\system_description\system.h
}
while (acq_busy_signal == 1);
// Indicate that we are busy reading RAM contents
read_RAM_busy = 1;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
// Do the transfer
buffer_position = 0;
*tx_wr_pos = 0;
tx_wr_pos = pos_ini;
if (acq_busy_signal == 0)//acq_busy_signal == 0
{
for (RAM_address = 1; RAM_address <= NSAMPLES; RAM_address++)
{
// Read data port (from RAM)
ADC_data = IORD_ALTERA_AVALON_PIO_DATA(ADC_DATA_PIO_BASE);
// Write address port (to RAM)
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_ADDRESS_BASE, RAM_address + 1);
dataPointer = &ADC_data;
// Send 16-bit data
tx_buf = dataPointer;
tx_buf = dataPointer;
/* If ADC_data == 32bits
tx_buf = dataPointer;
tx_buf = dataPointer;
tx_buf = dataPointer;
tx_buf = dataPointer;
tx_wr_pos += 4; // 4 bytes*/
tx_wr_pos += 2; // 2 bytes increment
buffer_position += 2;
// Send data every 500*2 bytes
/* if (RAM_address % 500 == 0 && RAM_address != 0)
{
send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0);
buffer_position = 0;
*tx_wr_pos = 0;
tx_wr_pos = pos_ini;
}
else
{
buffer_position = (RAM_address % 500) * 2; //2 bytes
}*/
} // END for (RAM_address = 0; RAM_address <= NSAMPLES; RAM_address++)
send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0);
buffer_position = 0;
*tx_wr_pos = 0;
tx_wr_pos = pos_ini;
//printf("--> A-line sent!\n");
} // END if (acq_busy_signal == 0)
// Indicate that we are done reading RAM contents
read_RAM_busy = 0;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
} // END if (SSSCommand == 65)
else
{
if (SSSCommand == 67)
{
printf("Continuous acquisition! \n");
while (SSSCommand != CMD_QUIT)
{
// Wait to finish writing acquired data to the RAM
do
{
acq_busy_signal = IORD_ALTERA_AVALON_PIO_DATA(ACQ_BUSY_PIO_BASE);
// look definitions in ..software\simple_socket_server\simple_socket_server_syslib\Debug\system_description\system.h
}
while (acq_busy_signal == 1);
// Indicate that we are busy reading RAM contents
read_RAM_busy = 1;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
// Do the transfer
buffer_position = 0;
*tx_wr_pos = 0;
tx_wr_pos = pos_ini;
if (acq_busy_signal == 0)//acq_busy_signal == 0
{
for (RAM_address = 1; RAM_address <= NSAMPLES; RAM_address++)
{
// Read data port (from RAM)
ADC_data = IORD_ALTERA_AVALON_PIO_DATA(ADC_DATA_PIO_BASE);
// Write address port (to RAM)
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_ADDRESS_BASE, RAM_address + 1);
dataPointer = &ADC_data;
// Send 16-bit data
tx_buf = dataPointer;
tx_buf = dataPointer;
tx_wr_pos += 2; // 2 bytes increment
buffer_position += 2;
} // END for (RAM_address = 0; RAM_address <= NSAMPLES; RAM_address++)
send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0);
buffer_position = 0;
*tx_wr_pos = 0;
tx_wr_pos = pos_ini;
} // END if (acq_busy_signal == 0)
// Indicate that we are done reading RAM contents
read_RAM_busy = 0;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
} // END while (SSSCommand != CMD_QUIT)
} // END if (SSSCommand == 67)
else
{
error_code = OSQPost(SSSLEDCommandQ, (void *)SSSCommand);
alt_SSSErrorHandler(error_code, 0);
} // END else if (SSSCommand == 67)
} // END else if (SSSCommand == 65)
} // END else if(SSSCommand == CMD_QUIT)
} // END if(SSSCommand >= ' ' && SSSCommand <= '~')
} // END while(bytes_to_process--)
// ORIGINAL POSITION OF SEND COMMAND!!!
return;
} // END void sss_exec_command(SSSConn* conn)
.
.
.
p.s. change .zip extension to .rar
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
And this is the Matlab code:
%% PNET EXAMPLE
clear; clc;
% Server machine (FPGA)
serverAddress = '192.168.1.234';
portNumber = 30;
NSAMPLES = 1170;
BUFFERSIZE = 9000;
% Creates tcp/ip connection to the specified 'hostname' and port
tcpConn = pnet('tcpconnect',serverAddress,portNumber );
pause(0.1);
% specifies how long read and listen commands blocks before it timeouts.
pnet(tcpConn,'setreadtimeout',0.25);
pnet(tcpConn,'setwritetimeout',0.1);
disp('Connection established')
%% Read elements at the beginning of connection to flush buffer
flush = pnet(tcpConn,'read',BUFFERSIZE,'uint8');
% Show flushed data
disp(char(flush))
%% Write commands '0\n\r' to '6\n\r'
% for iComm = 0:6,
% pnet(tcpConn,'write',uint8());
% % Receive 35+2 characters from FPGA
% textReceived = uint8(swapbytes(pnet(tcpConn,'read',,'uint8')));
% disp(char(textReceived'))
% end
%% Write command to send A-line 'A\n\r'
tic
nLinesPerFrame = 400;
nFrames = 1;
nAcqSamples = nLinesPerFrame*nFrames;
rawData = zeros(,'int16');
for iFrames = 1:nFrames,
for iLines = 1:nLinesPerFrame,
pnet(tcpConn,'write',uint8());
% Reads an array of NSAMPLES elements from a connection
rawData(:,iLines,iFrames) = pnet(tcpConn,'read',,'int16');
end
end
elapsedTime = toc;
disp()
fprintf('Estimated speed %.2f lines/sec\n',nAcqSamples/elapsedTime)
% Reads an array of elements from a connection
% reception = uint32(swapbytes(pnet(tcpConn,'read',,'uint32')));
%% Display previously acquired data
figure
ylim()
for iFrames = 1:size(rawData,3),
for iLines = 1:size(rawData,2),
plot(squeeze(rawData(:,iLines,iFrames)))
ylim()
title(sprintf('Slow Transfer. Frame %d. Line %d',iFrames,iLines))
pause(0.01);
end
end
%% Continuous acquisition 'C\n\r'
% DOES NOT WORK WELL!!!! CORRUPTED DATA!!!
nLinesPerFrame = 400;
nFrames = 25;
nAcqSamples = nLinesPerFrame*nFrames;
rawDataCont = zeros(,'int16');
pnet(tcpConn,'write',uint8());
tic
for iFrames = 1:nFrames,
for iLines = 1:nLinesPerFrame,
% Reads an array of NSAMPLES elements from a connection
% dataReceived = pnet(tcpConn,'read',,'int16');
rawDataCont(:,iLines,iFrames) = pnet(tcpConn,'read',,'int16');
end
end
elapsedTime = toc;
disp()
fprintf('Estimated speed: %.2f lines/sec\n',nAcqSamples/elapsedTime)
%% Display data acquired continuously
figure
ylim()
for iFrames = 1:size(rawDataCont,3),
for iLines = 1:nLinesPerFrame,
plot(squeeze(rawDataCont(:,iLines,iFrames)))
title(sprintf('Continuous Transfer. Frame %d. Line %d',iFrames,iLines))
end
end
%% Closes a tcpconnection (send first a 'Q\n\r')
pnet(tcpConn,'write',);
% Receive 35+2 characters from FPGA
textReceived = uint8(swapbytes(pnet(tcpConn,'read',,'uint8')));
disp(char(textReceived'))
% pause(0.1);
pnet(tcpConn,'close')
disp('Connection closed')
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You need to be able to read the 'write pointer' of the capture hardware.
Then you can loop until there is enough data to fill a frame. Probably means a capture/memory buffer that is a few 'A-line' buffers long.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the advice dsl, I changed my transmission buffer to 2340 bytes (just enough for a single buffer of 1170 samples). Had to add a small delay after the send command to make it work (~17 Mbits/sec), but it seems that my PC is not keeping up to the speed :cry:
case 67:
printf("Continuous acquisition! \n");
//////////////////////////////////////////////////////////
// Continuous acquisition loop (ASCII code = 67)
//////////////////////////////////////////////////////////
//for (iLines = 1; iLines <= nLines; iLines++)
while(1)
{
//////////////////////////////////////////////////////////
// Send single A-line
//////////////////////////////////////////////////////////
// Wait to finish writing acquired data to the RAM
do
{
acq_busy_signal = IORD_ALTERA_AVALON_PIO_DATA(ACQ_BUSY_PIO_BASE);
// look definitions in ..software\simple_socket_server\simple_socket_server_syslib\Debug\system_description\system.h
}
while (acq_busy_signal == 1);
// Indicate that we are busy reading RAM contents
read_RAM_busy = 1;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
// Begin the transfer
tx_wr_pos = tx_buf;
for (RAM_address = 1; RAM_address <= NSAMPLES; RAM_address++)
{
// Read data port (from RAM)
ADC_data = IORD_ALTERA_AVALON_PIO_DATA(ADC_DATA_PIO_BASE);
// Write address port (to RAM)
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_ADDRESS_BASE, RAM_address + 1);
dataPointer = (unsigned char*)&ADC_data;
// Send 16-bit data (swapped upper and lower bytes)
*tx_wr_pos++ = dataPointer;
*tx_wr_pos++ = dataPointer;
} // END for (RAM_address = 0; RAM_address <= NSAMPLES; RAM_address++)
bytes_sent = send(conn->fd, tx_buf, tx_wr_pos - tx_buf, 0);
//printf("L:%d BS: %d\n",iLines,bytes_sent);
// Indicate that we are done reading RAM contents
read_RAM_busy = 0;
IOWR_ALTERA_AVALON_PIO_DATA(READ_RAM_BUSY_PIO_BASE, read_RAM_busy);
//////////////////////////////////////////////////////////
// single A-line transfer done!
//////////////////////////////////////////////////////////
// Wait a little... Should know why...
for (RAM_address = 1; RAM_address <= NSAMPLES; RAM_address++);
} // END of continuous acquisition loop
break;
Any ideas how to know if the packet was received in the PC?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page