start working on gui
This commit is contained in:
parent
5cea4807f7
commit
8f39958679
7
CMakeLists.txt
Normal file
7
CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
# 3rd party tools
|
||||
find_package(Qt5 COMPONENTS Widgets Qml Quick REQUIRED)
|
||||
# Directory with source code
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(qt_gui)
|
||||
|
@ -1,6 +1,6 @@
|
||||
# STC DIY Calculator Firmware
|
||||
|
||||
This is a replacement firmware for the [diyleyuan calculator](http://www.diyleyuan.com/jc/L8Q.html). The calculator uses an STC IAP15W413AS microcontroller (an 8051 instruction set-compatible microcontorller) with a built in serial bootloder. This project uses SDCC to compile the C code and [stcgal](https://github.com/grigorig/stcgal) to load the new firmware.
|
||||
This is a replacement firmware for the [diyleyuan calculator](http://www.diyleyuan.com/jc/L8Q.html). The calculator is available for purchase for less than $13 shipped from eBay by searching for "diy calculator kit". The calculator uses an STC IAP15W413AS microcontroller (an 8051 instruction set-compatible microcontorller) with a built in serial bootloder. This project uses SDCC to compile the C code and [stcgal](https://github.com/grigorig/stcgal) to load the new firmware.
|
||||
|
||||
![calculator](./calc.jpg)
|
||||
|
||||
@ -10,7 +10,8 @@ This is a replacement firmware for the [diyleyuan calculator](http://www.diyleyu
|
||||
- (you must already have SDCC installed and setup so it can be found in your PATH)
|
||||
- this will create a `main.hex` output file
|
||||
- there is also a prebuilt binary checked in at `binaries/main.hex`
|
||||
<!-- - CMakeLists.txt is for building the Qt desktop application. -->
|
||||
- CMakeLists.txt is for building the Qt desktop application.
|
||||
- (still a work in progress, currently doesn't do anything)
|
||||
|
||||
# Installing
|
||||
The STC microcontroller used has a bootloader permanently stored in ROM that allows downloading new firmware over a serial port. You can re-program it using a USB-to-logic-level-serial (5V) dongle, and the stcgal program. WARNING: a lot of USB-to-logic-level-serial dongles are for 3.3V logic levels. The diyleyuan calculator runs at 5V to make it easier to power/drive the LCD display. You have a couple of options:
|
||||
|
29
qt_gui/CMakeLists.txt
Normal file
29
qt_gui/CMakeLists.txt
Normal file
@ -0,0 +1,29 @@
|
||||
include_directories(${Qt5Widgets_INCLUDE_DIRS} ${QtQml_INCLUDE_DIRS})
|
||||
add_definitions(${Qt5Widgets_DEFINITIONS} ${QtQml_DEFINITIONS} ${${Qt5Quick_DEFINITIONS}})
|
||||
|
||||
qt5_add_resources(QT_RESOURCES main.qrc)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(PROJECT "RPN_Calculator")
|
||||
project(${PROJECT})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -std=c++11 -fstrict-aliasing -pedantic ")
|
||||
|
||||
if(NOT DEFINED HEADERS)
|
||||
file(GLOB HEADERS ${CMAKE_CURRENT_SOURCE_DIR}⁄*.h)
|
||||
endif()
|
||||
# if(NOT DEFINED SOURCES)
|
||||
# file(GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}⁄*.cpp)
|
||||
# endif()
|
||||
source_group("Header Files" FILES ${HEADERS})
|
||||
# source_group("Source Files" FILES ${SOURCES})
|
||||
set(SOURCES main.cpp calculator.cpp)
|
||||
add_executable(${PROJECT} ${HEADERS} ${SOURCES} ${QT_RESOURCES})
|
||||
target_link_libraries(${PROJECT}
|
||||
Qt5::Widgets
|
||||
Qt5::Qml
|
||||
Qt5::Quick
|
||||
calc
|
||||
)
|
12
qt_gui/calculator.cpp
Normal file
12
qt_gui/calculator.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "calculator.h"
|
||||
|
||||
Calculator::Calculator(QObject *parent) :
|
||||
QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void Calculator::buttonClicked(const QString& in) {
|
||||
qDebug() << in;
|
||||
}
|
20
qt_gui/calculator.h
Normal file
20
qt_gui/calculator.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef QTGUI_CALCULATOR_H
|
||||
#define QTGUI_CALCULATOR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class Calculator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Calculator(QObject *parent = 0);
|
||||
|
||||
public slots:
|
||||
void buttonClicked(const QString& in);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //include guard
|
16
qt_gui/main.cpp
Normal file
16
qt_gui/main.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include <QApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlContext>
|
||||
#include "calculator.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
QQmlApplicationEngine engine;
|
||||
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
|
||||
|
||||
Calculator calculator;
|
||||
engine.rootContext()->setContextProperty("_calculator", &calculator);
|
||||
|
||||
return app.exec();
|
||||
}
|
55
qt_gui/main.qml
Normal file
55
qt_gui/main.qml
Normal file
@ -0,0 +1,55 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.0
|
||||
import Qt3D.Input 2.0
|
||||
|
||||
ApplicationWindow
|
||||
{
|
||||
visible: true
|
||||
width: 1000
|
||||
height: 1000
|
||||
title: qsTr("RPN Calculator")
|
||||
|
||||
//calculator
|
||||
Column {
|
||||
id: base;
|
||||
spacing: 5;
|
||||
width: 4 * (100 + 5)
|
||||
height: 5 * (100 + 5) + 200
|
||||
|
||||
//LCD
|
||||
Rectangle {
|
||||
id: lcd;
|
||||
color: "gray"
|
||||
width: 4 * (100 + 5) - 5
|
||||
height: 200
|
||||
}
|
||||
|
||||
//Keyboard
|
||||
Repeater {
|
||||
model: 5;
|
||||
//row
|
||||
delegate: Row {
|
||||
id: key_row;
|
||||
spacing: 5;
|
||||
//keys within row
|
||||
Repeater {
|
||||
model: 4;
|
||||
delegate: Rectangle {
|
||||
id: key_key;
|
||||
width: 100;
|
||||
height: 100;
|
||||
color: "blue"
|
||||
border { width: 1; color: "black" }
|
||||
Text {
|
||||
text: index
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
MouseHandler {
|
||||
onClicked: _calculator.buttonClicked(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5
qt_gui/main.qrc
Normal file
5
qt_gui/main.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>main.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
4
src/CMakeLists.txt
Normal file
4
src/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
add_library(decn decn/decn.c)
|
||||
|
||||
add_library(calc main.c calc.c utils.c lcd_emulator.c key.c)
|
93
src/lcd_emulator.c
Normal file
93
src/lcd_emulator.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* lcd_emulator.c
|
||||
*
|
||||
* Created on: Apr 1, 2019
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "lcd.h"
|
||||
|
||||
#define CR 13 // \r
|
||||
#define TAB 9 // \n
|
||||
|
||||
static int lcd_row, lcd_col;
|
||||
static char lcd_buf[MAX_ROWS][MAX_CHARS_PER_LINE];
|
||||
|
||||
void LCD_Open(void){
|
||||
|
||||
}
|
||||
|
||||
void LCD_Clear(void){
|
||||
lcd_row=0;
|
||||
lcd_col=0;
|
||||
for (int i = 0; i < MAX_ROWS; i++){
|
||||
for (int j = 0; j < MAX_CHARS_PER_LINE; j++){
|
||||
lcd_buf[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LCD_GoTo(unsigned int row, unsigned int col){
|
||||
if (row < MAX_ROWS && col < MAX_CHARS_PER_LINE){
|
||||
lcd_row = row;
|
||||
lcd_col = col;
|
||||
} else {
|
||||
printf("LCD_GoTo(%u, %u) out of range\n", lcd_row, lcd_col);
|
||||
}
|
||||
}
|
||||
|
||||
static void to_row(unsigned char row_to){
|
||||
if (row_to == 0){
|
||||
lcd_row = 0;
|
||||
} else {
|
||||
lcd_row = 1;
|
||||
}
|
||||
lcd_col = 0;
|
||||
}
|
||||
|
||||
void LCD_OutString(const char *string, uint8_t max_chars) {
|
||||
const char *s;
|
||||
for (s = string; *s && max_chars > 0; s++, max_chars--) {
|
||||
TERMIO_PutChar(*s);
|
||||
}
|
||||
}
|
||||
|
||||
short TERMIO_PutChar(unsigned char letter) {
|
||||
if (letter == CR || letter == '\n') {
|
||||
LCD_Clear();
|
||||
} else if (letter == TAB || letter == '\t') {
|
||||
if (lcd_row == 0) {
|
||||
to_row(1);
|
||||
} else {
|
||||
to_row(0);
|
||||
}
|
||||
} else {
|
||||
lcd_buf[lcd_row][lcd_col] = letter;
|
||||
lcd_col++;
|
||||
if (lcd_col > MAX_CHARS_PER_LINE) {
|
||||
if (lcd_row == 0) {
|
||||
to_row(1);
|
||||
} else {
|
||||
to_row(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LCD_ClearToEnd(uint8_t curr_row){
|
||||
while (lcd_col != 0 && lcd_row == curr_row){
|
||||
TERMIO_PutChar(' ');
|
||||
}
|
||||
}
|
||||
|
||||
void LCD_OutNibble(uint8_t x){
|
||||
x &= 0xf; //ensure only bottom nibble
|
||||
if (x <= 9){
|
||||
TERMIO_PutChar(x + '0');
|
||||
} else {
|
||||
TERMIO_PutChar(x - 10 + 'a');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user