From 7997af3f4f6d8ca680e381cb1bee4ebe3b82e175 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Mon, 14 Oct 2013 13:44:56 -0500 Subject: [PATCH] Fix 7-segment LED display and add sample driver for the same --- clients/tde/configure.in | 142 ------------------ clients/tde/src/part/fpgaview/part.cpp | 51 ++++--- clients/tde/src/part/fpgaview/part.h | 11 +- fpga/common/remote_access.v | 71 ++++++--- .../spartan_6/s6_remotefpga_test/main.ucf | 6 +- .../spartan_6/s6_remotefpga_test/main.v | 73 +++++++-- 6 files changed, 150 insertions(+), 204 deletions(-) delete mode 100644 clients/tde/configure.in diff --git a/clients/tde/configure.in b/clients/tde/configure.in deleted file mode 100644 index c8f9931..0000000 --- a/clients/tde/configure.in +++ /dev/null @@ -1,142 +0,0 @@ -dnl ======================================================= -dnl FILE: ./admin/configure.in.min -dnl ======================================================= - -dnl This file is part of the KDE libraries/packages -dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org) - -dnl This file is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Library General Public -dnl License as published by the Free Software Foundation; either -dnl version 2 of the License, or (at your option) any later version. - -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Library General Public License for more details. - -dnl You should have received a copy of the GNU Library General Public License -dnl along with this library; see the file COPYING.LIB. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -dnl Boston, MA 02110-1301, USA. - -# Original Author was Kalle@kde.org -# I lifted it in some mater. (Stephan Kulow) -# I used much code from Janos Farkas - -dnl Process this file with autoconf to produce a configure script. - -AC_INIT(acinclude.m4) dnl a source file from your sub dir - -dnl This is so we can use kde-common -AC_CONFIG_AUX_DIR(admin) - -dnl This ksh/zsh feature conflicts with `cd blah ; pwd` -unset CDPATH - -dnl Checking host/target/build systems, for make, install etc. -AC_CANONICAL_SYSTEM -dnl Perform program name transformation -AC_ARG_PROGRAM - -dnl Automake doc recommends to do this only here. (Janos) -AM_INIT_AUTOMAKE(tde, "3.5.10") dnl searches for some needed programs - -KDE_SET_PREFIX - -dnl generate the config header -AM_CONFIG_HEADER(config.h) dnl at the distribution this done - -dnl Checks for programs. -AC_PROG_CC -AC_PROG_CXX -AC_CHECK_COMPILERS -AC_ENABLE_SHARED(yes) -AC_ENABLE_STATIC(no) -KDE_PROG_LIBTOOL - -dnl for NLS support. Call them in this order! -dnl WITH_NLS is for the po files -AM_KDE_WITH_NLS - -KDE_USE_QT(3.2) -AC_PATH_KDE -dnl ======================================================= -dnl FILE: configure.in.in -dnl ======================================================= - -#MIN_CONFIG(3.2) -CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS" - -if test "$build_arts" = "yes"; then - AC_DEFINE(USE_ARTS, 1, [If we use arts volume]) - LIB_ARTS="-lartskde" - AC_SUBST(LIB_ARTS) -fi - -KDE_INIT_DOXYGEN([The API Reference], [Version $VERSION]) - -KDE_CREATE_SUBDIRSLIST -AC_CONFIG_FILES([ Makefile ]) -AC_CONFIG_FILES([ doc/Makefile ]) -AC_CONFIG_FILES([ misc/Makefile ]) -AC_CONFIG_FILES([ po/Makefile ]) -AC_CONFIG_FILES([ src/Makefile ]) -AC_CONFIG_FILES([ src/app/Makefile ]) -AC_CONFIG_FILES([ src/app/views/Makefile ]) -AC_CONFIG_FILES([ src/dialogs/Makefile ]) -AC_CONFIG_FILES([ src/part/Makefile ]) -AC_CONFIG_FILES([ src/part/adminconsole/Makefile ]) -AC_CONFIG_FILES([ src/part/adminusermgmt/Makefile ]) -AC_CONFIG_FILES([ src/part/commanalyzer/Makefile ]) -AC_CONFIG_FILES([ src/part/fpgaprogram/Makefile ]) -AC_CONFIG_FILES([ src/part/fpgaview/Makefile ]) -AC_CONFIG_FILES([ src/part/scope/Makefile ]) -AC_CONFIG_FILES([ src/part/sensormonitor/Makefile ]) -AC_CONFIG_FILES([ src/widgets/Makefile ]) -AC_OUTPUT -# Check if KDE_SET_PREFIX was called, and --prefix was passed to configure -if test -n "$kde_libs_prefix" -a -n "$given_prefix"; then - # And if so, warn when they don't match - if test "$kde_libs_prefix" != "$given_prefix"; then - # And if kde doesn't know about the prefix yet - echo ":"`tde-config --path exe`":" | grep ":$given_prefix/bin/:" 2>&1 >/dev/null - if test $? -ne 0; then - echo "" - echo "Warning: you chose to install this package in $given_prefix," - echo "but KDE was found in $kde_libs_prefix." - echo "For this to work, you will need to tell KDE about the new prefix, by ensuring" - echo "that TDEDIRS contains it, e.g. export TDEDIRS=$given_prefix:$kde_libs_prefix" - echo "Then restart KDE." - echo "" - fi - fi -fi - -if test x$GXX = "xyes" -a x$kde_have_gcc_visibility = "xyes" -a x$kde_cv_val_qt_gcc_visibility_patched = "xno"; then - echo "" - echo "Your GCC supports symbol visibility, but the patch for Qt supporting visibility" - echo "was not included. Therefore, GCC symbol visibility support remains disabled." - echo "" - echo "For better performance, consider including the Qt visibility supporting patch" - echo "located at:" - echo "" - echo "http://bugs.kde.org/show_bug.cgi?id=109386" - echo "" - echo "and recompile all of Qt and KDE. Note, this is entirely optional and" - echo "everything will continue to work just fine without it." - echo "" -fi - -if test "$all_tests" = "bad"; then - if test ! "$cache_file" = "/dev/null"; then - echo "" - echo "Please remove the file $cache_file after changing your setup" - echo "so that configure will find the changes next time." - echo "" - fi -else - echo "" - echo "Good - your configure finished. Start make now" - echo "" -fi diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp index c312c66..dc5c9d9 100644 --- a/clients/tde/src/part/fpgaview/part.cpp +++ b/clients/tde/src/part/fpgaview/part.cpp @@ -140,6 +140,7 @@ FPGA7Segment::~FPGA7Segment() { void FPGA7Segment::init() { setFrameStyle(TQFrame::Box | TQFrame::Raised); + prevSegments = 0; val = 0; smallPoint = TRUE; setSegmentStyle(Flat); @@ -147,34 +148,32 @@ void FPGA7Segment::init() { m_currentSegments = (char*)malloc(sizeof(char)*9); m_prevSegments[0] = 99; m_currentSegments[0] = 99; - d = 0; setSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum)); } -void FPGA7Segment::setLitSegments(unsigned int segs) { +void FPGA7Segment::setLitSegments(unsigned char segs) { // This produces an array of up to 10 chars, with each char being the number of a lit segment, and the list being terminated with the number 99 // The bit input in segs is active high // The bit sequence, MSB to LSB, is dp a b c d e f g // Segment letters are taken from ug130.pdf - // 0: a - // 1: f - // 2: d - // 3: g - // 4: e - // 5: c - // 6: b - // 7: dp - - int i = 0; - if (segs & 0x80) { m_currentSegments[i] = 7; i++; } - if (segs & 0x40) { m_currentSegments[i] = 0; i++; } - if (segs & 0x20) { m_currentSegments[i] = 6; i++; } - if (segs & 0x10) { m_currentSegments[i] = 5; i++; } - if (segs & 0x08) { m_currentSegments[i] = 2; i++; } - if (segs & 0x04) { m_currentSegments[i] = 4; i++; } - if (segs & 0x02) { m_currentSegments[i] = 1; i++; } - if (segs & 0x01) { m_currentSegments[i] = 3; i++; } - m_currentSegments[i] = 99; + + if (prevSegments != segs) { + int i = 0; + if (segs & 0x80) { m_currentSegments[i] = 7; i++; } + if (segs & 0x40) { m_currentSegments[i] = 0; i++; } + if (segs & 0x20) { m_currentSegments[i] = 2; i++; } + if (segs & 0x10) { m_currentSegments[i] = 5; i++; } + if (segs & 0x08) { m_currentSegments[i] = 6; i++; } + if (segs & 0x04) { m_currentSegments[i] = 4; i++; } + if (segs & 0x02) { m_currentSegments[i] = 1; i++; } + if (segs & 0x01) { m_currentSegments[i] = 3; i++; } + + m_currentSegments[i] = 99; + + update(); + } + + prevSegments = segs; } void FPGA7Segment::drawContents( TQPainter *p ) @@ -230,7 +229,7 @@ void FPGA7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const const char erase = 0; const char draw = 1; - const char leaveAlone = 2; +// const char leaveAlone = 2; segs = m_prevSegments; for ( nErases=0; segs[nErases] != 99; nErases++ ) { @@ -242,8 +241,12 @@ void FPGA7Segment::drawDigit(const TQPoint &pos, TQPainter &p, int segLen, const for(i = 0 ; segs[i] != 99 ; i++) { for ( j=0; j 30) begin + + if (digit_blanker_1 > 60) begin led_display_bytes[0] = 255; end - if (digit_blanker_2 > 30) begin + if (digit_blanker_2 > 60) begin led_display_bytes[1] = 255; end - if (digit_blanker_3 > 30) begin + if (digit_blanker_3 > 60) begin led_display_bytes[2] = 255; end - if (digit_blanker_4 > 30) begin + if (digit_blanker_4 > 60) begin led_display_bytes[3] = 255; end end @@ -245,7 +274,7 @@ module remote_access( reg transmit_dsp_rx_complete = 0; reg transmit_dsp_rx_complete_done = 0; - // Transmit! + // Transmit! always @(posedge clk_div_by_two) begin transmitter_4_bit_state = remote_access_4_bit_output; transmitter_8_bit_state = remote_access_8_bit_output; diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf index ab433e5..c9a68dd 100644 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf +++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf @@ -1,8 +1,8 @@ # (c) 2013 Timothy Pearson, Raptor Engineering # Released into the Public Domain -NET "clk" LOC = "V10"; +NET "clk" LOC = "V10" | IOSTANDARD = "LVCMOS33"; TIMESPEC TS_clk = PERIOD clk 100000 kHz; -NET "serial_input" LOC = "T12"; -NET "serial_output" LOC = "M10"; +NET "serial_input" LOC = "T12" | IOSTANDARD = "LVCMOS33"; +NET "serial_output" LOC = "M10" | IOSTANDARD = "LVCMOS33"; diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v index 801a9aa..6162ec1 100644 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v +++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v @@ -40,6 +40,9 @@ module main( wire [5:0] lcd_data_in_address; wire [7:0] lcd_data_in_data; wire lcd_data_in_enable; + + wire [7:0] led_segment_bus; + wire [3:0] led_digit_select; //------------------------------------------------------------------------------------------------------- // @@ -69,9 +72,9 @@ module main( // // Inputs: // .clk: 50MHz clock - // .4_bit_input 4-bit input to the user program from the remote access module - // .8_bit_input 8-bit input to the user program from the remote access module - // .16_bit_input 16-bit input to the user program from the remote access module + // .four_bit_input 4-bit input to the user program from the remote access module + // .eight_bit_input 8-bit input to the user program from the remote access module + // .sixteen_bit_input 16-bit input to the user program from the remote access module // .serial_port_receiver Input from the serial port's RxD (receive data) pin // .remote_access_input_enable Toggle remote access input vs. local input mode // .local_input Local input to the remote program @@ -90,9 +93,9 @@ module main( // .led_digit_select Connect directly to the 4 bits enabling the LED display digits // // Outputs: - // .4_bit_output 4-bit output from the user program to the remote access module - // .8_bit_output 8-bit output from the user program to the remote access module - // .16_bit_output 16-bit output from the user program to the remote access module + // .four_bit_output 4-bit output from the user program to the remote access module + // .eight_bit_output 8-bit output from the user program to the remote access module + // .sixteen_bit_output 16-bit output from the user program to the remote access module // .lcd_data_out Data output to the LCD // .lcd_rs_out RS signal output to the LCD // .lcd_rw_out RW signal output to the LCD @@ -131,7 +134,7 @@ module main( .lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable), .sram_wren_in(sram_wren_in), .sram_clock_in(sram_clock_in), .sram_data_in(sram_data_in), .sram_address_in(sram_address_in), .sram_data_out(sram_data_out), .sram_available(sram_available), .sram_processing_done(sram_processing_done), - .led_segment_bus(255), .led_digit_select(15)); + .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select)); assign remote_access_local_input[7:4] = 0; // Local inputs assign remote_access_local_input[3:0] = 0; // Local inputs @@ -153,7 +156,8 @@ module main( sample_demo sample_demo(.clk(clk_div_by_two), .four_bit_input(four_bit_input), .four_bit_output(four_bit_output), .eight_bit_input(eight_bit_input), .eight_bit_output(eight_bit_output), .sixteen_bit_input(sixteen_bit_input), .sixteen_bit_output(sixteen_bit_output), .lcd_data_in_address(lcd_data_in_address), - .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable)); + .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable), + .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select)); //------------------------------------------------------------------------------------------------------- // @@ -174,7 +178,7 @@ endmodule // //------------------------------------------------------------------------------------------------------- -module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable); +module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable, led_segment_bus, led_digit_select); input clk; input [3:0] four_bit_input; @@ -188,6 +192,9 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_ output reg [7:0] lcd_data_in_data; output reg lcd_data_in_enable; + output reg [7:0] led_segment_bus; + output reg [3:0] led_digit_select; + reg [7:0] lcd_sample_counter = 48; // Create a sample LCD display counter register reg [31:0] lcd_character_change_timer = 0; // Wait a certain number of cycles before loading a new character reg [5:0] lcd_current_character = 0; // The current character's address @@ -218,6 +225,54 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_ end end end + + // 7-segment LED display driver clock generator + reg sseg_clock; + reg [4:0] sseg_clock_counter; + + always @(posedge clk) begin + sseg_clock_counter = sseg_clock_counter + 1; + if (sseg_clock_counter > 16) begin + sseg_clock_counter = 0; + sseg_clock = ~sseg_clock; + end + end + + // 7-segment LED display driver + // led_segment_bus and led_digit_select are active low + // The bit sequence, MSB to LSB, is dp a b c d e f g + // Segment letters are taken from ug130.pdf page 15 + + // 0: 8'b10000001 + // 1: 8'b11001111 + // 2: 8'b10010010 + // 3: 8'b10000110 + reg [2:0] current_anode; + always @(posedge sseg_clock) begin + current_anode = current_anode + 1; + if (current_anode > 3) begin + current_anode = 0; + end + + case (current_anode) + 0: begin + led_digit_select = 4'b1110; + led_segment_bus = 8'b10000001; + end + 1: begin + led_digit_select = 4'b1101; + led_segment_bus = 8'b11001111; + end + 2: begin + led_digit_select = 4'b1011; + led_segment_bus = 8'b10010010; + end + 3: begin + led_digit_select = 4'b0111; + led_segment_bus = 8'b10000110; + end + endcase + end endmodule //-------------------------------------------------------------------------------------------------------