Fix 7-segment LED display and add sample driver for the same

master
Timothy Pearson 11 years ago
parent e9bed7d3af
commit 7997af3f4f

@ -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

@ -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<nErases; j++ ) {
if ( segs[i] == updates[j][1] ) { // Same segment ?
// FIXME
// Always redraw segments for now, as dragging windows in front of the LED display currently erases the occluded portion(s) of the display!
#if 0
updates[j][0] = leaveAlone; // yes, already on screen
break;
#endif
}
}
if ( j == nErases ) { // If not already on screen
@ -584,8 +587,8 @@ K_EXPORT_COMPONENT_FACTORY(libremotelab_fpgaviewer, RemoteLab::Factory)
FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&)
: RemoteInstrumentPart( parent, name ), m_base(NULL), m_interfaceMode(BasicInterfaceMode),
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(0xffffffff),
m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff),
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_inputImageViewer(NULL), m_outputImageViewer(NULL)
{

@ -105,7 +105,7 @@ class TQ_EXPORT FPGA7Segment : public TQFrame
SegmentStyle segmentStyle() const;
virtual void setSegmentStyle(SegmentStyle);
void setLitSegments(unsigned int);
void setLitSegments(unsigned char);
TQSize sizeHint() const;
@ -120,6 +120,7 @@ class TQ_EXPORT FPGA7Segment : public TQFrame
char* m_prevSegments;
char* m_currentSegments;
unsigned int prevSegments;
double val;
uint smallPoint : 1;
uint fill : 1;
@ -231,10 +232,10 @@ namespace RemoteLab
unsigned int m_16bitInputValue;
unsigned int m_16bitOutputValue;
TQCString m_LCDOutputValue;
unsigned int m_7segDigit3OutputValue;
unsigned int m_7segDigit2OutputValue;
unsigned int m_7segDigit1OutputValue;
unsigned int m_7segDigit0OutputValue;
unsigned char m_7segDigit3OutputValue;
unsigned char m_7segDigit2OutputValue;
unsigned char m_7segDigit1OutputValue;
unsigned char m_7segDigit0OutputValue;
UnsignedIntegerList m_batchInputValueList;
UnsignedIntegerList m_batchOutputValueList;

@ -43,7 +43,13 @@ module remote_access(
output sram_available,
input sram_processing_done,
input [7:0] led_segment_bus,
input [3:0] led_digit_select);
input [3:0] led_digit_select,
// For use on Digilent Spartan 3E or compatible board only
output [3:0] remote_access_lcd_data_out,
output remote_access_lcd_rs_out,
output remote_access_lcd_rw_out,
output remote_access_lcd_enable_out);
reg [7:0] remote_access_4_bit_input_reg;
reg [7:0] remote_access_8_bit_input_reg;
@ -57,7 +63,7 @@ module remote_access(
reg sram_available_reg;
reg startup_needed = 1;
assign remote_access_4_bit_input = remote_access_4_bit_input_reg;
assign remote_access_4_bit_input = remote_access_4_bit_input_reg[3:0];
assign remote_access_8_bit_input = remote_access_8_bit_input_reg;
assign remote_access_16_bit_input = remote_access_16_bit_input_reg;
assign remote_access_lcd_data_out = remote_access_lcd_data_out_reg;
@ -77,6 +83,7 @@ module remote_access(
reg four_mhz_clk;
reg clk_div_by_two;
reg clk_div_by_two_oneeighty;
reg clk_div_by_four;
reg clk_div_by_eight;
reg [3:0] fifty_clock_divider = 0;
@ -92,8 +99,12 @@ module remote_access(
always @(posedge main_fifty_clock) begin
clk_div_by_two = !clk_div_by_two;
end
always @(negedge main_fifty_clock) begin
clk_div_by_two_oneeighty = !clk_div_by_two_oneeighty;
end
always @(posedge clk_div_by_two) begin
always @(posedge clk_div_by_two_oneeighty) begin
clk_div_by_four = !clk_div_by_four;
end
@ -108,45 +119,63 @@ module remote_access(
//-----------------------------------------------------------------------------------
reg [7:0] led_display_bytes [3:0];
reg [4:0] digit_blanker_1 = 0;
reg [4:0] digit_blanker_2 = 0;
reg [4:0] digit_blanker_3 = 0;
reg [4:0] digit_blanker_4 = 0;
reg [5:0] digit_blanker_1 = 0;
reg [5:0] digit_blanker_2 = 0;
reg [5:0] digit_blanker_3 = 0;
reg [5:0] digit_blanker_4 = 0;
reg [7:0] led_segment_bus_latch;
reg [3:0] led_digit_select_latch;
always @(negedge clk_div_by_eight) begin
if (led_digit_select[0] == 0) begin
led_display_bytes[0] = led_segment_bus;
led_segment_bus_latch = led_segment_bus;
led_digit_select_latch = led_digit_select;
if (led_digit_select_latch[0] == 0) begin
led_display_bytes[0] = led_segment_bus_latch;
digit_blanker_1 = 0;
digit_blanker_2 = digit_blanker_2 + 1;
digit_blanker_3 = digit_blanker_3 + 1;
digit_blanker_4 = digit_blanker_4 + 1;
end
if (led_digit_select[1] == 0) begin
led_display_bytes[1] = led_segment_bus;
if (led_digit_select_latch[1] == 0) begin
led_display_bytes[1] = led_segment_bus_latch;
digit_blanker_1 = digit_blanker_1 + 1;
digit_blanker_2 = 0;
digit_blanker_3 = digit_blanker_3 + 1;
digit_blanker_4 = digit_blanker_4 + 1;
end
if (led_digit_select[2] == 0) begin
led_display_bytes[2] = led_segment_bus;
if (led_digit_select_latch[2] == 0) begin
led_display_bytes[2] = led_segment_bus_latch;
digit_blanker_1 = digit_blanker_1 + 1;
digit_blanker_2 = digit_blanker_2 + 1;
digit_blanker_3 = 0;
digit_blanker_4 = digit_blanker_4 + 1;
end
if (led_digit_select[3] == 0) begin
led_display_bytes[3] = led_segment_bus;
if (led_digit_select_latch[3] == 0) begin
led_display_bytes[3] = led_segment_bus_latch;
digit_blanker_1 = digit_blanker_1 + 1;
digit_blanker_2 = digit_blanker_2 + 1;
digit_blanker_3 = digit_blanker_3 + 1;
digit_blanker_4 = 0;
end
if (digit_blanker_1 > 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;

@ -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";

@ -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
//-------------------------------------------------------------------------------------------------------

Loading…
Cancel
Save