Commit 412bd9fe authored by Pavel Pisa's avatar Pavel Pisa
Browse files

Simple Qt5 X GUI application to control knobs on through servos on MZ_APO kits.


Signed-off-by: Pavel Pisa's avatarPavel Pisa <pisa@cmp.felk.cvut.cz>
parents
TEMPLATE = subdirs
SUBDIRS += \
src
#include "servoknobswindow.h"
#include "peripheralsview.h"
#include "servocontrol.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ServoKnobsWindow w;
PeripheralsView *periph_view = new PeripheralsView();
ServoControl *servo_control = new ServoControl(periph_view);
w.connect(periph_view, SIGNAL(red_knob_changed(int)), servo_control, SLOT(red_knob_update(int)));
w.connect(periph_view, SIGNAL(green_knob_changed(int)), servo_control, SLOT(green_knob_update(int)));
w.connect(periph_view, SIGNAL(blue_knob_changed(int)), servo_control, SLOT(blue_knob_update(int)));
w.setCentralWidget(periph_view);
w.show();
return a.exec();
}
/*******************************************************************
Simple program to check LCD functionality on MicroZed
based MZ_APO board designed by Petr Porazil at PiKRON
mzapo_phys.h - mapping of the physical address to process
(C) Copyright 2017 by Pavel Pisa
e-mail: pisa@cmp.felk.cvut.cz
homepage: http://cmp.felk.cvut.cz/~pisa
company: http://www.pikron.com/
license: any combination of GPL, LGPL, MPL or BSD licenses
*******************************************************************/
#define _POSIX_C_SOURCE 200112L
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "mzapo_phys.h"
const char *map_phys_memdev="/dev/mem";
void *map_phys_address(off_t region_base, size_t region_size, int opt_cached)
{
unsigned long mem_window_size;
unsigned long pagesize;
unsigned char *mm;
unsigned char *mem;
int fd;
fd = open(map_phys_memdev, O_RDWR | (!opt_cached? O_SYNC: 0));
if (fd < 0) {
fprintf(stderr, "cannot open %s\n", map_phys_memdev);
return NULL;
}
pagesize=sysconf(_SC_PAGESIZE);
mem_window_size = ((region_base & (pagesize-1)) + region_size + pagesize-1) & ~(pagesize-1);
mm = (unsigned char *)mmap(NULL, mem_window_size, PROT_WRITE|PROT_READ,
MAP_SHARED, fd, region_base & ~(pagesize-1));
if (mm == MAP_FAILED) {
fprintf(stderr,"mmap error\n");
return NULL;
}
mem = mm + (region_base & (pagesize-1));
return (void *)mem;
}
/*******************************************************************
Simple program to check LCD functionality on MicroZed
based MZ_APO board designed by Petr Porazil at PiKRON
mzapo_phys.h - mapping of the physical address to process
(C) Copyright 2017 by Pavel Pisa
e-mail: pisa@cmp.felk.cvut.cz
homepage: http://cmp.felk.cvut.cz/~pisa
company: http://www.pikron.com/
license: any combination of GPL, LGPL, MPL or BSD licenses
*******************************************************************/
#ifndef MZAPO_PHYS_H
#define MZAPO_PHYS_H
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
void *map_phys_address(off_t region_base, size_t region_size, int opt_cached);
#ifdef __cplusplus
} /* extern "C"*/
#endif
#endif /*MZAPO_PHYS_H*/
/*******************************************************************
Simple program to check LCD functionality on MicroZed
based MZ_APO board designed by Petr Porazil at PiKRON
mzapo_regs.h - definition of the MZ_APO design registers
(C) Copyright 2017 by Pavel Pisa
e-mail: pisa@cmp.felk.cvut.cz
homepage: http://cmp.felk.cvut.cz/~pisa
company: http://www.pikron.com/
license: any combination of GPL, LGPL, MPL or BSD licenses
*******************************************************************/
#ifndef MZAPO_REGS_H
#define MZAPO_REGS_H
/*
Complete description of the educational MZ_APO design registers
can be found at
https://cw.fel.cvut.cz/wiki/courses/b35apo/documentation/mz_apo/start
The peripherals VHDL sources can be found in the repository
http://rtime.felk.cvut.cz/gitweb/fpga/zynq/canbench-sw.git/tree/refs/heads/microzed_apo:/system/ip
*/
/* SPI connected knobs and LEDs registers and keyboard */
#define SPILED_REG_BASE_PHYS 0x43c40000
#define SPILED_REG_SIZE 0x00004000
#define SPILED_REG_LED_LINE_o 0x004
#define SPILED_REG_LED_RGB1_o 0x010
#define SPILED_REG_LED_RGB2_o 0x014
#define SPILED_REG_LED_KBDWR_DIRECT_o 0x018
#define SPILED_REG_KBDRD_KNOBS_DIRECT_o 0x020
#define SPILED_REG_KNOBS_8BIT_o 0x024
/* Parallel LCD registers */
#define PARLCD_REG_BASE_PHYS 0x43c00000
#define PARLCD_REG_SIZE 0x00004000
#define PARLCD_REG_CR_o 0x0000
#define PARLCD_REG_CR_RESET_m 0x00000002
#define PARLCD_REG_CMD_o 0x0008
#define PARLCD_REG_DATA_o 0x000C
/* RC model servos and optional PS2 peripheral */
#define SERVOPS2_REG_BASE_PHYS 0x43c50000
#define SERVOPS2_REG_SIZE 0x4000
#define SERVOPS2_REG_CR_o 0x0000
#define SERVOPS2_REG_PWMPER_o 0x000C
#define SERVOPS2_REG_PWM1_o 0x0010
#define SERVOPS2_REG_PWM2_o 0x0014
#define SERVOPS2_REG_PWM3_o 0x0018
#define SERVOPS2_REG_PWM4_o 0x001C
/* Simple audio PWM output */
#define AUDIOPWM_REG_BASE_PHYS 0x43c60000
#define AUDIOPWM_REG_SIZE 0x4000
#define AUDIOPWM_REG_CR_o 0x0000
#define AUDIOPWM_REG_PWMPER_o 0x0008
#define AUDIOPWM_REG_PWM_o 0x000C
/* Optional DC Motor Simple Driver Peripherals for PSR Subject */
#define DCSPDRV_REG_BASE_PHYS_0 0x43c20000
#define DCSPDRV_REG_BASE_PHYS_1 0x43c30000
#define DCSPDRV_REG_SIZE 0x4000
#define DCSPDRV_REG_CR_o 0x0000
#define DCSPDRV_REG_CR_PWM_A_DIRECT_m 0x00000010
#define DCSPDRV_REG_CR_PWM_B_DIRECT_m 0x00000020
#define DCSPDRV_REG_CR_PWM_ENABLE_m 0x00000040
#define DCSPDRV_REG_CR_IRC_RESET_m 0x00000100
#define DCSPDRV_REG_SR_o 0x0004
#define DCSPDRV_REG_SR_IRC_A_MON_m 0x00000100
#define DCSPDRV_REG_SR_IRC_B_MON_m 0x00000200
#define DCSPDRV_REG_SR_IRC_IRQ_MON_m 0x00000400
#define DCSPDRV_REG_PERIOD_o 0x0008
#define DCSPDRV_REG_PERIOD_MASK_m 0x3fffffff
#define DCSPDRV_REG_DUTY_o 0x000C
#define DCSPDRV_REG_DUTY_MASK_m 0x3fffffff
#define DCSPDRV_REG_DUTY_DIR_A_m 0x40000000
#define DCSPDRV_REG_DUTY_DIR_B_m 0x80000000
#define DCSPDRV_REG_IRC_o 0x0010
#endif /*MZAPO_REGS_H*/
#include "peripheralsview.h"
#include "ui_peripheralsview.h"
PeripheralsView::PeripheralsView(QWidget *parent) :
QWidget(parent),
ui(new Ui::PeripheralsView)
{
ui->setupUi(this);
ui->dialRed->setStyleSheet("QDial { background-color: red }");
ui->dialGreen->setStyleSheet("QDial { background-color: green }");
ui->dialBlue->setStyleSheet("QDial { background-color: blue }");
connect(ui->dialRed, SIGNAL(valueChanged(int)), ui->spinRed, SLOT(setValue(int)));
connect(ui->dialGreen, SIGNAL(valueChanged(int)), ui->spinGreen, SLOT(setValue(int)));
connect(ui->dialBlue, SIGNAL(valueChanged(int)), ui->spinBlue, SLOT(setValue(int)));
connect(ui->spinRed, SIGNAL(valueChanged(int)), ui->dialRed, SLOT(setValue(int)));
connect(ui->spinGreen, SIGNAL(valueChanged(int)), ui->dialGreen, SLOT(setValue(int)));
connect(ui->spinBlue, SIGNAL(valueChanged(int)), ui->dialBlue, SLOT(setValue(int)));
connect(ui->spinRed, SIGNAL(valueChanged(int)), this, SIGNAL(red_knob_changed(int)));
connect(ui->spinGreen, SIGNAL(valueChanged(int)), this, SIGNAL(green_knob_changed(int)));
connect(ui->spinBlue, SIGNAL(valueChanged(int)), this, SIGNAL(blue_knob_changed(int)));
}
PeripheralsView::~PeripheralsView()
{
delete ui;
}
#if 0
void PeripheralsView::setup(const machine::PeripSpiLed *perip_spi_led) {
int val;
connect(ui->spinRed, SIGNAL(valueChanged(int)), perip_spi_led, SLOT(red_knob_update(int)));
connect(ui->spinGreen, SIGNAL(valueChanged(int)), perip_spi_led, SLOT(green_knob_update(int)));
connect(ui->spinBlue, SIGNAL(valueChanged(int)), perip_spi_led, SLOT(blue_knob_update(int)));
val = ui->spinRed->value();
ui->spinRed->setValue(val - 1);
ui->spinRed->setValue(val);
val = ui->spinGreen->value();
ui->spinGreen->setValue(val - 1);
ui->spinGreen->setValue(val);
val = ui->spinBlue->value();
ui->spinBlue->setValue(val - 1);
ui->spinBlue->setValue(val);
connect(ui->checkRed, SIGNAL(clicked(bool)), perip_spi_led, SLOT(red_knob_push(bool)));
connect(ui->checkGreen, SIGNAL(clicked(bool)), perip_spi_led, SLOT(green_knob_push(bool)));
connect(ui->checkBlue, SIGNAL(clicked(bool)), perip_spi_led, SLOT(blue_knob_push(bool)));
ui->checkRed->setChecked(false);
ui->checkGreen->setChecked(false);;
ui->checkBlue->setChecked(false);;
ui->labelRgb1->setAutoFillBackground(true);
ui->labelRgb2->setAutoFillBackground(true);
connect(perip_spi_led, SIGNAL(led_line_changed(uint)), this, SLOT(led_line_changed(uint)));
connect(perip_spi_led, SIGNAL(led_rgb1_changed(uint)), this, SLOT(led_rgb1_changed(uint)));
connect(perip_spi_led, SIGNAL(led_rgb2_changed(uint)), this, SLOT(led_rgb2_changed(uint)));
led_line_changed(0);
led_rgb1_changed(0);
led_rgb2_changed(0);
}
#endif
void PeripheralsView::led_line_changed(uint val) {
QString s, t;
s = QString::number(val, 16);
t.fill('0', 8 - s.count());
ui->lineEditHex->setText(t + s);
s = QString::number(val, 10);
ui->lineEditDec->setText(s);
s = QString::number(val, 2);
t.fill('0', 32 - s.count());
ui->lineEditBin->setText(t + s);
}
static void set_widget_background_color(QWidget *w, uint val) {
int r = (val >> 16) & 0xff;
int g = (val >> 8) & 0xff;
int b = (val >> 0) & 0xff;
QPalette::ColorRole brole = w->backgroundRole();
QPalette pal = w->palette();
pal.setColor(brole, QColor(r, g, b));
w->setPalette(pal);
}
void PeripheralsView::led_rgb1_changed(uint val) {
QString s, t;
s = QString::number(val, 16);
t.fill('0', 8 - s.count());
ui->lineEditRgb1->setText(t + s);
set_widget_background_color(ui->labelRgb1, val);
}
void PeripheralsView::led_rgb2_changed(uint val) {
QString s, t;
s = QString::number(val, 16);
t.fill('0', 8 - s.count());
ui->lineEditRgb2->setText(t + s);
set_widget_background_color(ui->labelRgb2, val);
}
#ifndef PERIPHERALSVIEW_H
#define PERIPHERALSVIEW_H
#include <QWidget>
#if 0
#include "peripspiled.h"
#endif
namespace Ui {
class PeripheralsView;
}
class PeripheralsView : public QWidget
{
Q_OBJECT
public:
explicit PeripheralsView(QWidget *parent = nullptr);
~PeripheralsView();
#if 0
void setup(const machine::PeripSpiLed *perip_spi_led);
#endif
signals:
void red_knob_changed(int val);
void green_knob_changed(int val);
void blue_knob_changed(int val);
public slots:
void led_line_changed(uint val);
void led_rgb1_changed(uint val);
void led_rgb2_changed(uint val);
private:
Ui::PeripheralsView *ui;
};
#endif // PERIPHERALSVIEW_H
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PeripheralsView</class>
<widget class="QWidget" name="PeripheralsView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>573</width>
<height>484</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetMaximumSize</enum>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>LED RGB 1</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelRgb1">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditRgb1">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>LED RGB 2</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelRgb2">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditRgb2">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkRed">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="dialRed">
<property name="maximum">
<number>255</number>
</property>
<property name="wrapping">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Red Knob</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinRed">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QCheckBox" name="checkGreen">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="dialGreen">
<property name="maximum">
<number>255</number>
</property>
<property name="wrapping">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Green Knob</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinGreen">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="maximum">
<number>255</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="checkBlue">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="dialBlue">
<property name="maximum">
<number>255</number>
</property>
<property name="wrapping">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Blue Knob</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>