diff --git a/clients/tde/src/part/fpgaprogram/part.cpp b/clients/tde/src/part/fpgaprogram/part.cpp index a7edbe2..ced624e 100644 --- a/clients/tde/src/part/fpgaprogram/part.cpp +++ b/clients/tde/src/part/fpgaprogram/part.cpp @@ -103,6 +103,11 @@ FPGAProgramPart::FPGAProgramPart(TQWidget *parentWidget, const char *widgetName, // Create widgets m_base = new FPGAProgramBase(widget()); + // Load configuration + m_config = new KSimpleConfig("ulab_client_part_fpgaprogrammer.conf", false); + m_config->setGroup("UI"); + m_base->programmingInputFile->setURL(m_config->readPathEntry("programmingInputFile", "")); + // Initialize widgets m_base->setMinimumSize(500,350); m_base->programmingLogBox->setReadOnly(true); @@ -115,6 +120,12 @@ FPGAProgramPart::FPGAProgramPart(TQWidget *parentWidget, const char *widgetName, } FPGAProgramPart::~FPGAProgramPart() { + // Save field state for restoration on next load + m_config->setGroup("UI"); + m_config->writeEntry("programmingInputFile", m_base->programmingInputFile->url()); + m_config->sync(); + delete m_config; + if (m_connectionMutex->locked()) { printf("[WARNING] Exiting when data transfer still in progress!\n\r"); fflush(stdout); } @@ -165,6 +176,7 @@ void FPGAProgramPart::connectionClosed() { void FPGAProgramPart::postInit() { setUsingFixedSize(false); + processLockouts(); } bool FPGAProgramPart::openURL(const KURL &url) { @@ -317,6 +329,7 @@ void FPGAProgramPart::mainEventLoop() { } setTickerMessage(i18n("Connected")); + processLockouts(); if (m_commHandlerState == ModeIdle_StateProcessStatus) { m_pingDelayTimer->start(250, TRUE); diff --git a/clients/tde/src/part/fpgaprogram/part.h b/clients/tde/src/part/fpgaprogram/part.h index 48dde79..95ea66c 100644 --- a/clients/tde/src/part/fpgaprogram/part.h +++ b/clients/tde/src/part/fpgaprogram/part.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012 Timothy Pearson + * (c) 2012-2013 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -81,6 +83,7 @@ namespace RemoteLab private: FPGAProgramBase* m_base; TQMutex* m_connectionMutex; + KSimpleConfig* m_config; TQTimer* m_pingDelayTimer; TQTimer* m_forcedUpdateTimer; TQTimer* m_updateTimeoutTimer; diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp index dc5c9d9..c9589f5 100644 --- a/clients/tde/src/part/fpgaview/part.cpp +++ b/clients/tde/src/part/fpgaview/part.cpp @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012 Timothy Pearson + * (c) 2012-2013 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ @@ -589,7 +589,7 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj m_commHandlerState(0), m_commHandlerMode(0), m_commHandlerNextState(0), m_commHandlerNextMode(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0), m_8bitInputValue(0), m_8bitOutputValue(0), m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xff), m_7segDigit2OutputValue(0xff), m_7segDigit1OutputValue(0xff), m_7segDigit0OutputValue(0xff), - m_batchOutputFile(NULL), m_dataOutputFile(NULL), + m_batchOutputFile(NULL), m_dataOutputFile(NULL), m_dataMemorySize(16384), m_inputImageViewer(NULL), m_outputImageViewer(NULL) { // Initialize important base class variables @@ -611,6 +611,16 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj // Create widgets m_base = new FPGAViewBase(widget()); + // Load configuration + m_config = new KSimpleConfig("ulab_client_part_fpgaviewer.conf", false); + m_config->setGroup("UI"); + m_interfaceMode = (RemoteLab::FPGAViewPart::InterfaceMode)(m_config->readNumEntry("interfaceMode", BasicInterfaceMode)); + m_base->batchTestInputFile->setURL(m_config->readPathEntry("batchTestInputFile", "")); + m_base->batchTestOutputFile->setURL(m_config->readPathEntry("batchTestOutputFile", "")); + m_base->batchTest16BitCheckBox->setChecked(m_config->readBoolEntry("batchUsing16Bit", false)); + m_base->dataProcessingInputFile->setURL(m_config->readPathEntry("dataProcessingInputFile", "")); + m_base->dataProcessingOutputFile->setURL(m_config->readPathEntry("dataProcessingOutputFile", "")); + // Create menu actions // Submenus TDEActionCollection *const ac = actionCollection(); @@ -740,12 +750,21 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj connect(m_base->dataProcessingInputFile, SIGNAL(textChanged(const TQString &)), this, SLOT(processLockouts())); connect(m_base->dataProcessingOutputFile, SIGNAL(textChanged(const TQString &)), this, SLOT(processLockouts())); - processAllGraphicsUpdates(); - TQTimer::singleShot(0, this, TQT_SLOT(postInit())); } FPGAViewPart::~FPGAViewPart() { + // Save field state for restoration on next load + m_config->setGroup("UI"); + m_config->writeEntry("interfaceMode", m_interfaceMode); + m_config->writeEntry("batchTestInputFile", m_base->batchTestInputFile->url()); + m_config->writeEntry("batchTestOutputFile", m_base->batchTestOutputFile->url()); + m_config->writeEntry("batchUsing16Bit", m_base->batchTest16BitCheckBox->isChecked()); + m_config->writeEntry("dataProcessingInputFile", m_base->dataProcessingInputFile->url()); + m_config->writeEntry("dataProcessingOutputFile", m_base->dataProcessingOutputFile->url()); + m_config->sync(); + delete m_config; + // Close any active image display windows m_interfaceMode = BasicInterfaceMode; if (m_inputImageViewer) { @@ -1056,6 +1075,8 @@ void FPGAViewPart::connectionClosed() { } void FPGAViewPart::postInit() { + processAllGraphicsUpdates(); + setUsingFixedSize(true); connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(updateDisplay())); connect(m_timeoutTimer, SIGNAL(timeout()), this, SLOT(updateDisplay())); @@ -1433,7 +1454,7 @@ void FPGAViewPart::updateDisplay() { // Is it an image? m_dataIsImage = m_dataInputImage.load(m_base->dataProcessingInputFile->url()); - if ((file.size() <= 16384) || ((m_dataIsImage) && ((m_dataInputImage.height()*m_dataInputImage.width()) <= 16384))) { + if ((file.size() <= m_dataMemorySize) || ((m_dataIsImage) && ((m_dataInputImage.height()*m_dataInputImage.width()) <= m_dataMemorySize))) { m_base->dataProcessingProgressBar->setTotalSteps(0); m_base->dataProcessingProgressBar->setProgress(0); @@ -1472,23 +1493,21 @@ void FPGAViewPart::updateDisplay() { m_socket->writeBlock("M\r", 2); m_socket->writeBufferedData(); int len = m_dataByteArray.size(); - int txlen = 16384; + int txlen = m_dataMemorySize; if (len >= txlen) { len = txlen; } - TQByteArray dataToSend(16384*2); + TQByteArray dataToSend(m_dataMemorySize); for (i=0; idataProcessingProgressBar->setTotalSteps(txlen*4); + m_base->dataProcessingProgressBar->setTotalSteps(txlen*2); m_base->dataProcessingProgressBar->setProgress(0); int offset = 0; - while (offset < (txlen*2)) { + while (offset < txlen) { m_socket->writeBlock(dataToSend.data()+offset, 1024); m_socket->writeBufferedData(); offset = offset + 1024; @@ -1553,13 +1572,13 @@ void FPGAViewPart::updateDisplay() { } } else if (m_commHandlerState == 2) { - if (m_socket->bytesAvailable() >= 16384) { - TQByteArray recData(16384); + if (m_socket->bytesAvailable() >= m_dataMemorySize) { + TQByteArray recData(m_dataMemorySize); int offset = 0; - while (offset < 16384) { + while (offset < m_dataMemorySize) { m_socket->readBlock(recData.data()+offset, 1024); offset = offset + 1024; - m_base->dataProcessingProgressBar->setProgress((16384*2) + offset); + m_base->dataProcessingProgressBar->setProgress((m_dataMemorySize*2) + offset); } m_base->dataProcessingStatusLabel->setText(i18n("Writing data to file") + "..."); diff --git a/clients/tde/src/part/fpgaview/part.h b/clients/tde/src/part/fpgaview/part.h index b49ace2..81f74f7 100644 --- a/clients/tde/src/part/fpgaview/part.h +++ b/clients/tde/src/part/fpgaview/part.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (c) 2012 Timothy Pearson + * (c) 2012-2013 Timothy Pearson * Raptor Engineering * http://www.raptorengineeringinc.com */ @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -207,6 +209,7 @@ namespace RemoteLab private: FPGAViewBase* m_base; TQMutex* m_connectionMutex; + KSimpleConfig* m_config; TQTimer* m_updateTimer; TQTimer* m_timeoutTimer; @@ -247,6 +250,7 @@ namespace RemoteLab TQImage m_dataInputImage; TQFile* m_dataOutputFile; TQByteArray m_dataByteArray; + int m_dataMemorySize; ImageViewerWindow* m_inputImageViewer; ImageViewerWindow* m_outputImageViewer; diff --git a/fpga/common/remote_access.v b/fpga/common/remote_access.v index 33fc99b..1482cfb 100644 --- a/fpga/common/remote_access.v +++ b/fpga/common/remote_access.v @@ -50,10 +50,13 @@ module remote_access( output remote_access_lcd_rs_out, output remote_access_lcd_rw_out, output remote_access_lcd_enable_out); + + parameter RAM_ADDR_BITS = 14; reg [7:0] remote_access_4_bit_input_reg; reg [7:0] remote_access_8_bit_input_reg; reg [15:0] remote_access_16_bit_input_reg; + reg [15:0] remote_access_data_ram_size_reg = (2**RAM_ADDR_BITS); reg [3:0] remote_access_lcd_data_out_reg; reg remote_access_lcd_rs_out_reg; reg remote_access_lcd_rw_out_reg; @@ -197,7 +200,7 @@ module remote_access( reg [13:0] data_storage_addra_reg; reg data_storage_write_enable_reg; - data_storage data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra), + data_storage #(RAM_ADDR_BITS) data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra), .wea(data_storage_write_enable), .douta(data_storage_data_out)); assign data_storage_clka = (data_storage_remote_enable) ? main_fifty_clock : sram_clock_in; @@ -258,7 +261,6 @@ module remote_access( reg enable_remote_access_input = 1; reg remote_access_input_enable_prev = 0; - reg prev_was_carriage_return = 0; reg [7:0] lcd_display_string [31:0]; @@ -370,7 +372,7 @@ module remote_access( if ((transmit_dsp_rx_complete == 1) && (transmit_dsp_rx_complete_done == 0)) begin TxD_data = 77; - + TxD_start = 1; tx_toggle = 1; @@ -385,13 +387,13 @@ module remote_access( end else begin data_storage_write_enable_reg = 0; TxD_data = data_storage_data_out; - + TxD_start = 1; tx_toggle = 1; transmit_dsp_status_counter = transmit_dsp_status_counter + 1; data_storage_addra_reg = transmit_dsp_status_counter; - if (transmit_dsp_status_counter > 16384) begin + if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin transmit_dsp_status_done = 1; data_storage_write_enable_reg = 1'bz; data_storage_addra_reg = 14'bz; @@ -571,164 +573,165 @@ module remote_access( transmit_dsp_status = 1; end - if (RxD_data_ready == 1) begin + if (RxD_data_ready == 1) begin if (serial_character_received == 0) begin serial_rx_data_reg = RxD_data; serial_rx_strobe_reg = 1; // Signal new data... if (seize_serial_tx == 0) begin - // Parse the command and see what it is - serial_character_received = 1; - if (RxD_data == 13) begin - // Carriage Return! The serial_command_buffer holds the command! Parse it! - if (next_byte_is_command == 0) begin - if (serial_command_buffer == 65) begin - // Display update requested - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 65; - end + if (next_byte_is_command_prev_command == 77) begin + // DSP input data + if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin + data_storage_remote_enable = 1; + data_storage_addra_reg = dsp_update_counter; + data_storage_dina_reg = serial_rx_data_reg; + data_storage_write_enable_reg = 1; + data_write_timer = 3; + dsp_update_counter = dsp_update_counter + 1; - if (serial_command_buffer == 66) begin - // 8 bit input update - if (enable_remote_access_input == 1) begin + // TESTING ONLY!!! + //if (dsp_update_counter < 17) begin + // received_lcd_display_string[dsp_update_counter - 1] = serial_command_buffer; + //end + + if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin + next_byte_is_command = 0; + data_storage_write_enable_reg = 0; + data_storage_remote_enable = 0; + sram_available_reg = 1; + data_storage_write_enable_reg = 1'bz; + data_storage_addra_reg = 14'bz; + waiting_on_dsp_processing = 1; + transmit_dsp_rx_complete = 1; + next_byte_is_command_prev_command = 0; + + // TESTING ONLY!!! + //transmit_dsp_status = 1; + end + end + end else begin + // Parse the command and see what it is + serial_character_received = 1; + if (serial_rx_data_reg == 13) begin + // Carriage Return! The serial_command_buffer holds the command! Parse it! + if (next_byte_is_command == 0) begin + if (serial_command_buffer == 65) begin + // Display update requested next_byte_is_command = 1; serial_update_counter = 0; - next_byte_is_command_prev_command = 66; + next_byte_is_command_prev_command = 65; end - end - - if (serial_command_buffer == 67) begin - // 16 bit input update - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 67; - end - - if (serial_command_buffer == 68) begin - // 8 bit output status - transmit_8_bit_status = 1; - end - - if (serial_command_buffer == 69) begin - // 16 bit output status - transmit_16_bit_status = 1; - end - - if (serial_command_buffer == 70) begin - // System status - transmit_main_status = 1; - end - - if (serial_command_buffer == 71) begin - // Simulate center button press - enable_remote_access_input = !enable_remote_access_input; - end - - if (serial_command_buffer == 72) begin - // Local input status - transmit_input_status = 1; - end - - if (serial_command_buffer == 73) begin - // 4 bit input update - if (enable_remote_access_input == 1) begin + + if (serial_command_buffer == 66) begin + // 8 bit input update + if (enable_remote_access_input == 1) begin + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 66; + end + end + + if (serial_command_buffer == 67) begin + // 16 bit input update next_byte_is_command = 1; serial_update_counter = 0; - next_byte_is_command_prev_command = 73; + next_byte_is_command_prev_command = 67; end - end - - if (serial_command_buffer == 74) begin - // 4 bit output status - transmit_4_bit_status = 1; - end - - if (serial_command_buffer == 75) begin - // Transmit the contents of the LCD... - transmit_lcd_status = 1; - end - - if (serial_command_buffer == 76) begin - // Transmit the contents of the LCD... - transmit_all_data_state = 1; - transmit_lcd_status = 1; - end - - if (serial_command_buffer == 77) begin - // Receive offline DSP data - next_byte_is_command = 1; - dsp_update_counter = 0; - next_byte_is_command_prev_command = 77; - end - - if (serial_command_buffer == 78) begin - // Transmit the contents of RAM... - transmit_dsp_status = 1; - end - end else begin - if (next_byte_is_command == 1) begin - // The previous byte was the command--now load in the data! - if (next_byte_is_command_prev_command == 65) begin - if (serial_update_counter < 32) begin - received_lcd_display_string[serial_update_counter] = serial_command_buffer; - serial_update_counter = serial_update_counter + 1; - end else begin - update_lcd_display = 1; - serial_command_timer = 255; - next_byte_is_command = 0; - end + + if (serial_command_buffer == 68) begin + // 8 bit output status + transmit_8_bit_status = 1; end - // 4 bit input update - if (next_byte_is_command_prev_command == 73) begin - remote_access_4_bit_input_reg = serial_command_buffer; - next_byte_is_command = 0; + if (serial_command_buffer == 69) begin + // 16 bit output status + transmit_16_bit_status = 1; end - // 8 bit input update - if (next_byte_is_command_prev_command == 66) begin - remote_access_8_bit_input_reg = serial_command_buffer; - next_byte_is_command = 0; + if (serial_command_buffer == 70) begin + // System status + transmit_main_status = 1; end - // 16 bit input update - if (next_byte_is_command_prev_command == 67) begin - if (serial_update_counter == 0) begin - remote_access_16_bit_input_reg[15:8] = serial_command_buffer; - serial_update_counter = 1; - end else begin - remote_access_16_bit_input_reg[7:0] = serial_command_buffer; - next_byte_is_command = 0; + if (serial_command_buffer == 71) begin + // Simulate center button press + enable_remote_access_input = !enable_remote_access_input; + end + + if (serial_command_buffer == 72) begin + // Local input status + transmit_input_status = 1; + end + + if (serial_command_buffer == 73) begin + // 4 bit input update + if (enable_remote_access_input == 1) begin + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 73; end end - // DSP input data - if (next_byte_is_command_prev_command == 77) begin - if (dsp_update_counter < 16384) begin - data_storage_remote_enable = 1; - data_storage_addra_reg = dsp_update_counter; - data_storage_dina_reg = serial_command_buffer; - data_storage_write_enable_reg = 1; - data_write_timer = 3; - dsp_update_counter = dsp_update_counter + 1; - - // TESTING ONLY!!! - //if (dsp_update_counter < 17) begin - // received_lcd_display_string[dsp_update_counter - 1] = serial_command_buffer; - //end - - if (dsp_update_counter >= 16384) begin + if (serial_command_buffer == 74) begin + // 4 bit output status + transmit_4_bit_status = 1; + end + + if (serial_command_buffer == 75) begin + // Transmit the contents of the LCD... + transmit_lcd_status = 1; + end + + if (serial_command_buffer == 76) begin + // Transmit the contents of the LCD... + transmit_all_data_state = 1; + transmit_lcd_status = 1; + end + + if (serial_command_buffer == 77) begin + // Receive offline DSP data + next_byte_is_command = 1; + dsp_update_counter = 0; + next_byte_is_command_prev_command = 77; + end + + if (serial_command_buffer == 78) begin + // Transmit the contents of RAM... + transmit_dsp_status = 1; + end + end else begin + if (next_byte_is_command == 1) begin + // The previous byte was the command--now load in the data! + if (next_byte_is_command_prev_command == 65) begin + if (serial_update_counter < 32) begin + received_lcd_display_string[serial_update_counter] = serial_command_buffer; + serial_update_counter = serial_update_counter + 1; + end else begin + update_lcd_display = 1; + serial_command_timer = 255; + next_byte_is_command = 0; + end + end + + // 4 bit input update + if (next_byte_is_command_prev_command == 73) begin + remote_access_4_bit_input_reg = serial_command_buffer; + next_byte_is_command = 0; + end + + // 8 bit input update + if (next_byte_is_command_prev_command == 66) begin + remote_access_8_bit_input_reg = serial_command_buffer; + next_byte_is_command = 0; + end + + // 16 bit input update + if (next_byte_is_command_prev_command == 67) begin + if (serial_update_counter == 0) begin + remote_access_16_bit_input_reg[15:8] = serial_command_buffer; + serial_update_counter = 1; + end else begin + remote_access_16_bit_input_reg[7:0] = serial_command_buffer; next_byte_is_command = 0; - data_storage_write_enable_reg = 0; - data_storage_remote_enable = 0; - sram_available_reg = 1; - data_storage_write_enable_reg = 1'bz; - data_storage_addra_reg = 14'bz; - waiting_on_dsp_processing = 1; - transmit_dsp_rx_complete = 1; - - // TESTING ONLY!!! - //transmit_dsp_status = 1; end end end @@ -740,12 +743,6 @@ module remote_access( //if (RxD_data != 10) begin // Ignore linefeeds serial_command_buffer = RxD_data; //end - - if (RxD_data == 13) begin - prev_was_carriage_return = 1; - end else begin - prev_was_carriage_return = 0; - end serial_receiver_toggler = serial_receiver_toggler + 1; end diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v index f1d10be..60c1dff 100644 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v +++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v @@ -13,20 +13,20 @@ module data_storage( input wea, output reg [7:0] douta); - parameter RAM_WIDTH = 8; - parameter RAM_ADDR_BITS = 14; - - // Xilinx specific directive - (* RAM_STYLE="BLOCK" *) - - reg [RAM_WIDTH-1:0] data_storage_ram [(2**RAM_ADDR_BITS)-1:0]; - - always @(posedge clka) begin - if (wea) begin + parameter RAM_ADDR_BITS = 14; + parameter RAM_WIDTH = 8; + + // Xilinx specific directive + (* RAM_STYLE="BLOCK" *) + + reg [RAM_WIDTH-1:0] data_storage_ram [(2**RAM_ADDR_BITS)-1:0]; + + always @(posedge clka) begin + if (wea) begin data_storage_ram[addra] <= dina; douta <= dina; - end else begin - douta <= data_storage_ram[addra]; + end else begin + douta <= data_storage_ram[addra]; end end