work on Qt GUI, still not working properly

This commit is contained in:
Jeff Wang 2019-04-04 00:33:42 -04:00
parent 8f39958679
commit fc6d8efc5f
17 changed files with 328 additions and 33 deletions

View File

@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 2.8) cmake_minimum_required(VERSION 2.8)
# 3rd party tools # 3rd party tools
find_package(Qt5 COMPONENTS Widgets Qml Quick REQUIRED) find_package(Qt5 COMPONENTS Widgets Qml Quick REQUIRED)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -fsanitize=address,undefined")
# Directory with source code # Directory with source code
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(qt_gui) add_subdirectory(qt_gui)

View File

@ -26,4 +26,5 @@ target_link_libraries(${PROJECT}
Qt5::Qml Qt5::Qml
Qt5::Quick Qt5::Quick
calc calc
decn
) )

23
qt_gui/calc_main.h Normal file
View File

@ -0,0 +1,23 @@
//header file for main.c for gui
#ifndef QT_GUI_CALC_MAIN_H
#define QT_GUI_CALC_MAIN_H
#include <QMutex>
extern const char KEY_MAP[20];
extern int8_t NewKeyBuf[4];
extern QMutex KeyMutex;
extern volatile uint8_t new_key_write_i;
extern volatile uint8_t new_key_read_i;
extern volatile uint8_t NewKeyEmpty;
extern uint8_t ExitCalcMain;
int calc_main(void);
#endif //include guard

View File

@ -1,12 +1,70 @@
#include <QDebug> #include <QDebug>
#include "calc_main.h"
#include "../src/lcd.h"
#include "calculator.h" #include "calculator.h"
Calculator::Calculator(QObject *parent) : Calculator::Calculator(QObject *parent) :
QObject(parent) QObject(parent),
m_lcdText("calculator initial text"),
m_timer(this)
{ {
NewKeyEmpty = 1;
qDebug() << "Starting calculator thread";
calc_thread.start();
qDebug() << "calculator thread started";
QObject::connect(&m_timer, &QTimer::timeout, this, &Calculator::updateLcd);
m_timer.start(50);
}
Calculator::~Calculator(){
ExitCalcMain = 1;
while (!calc_thread.isFinished()); //TODO: timeout
} }
void Calculator::buttonClicked(const QString& in) { void Calculator::buttonClicked(const QString& in) {
qDebug() << in; QStringList split = in.split(",");
int8_t row = split[0].toInt();
int8_t col = split[1].toInt();
//translate column from left indexed, to right indexed
static const int NUM_COLS = 4;
col = (NUM_COLS - 1) - col;
//get keycode
int8_t keycode = col + NUM_COLS*row;
// qDebug() << "keycode: " << keycode;
// qDebug() << " row: " << row << ", col: " << col;
//push keycode
KeyMutex.lock();
#define INCR_NEW_KEY_I(i) i = (i + 1) & 3
if (!NewKeyEmpty && (new_key_write_i == new_key_read_i)){
printf("ERROR: key fifo full\n");
KeyMutex.unlock();
return;
} }
NewKeyBuf[new_key_write_i] = keycode;
INCR_NEW_KEY_I(new_key_write_i);
NewKeyEmpty = 0;
KeyMutex.unlock();
}
void Calculator::updateLcd() {
QString tmp("lcd text:\n");
const char* lcd_buf = get_lcd_buf();
for (int i = 0; i < MAX_ROWS; i++){
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
tmp += lcd_buf[j + i*MAX_CHARS_PER_LINE];
}
tmp += '\n';
}
// qDebug() << "update lcd:" << tmp.toStdString().c_str();
setLcdText(tmp);
}
void CalcThread::run() {
calc_main();
}

View File

@ -2,19 +2,50 @@
#define QTGUI_CALCULATOR_H #define QTGUI_CALCULATOR_H
#include <QObject> #include <QObject>
#include <QThread>
#include <QString>
#include <QTimer>
#include <QMutex>
class Calculator : public QObject class CalcThread : public QThread
{ {
Q_OBJECT Q_OBJECT
public: protected:
explicit Calculator(QObject *parent = 0); void run() override;
public slots:
void buttonClicked(const QString& in);
}; };
class Calculator : public QObject
{
Q_OBJECT
Q_PROPERTY(QString lcdText READ lcdText WRITE setLcdText NOTIFY lcdTextChanged)
public:
explicit Calculator(QObject *parent = 0);
~Calculator();
inline QString lcdText(){return m_lcdText;}
inline void setLcdText(const QString &lcdText){m_lcdText = lcdText;}
signals:
void lcdTextChanged();
public slots:
void buttonClicked(const QString& in);
void updateLcd();
private:
CalcThread calc_thread;
QString m_lcdText;
QTimer m_timer;
};
#endif //include guard #endif //include guard

View File

@ -1,4 +1,5 @@
#include <QApplication> #include <QApplication>
#include <QObject>
#include <QQmlApplicationEngine> #include <QQmlApplicationEngine>
#include <QQmlContext> #include <QQmlContext>
#include "calculator.h" #include "calculator.h"
@ -6,6 +7,9 @@
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
qmlRegisterType<Calculator>("calculator.lcd", 1, 0, "CLcd");
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

View File

@ -1,6 +1,6 @@
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.0 import QtQuick.Controls 1.0
import Qt3D.Input 2.0 import calculator.lcd 1.0
ApplicationWindow ApplicationWindow
{ {
@ -14,14 +14,38 @@ ApplicationWindow
id: base; id: base;
spacing: 5; spacing: 5;
width: 4 * (100 + 5) width: 4 * (100 + 5)
height: 5 * (100 + 5) + 200 height: 5 * (100 + 5) + 200 + 30
//quit button
Rectangle{
width: 100
height: 25
color: "red"
Text {text: "Quit"}
MouseArea {
onClicked: Qt.quit()
anchors.fill: parent
}
}
//lcd text from C++
CLcd {
id: clcd
}
//LCD //LCD
Rectangle { Rectangle {
id: lcd; objectName: "lcd";
color: "gray" color: "lightgray"
width: 4 * (100 + 5) - 5 width: 4 * (100 + 5) - 5
height: 200 height: 200
Text {
objectName: "lcd_text";
text: clcd.lcdText
anchors.centerIn: parent
onTextChanged: clcd.lcdText = text
}
} }
//Keyboard //Keyboard
@ -29,8 +53,9 @@ ApplicationWindow
model: 5; model: 5;
//row //row
delegate: Row { delegate: Row {
id: key_row; id: key_row
spacing: 5; spacing: 5
objectName: index
//keys within row //keys within row
Repeater { Repeater {
model: 4; model: 4;
@ -38,14 +63,15 @@ ApplicationWindow
id: key_key; id: key_key;
width: 100; width: 100;
height: 100; height: 100;
color: "blue" color: "gray"
border { width: 1; color: "black" } border { width: 1; color: "black" }
Text { Text {
text: index text: index
anchors.centerIn: parent anchors.centerIn: parent
} }
MouseHandler { MouseArea {
onClicked: _calculator.buttonClicked(index) onClicked: _calculator.buttonClicked(parent.parent.objectName + "," + index)
anchors.fill: parent
} }
} }
} }

View File

@ -1,4 +1,10 @@
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${QtQml_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS} ${QtQml_DEFINITIONS} ${${Qt5Quick_DEFINITIONS}})
add_library(decn decn/decn.c) add_library(decn decn/decn.c)
add_library(calc main.c calc.c utils.c lcd_emulator.c key.c) add_library(calc qt_main.cpp calc.c utils.c lcd_emulator.c key.c)
target_link_libraries(calc Qt5::Widgets)
add_executable(keytest key.c)
target_compile_definitions(keytest PRIVATE KEY_TEST_APP=1)

View File

@ -10,6 +10,10 @@
#include <stdint.h> #include <stdint.h>
#include "decn/decn.h" #include "decn/decn.h"
#ifdef __cplusplus
extern "C" {
#endif
void process_cmd(char cmd); void process_cmd(char cmd);
void push_decn(const char* signif_str, int16_t exponent, uint8_t no_lift); void push_decn(const char* signif_str, int16_t exponent, uint8_t no_lift);
@ -19,4 +23,8 @@ void set_x(const char* signif_str, int16_t exponent);
__xdata dec80* get_x(void); __xdata dec80* get_x(void);
__xdata dec80* get_y(void); __xdata dec80* get_y(void);
#ifdef __cplusplus
}
#endif
#endif /* SRC_CALC_H_ */ #endif /* SRC_CALC_H_ */

View File

@ -10,6 +10,10 @@
#include <stdint.h> #include <stdint.h>
#include "../utils.h" #include "../utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEC80_NUM_LSU 9 #define DEC80_NUM_LSU 9
//allow full range, but reserve -16384 for special numbers //allow full range, but reserve -16384 for special numbers
@ -57,4 +61,8 @@ int8_t decn_to_str(char* buf, const dec80* x);
void decn_to_str_complete(char* buf, const dec80* x); void decn_to_str_complete(char* buf, const dec80* x);
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* SRC_DEC_DECN_H_ */ #endif /* SRC_DEC_DECN_H_ */

View File

@ -237,7 +237,7 @@ const uint8_t* DebugGetKeys(void){
#ifdef DESKTOP #ifdef KEY_TEST_APP
int main(void){ int main(void){
KeyInit(); KeyInit();

View File

@ -7,6 +7,11 @@
#ifndef SRC_KEY_H_ #ifndef SRC_KEY_H_
#define SRC_KEY_H_ #define SRC_KEY_H_
#ifdef __cplusplus
extern "C" {
#endif
//#define DEBUG_KEYS //#define DEBUG_KEYS
void KeyInit(void); void KeyInit(void);
@ -24,4 +29,8 @@ extern uint8_t Keys[TOTAL_ROWS]; //only bottom nibbles get set
extern int8_t NewKeyPressed; extern int8_t NewKeyPressed;
#ifdef __cplusplus
}
#endif
#endif /* SRC_KEY_H_ */ #endif /* SRC_KEY_H_ */

View File

@ -1,6 +1,9 @@
#ifndef LCD_H #ifndef LCD_H
#define LCD_H #define LCD_H
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_CHARS_PER_LINE 16 #define MAX_CHARS_PER_LINE 16
#define MAX_ROWS 2 #define MAX_ROWS 2
@ -18,5 +21,15 @@ void LCD_ClearToEnd(uint8_t curr_row);
#define CGRAM_EXP 0 #define CGRAM_EXP 0
#define CGRAM_EXP_NEG 1 #define CGRAM_EXP_NEG 1
#include "utils.h"
#ifdef DESKTOP
const char* get_lcd_buf(void);
void print_lcd(void);
#endif
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -6,26 +6,44 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <ctype.h>
#include "lcd.h" #include "lcd.h"
#define CR 13 // \r #define CR 13 // \r
#define TAB 9 // \n #define TAB 9 // \n
static int lcd_row, lcd_col; static uint8_t lcd_row, lcd_col;
static char lcd_buf[MAX_ROWS][MAX_CHARS_PER_LINE]; static char lcd_buf[MAX_ROWS][MAX_CHARS_PER_LINE];
void LCD_Open(void){ const char* get_lcd_buf(void){
return &lcd_buf[0][0];
}
void print_lcd(void){
printf("(row,col)=(%d,%d)\n", lcd_row, lcd_col);
printf("|---|---|---|---|\n");
for (int i = 0; i < MAX_ROWS; i++){
printf("|");
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
printf("%c", lcd_buf[i][j]);
}
printf("\n");
}
printf("|---|---|---|---|\n");
}
void LCD_Open(void){
LCD_Clear();
} }
void LCD_Clear(void){ void LCD_Clear(void){
lcd_row=0;
lcd_col=0;
for (int i = 0; i < MAX_ROWS; i++){ for (int i = 0; i < MAX_ROWS; i++){
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){ for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
lcd_buf[i][j] = 0; lcd_buf[i][j] = ' ';
} }
} }
lcd_row=0;
lcd_col=0;
} }
void LCD_GoTo(unsigned int row, unsigned int col){ void LCD_GoTo(unsigned int row, unsigned int col){
@ -53,6 +71,18 @@ void LCD_OutString(const char *string, uint8_t max_chars) {
} }
} }
static int is_valid_character(char letter){
if (isdigit(letter)){
return 1;
} else if(letter == CGRAM_EXP || letter == CGRAM_EXP_NEG){
return 1;
} else if(letter == '.' || letter == ' '){
return 1;
}
return 0;
}
short TERMIO_PutChar(unsigned char letter) { short TERMIO_PutChar(unsigned char letter) {
if (letter == CR || letter == '\n') { if (letter == CR || letter == '\n') {
LCD_Clear(); LCD_Clear();
@ -62,8 +92,14 @@ short TERMIO_PutChar(unsigned char letter) {
} else { } else {
to_row(0); to_row(0);
} }
} else if (is_valid_character(letter)) {
if (letter == CGRAM_EXP){
lcd_buf[lcd_row][lcd_col] = 'E';
} else if (letter == CGRAM_EXP_NEG) {
lcd_buf[lcd_row][lcd_col] = '-';
} else { } else {
lcd_buf[lcd_row][lcd_col] = letter; lcd_buf[lcd_row][lcd_col] = letter;
}
lcd_col++; lcd_col++;
if (lcd_col > MAX_CHARS_PER_LINE) { if (lcd_col > MAX_CHARS_PER_LINE) {
if (lcd_row == 0) { if (lcd_row == 0) {
@ -72,6 +108,9 @@ short TERMIO_PutChar(unsigned char letter) {
to_row(0); to_row(0);
} }
} }
} else {
printf("\nerror @%d,%d, invalid character %d\n",
lcd_row, lcd_col, letter);
} }
return 1; return 1;

View File

@ -8,7 +8,10 @@
#include "decn/decn.h" #include "decn/decn.h"
#include "calc.h" #include "calc.h"
#include "utils.h" #include "utils.h"
#ifndef DESKTOP #ifdef DESKTOP
#include <stdio.h>
#include <QMutex>
#else
#include "stc15.h" #include "stc15.h"
#endif #endif
@ -24,10 +27,15 @@ static const char KEY_MAP[20] = {
}; };
#ifdef DESKTOP
QMutex KeyMutex;
#endif
int8_t NewKeyBuf[4]; int8_t NewKeyBuf[4];
volatile uint8_t new_key_write_i; volatile uint8_t new_key_write_i;
volatile uint8_t new_key_read_i; volatile uint8_t new_key_read_i;
volatile uint8_t NewKeyEmpty; volatile uint8_t NewKeyEmpty;
#define INCR_NEW_KEY_I(i) i = (i + 1) & 3 #define INCR_NEW_KEY_I(i) i = (i + 1) & 3
volatile uint8_t SecCount; volatile uint8_t SecCount;
@ -44,7 +52,11 @@ void timer0_isr() SDCC_ISR(1,1)
if (NewKeyPressed != -1){ if (NewKeyPressed != -1){
if (!NewKeyEmpty && (new_key_write_i == new_key_read_i)){ if (!NewKeyEmpty && (new_key_write_i == new_key_read_i)){
//do not overwrite keymap currently being processed //do not overwrite keymap currently being processed
INCR_NEW_KEY_I(new_key_write_i); // INCR_NEW_KEY_I(new_key_write_i);
#ifdef DESKTOP
printf("ERROR: key fifo full\n");
#endif
return;
} }
NewKeyBuf[new_key_write_i] = NewKeyPressed; NewKeyBuf[new_key_write_i] = NewKeyPressed;
INCR_NEW_KEY_I(new_key_write_i); INCR_NEW_KEY_I(new_key_write_i);
@ -106,9 +118,21 @@ char Buf[DECN_BUF_SIZE];
__xdata char EntryBuf[MAX_CHARS_PER_LINE + 1]; __xdata char EntryBuf[MAX_CHARS_PER_LINE + 1];
__xdata uint8_t ExpBuf[2]; __xdata uint8_t ExpBuf[2];
#ifdef DESKTOP
static void print_entry_bufs(void){
printf("EntryBuf:~%s~\n", EntryBuf);
printf("ExpBuf:%c%c\n", '0'+ExpBuf[1], '0'+ExpBuf[0]);
}
#endif
//#define DEBUG_UPTIME //#define DEBUG_UPTIME
/*********************************************/ /*********************************************/
#ifdef DESKTOP
uint8_t ExitCalcMain;
int calc_main()
#else
int main() int main()
#endif
{ {
enum { enum {
ENTERING_DONE, ENTERING_DONE,
@ -152,6 +176,11 @@ int main()
if (Keys[0] == 8 && Keys[4] == 8){ if (Keys[0] == 8 && Keys[4] == 8){
TURN_OFF(); TURN_OFF();
} }
#ifdef DESKTOP
if (ExitCalcMain){
return 0;
}
#endif
LCD_GoTo(0,0); LCD_GoTo(0,0);
#ifdef DEBUG_UPTIME #ifdef DEBUG_UPTIME
@ -200,12 +229,21 @@ int main()
///get new key ///get new key
#ifdef DESKTOP
KeyMutex.lock();
#endif
if (!NewKeyEmpty){ if (!NewKeyEmpty){
int8_t i_key = NewKeyBuf[new_key_read_i]; int8_t i_key = NewKeyBuf[new_key_read_i];
INCR_NEW_KEY_I(new_key_read_i); INCR_NEW_KEY_I(new_key_read_i);
if (new_key_read_i == new_key_write_i){ if (new_key_read_i == new_key_write_i){
NewKeyEmpty = 1; NewKeyEmpty = 1;
} }
#ifdef DESKTOP
KeyMutex.unlock();
printf("\nprocessing key %c (r=%d, w=%d, e=%d)\n",
KEY_MAP[i_key], new_key_read_i, new_key_write_i, NewKeyEmpty);
printf("entry_i=%d,exp_i=%d\n", entry_i, exp_i);
#endif
#ifdef DEBUG_KEYS #ifdef DEBUG_KEYS
LCD_GoTo(1,j); LCD_GoTo(1,j);
TERMIO_PutChar(KEY_MAP[i_key]); TERMIO_PutChar(KEY_MAP[i_key]);
@ -367,10 +405,21 @@ int main()
default: process_cmd(KEY_MAP[i_key]); default: process_cmd(KEY_MAP[i_key]);
////////// //////////
} //switch(KEY_MAP[i_key]) } //switch(KEY_MAP[i_key])
} //if found new key pressed } else { //else for (if found new key pressed)
//no new key pressed
#ifdef DESKTOP
KeyMutex.unlock();
#endif
continue;
}
//print X //print X
LCD_ClearToEnd(0); //go to 2nd row LCD_ClearToEnd(0); //go to 2nd row
#ifdef DESKTOP
print_lcd();
printf("entry_i=%d,exp_i=%d\n", entry_i, exp_i);
print_entry_bufs();
#endif
if (entering_exp == ENTERING_DONE){ if (entering_exp == ENTERING_DONE){
disp_exponent = decn_to_str(Buf, get_x()); disp_exponent = decn_to_str(Buf, get_x());
if (disp_exponent == 0){ if (disp_exponent == 0){
@ -419,6 +468,11 @@ int main()
TERMIO_PutChar(ExpBuf[0] + '0'); TERMIO_PutChar(ExpBuf[0] + '0');
} }
LCD_ClearToEnd(1); LCD_ClearToEnd(1);
#ifdef DESKTOP
print_lcd();
printf("entry_i=%d,exp_i=%d\n", entry_i, exp_i);
print_entry_bufs();
#endif
//turn backlight back on //turn backlight back on
BACKLIGHT_ON(); BACKLIGHT_ON();
} //while (1) } //while (1)

3
src/qt_main.cpp Normal file
View File

@ -0,0 +1,3 @@
// dummy .cpp file, so that this is c++
#include "main.c"

View File

@ -9,6 +9,10 @@
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void _delay_ms(uint8_t ms); void _delay_ms(uint8_t ms);
#define ACCURATE_DELAY_US #define ACCURATE_DELAY_US
@ -44,5 +48,10 @@ char* u32str(uint32_t x, char* buf, uint8_t base);
#define TURN_OFF() P3_2 = 0 #define TURN_OFF() P3_2 = 0
#endif #endif
#ifdef __cplusplus
}
#endif
#endif /* SRC_UTILS_H_ */ #endif /* SRC_UTILS_H_ */