#include "config.h"
#include <rust_types.h>
#include <keyboard.hpp>
#include <LiquidCrystal.h>
#include "lcd_font.h"
#include "mk61emu_core.h"
#include "mk61_mk52_cross_hal.h"
#define CUSTOM_CHARS 8
#define CUSTOM_CHAR_BUF_SIZE 8
const uint8_t customCharGlyphs_for_mk52[CUSTOM_CHARS][CUSTOM_CHAR_BUF_SIZE] = {
{0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, // #0
{0x0F, 0x1F, 0x1F, 0x17, 0x07, 0x07, 0x07, 0x07}, // #1
{0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}, // #2
{0x07, 0x0F, 0x1F, 0x1F, 0x1E, 0x1C, 0x18, 0x10}, // #3
{0x10, 0x18, 0x1C, 0x1E, 0x1F, 0x1F, 0x0F, 0x07}, // #4
{0x1F, 0x1F, 0x1F, 0, 0, 0, 0, 0}, // #5
{0, 0, 0, 0, 0, 0x1F, 0x1F, 0x1F}, // #6
{0x1F, 0x1F, 0x1F, 0, 0, 0, 0x1F, 0x1F} // #7
};
const uint8_t customCharGlyphs_for_mk61[CUSTOM_CHARS][CUSTOM_CHAR_BUF_SIZE] = {
{ 0x07, 0x0F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }, // 0
{ 0x07, 0x0F, 0x1F, 0x1F, 0x1F, 0x17, 0x07, 0x07 }, // 1
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }, // 2
{ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07 }, // 3
{ 0x03, 0x07, 0x0F, 0x1F, 0x1E, 0x1C, 0x18, 0x10 }, // 4
{ 0x10, 0x18, 0x1C, 0x1E, 0x1F, 0x0F, 0x07, 0x03 }, // 5
{ 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x1F, 0x1F }, // 6
{ 0x1F, 0x1F, 0x1F, 0x07, 0x07, 0x0F, 0x1E, 0x1C } // 7
};
uint8_t mk52_glyph_L1[16] = {0, 1, 1, ' ', 0, 3, ' ', 0, 5, ' ', 5, 0, ' ', 0, 7, 7};
uint8_t mk52_glyph_L2[16] = {0, 2, 2, ' ', 0, 4, ' ', 6, 0, ' ', 0, 6, ' ', 6, 6, 0};
uint8_t mk61_glyph_L1[16] = {0, 1, 1, ' ', 0, 4, ' ', 0, 6, ' ', 4, 2, ' ', 0, 6, 6};
uint8_t mk61_glyph_L2[16] = {2, 3, 3, ' ', 2, 5, ' ', 2, 7, ' ', ' ', 2, ' ', 6, 6, 7};
#ifdef CDU
LiquidCrystal lcd(PB9, PB8, PB5, PB4, PB3, PA15);
#else
LiquidCrystal lcd(PB9, PB8, PB5, PB4, PB3, PA15);
#endif
enum enum_core61_stage {START, NEXT};
struct TFieldLCD {
u8 x, y;
};
const TFieldLCD MNEMO_LCD = {.x=13, .y=0};
static class_keyboard keyboard;
static u32 exeq;
static enum_core61_stage core_stage;
#ifdef SERIAL_OUTPUT
const u8 CR = 0x0D;
static u8 input_from_serial[16];
static u8* recive_char;
#endif
//0123456789ABCD
static char display_text[14]; //-12345678 -12
void mk61_display_refresh(void) {
const bool changed = !MK61Emu_ReadIndicator(&display_text[0]);
if(changed) {
lcd.setCursor(0, 1); lcd.print(display_text);
#ifdef SERIAL_OUTPUT
Serial.println(display_text);
#endif
}
}
void debug_key_info(i32 keycode) {
const TMK61_cross_key cross_key = KeyPairs[keycode];
#ifdef SERIAL_OUTPUT
Serial.print(keycode);
Serial.print("H (");
Serial.print(cross_key.x);
Serial.write(',');
Serial.print(cross_key.y);
Serial.println(") key -> mk61s");
#endif
}
void /* __attribute__((optimize("O0"))) */ output_version(void){
#ifdef SERIAL_OUTPUT
Serial.print("MK52s ver. ");
Serial.print(__DATE__);
Serial.write('(');
Serial.print(__TIME__);
Serial.println(')');
#endif
}
void setup() {
#ifdef SERIAL_OUTPUT
Serial.begin(115200);
recive_char = (u8*)((u32)(&input_from_serial[0]) - 1);
#endif
output_version();
keyboard.Init();
memset(display_text, 0, sizeof(display_text));
for(int i=0; i < CUSTOM_CHARS; i++) {
lcd.createChar(i, (uint8_t*) &customCharGlyphs_for_mk61[i]);
}
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
for(int i=0; i<16; i++) {
lcd.write(mk61_glyph_L1[i]);
}
lcd.setCursor(0, 1);
for(int i=0; i<16; i++) {
lcd.write(mk61_glyph_L2[i]);
}
// Тест ожидания нажатия кнопки на клавиатуре
//lcd.setCursor(0,1); lcd.print(" wait key press ");
keyboard.get_key_wait();
//lcd.setCursor(0,1); lcd.print("key = "); lcd.print((u8) keycode, HEX); lcd.print(" ");
lcd.clear();
lcd.createChar(1, (uint8_t*) &P_ru);
lcd.createChar(2, (uint8_t*) &B_ru);
lcd.setCursor(0, 0);
lcd.print("MK61s");
// Запуск эмулятора MK61
core_stage = START;
MK61Emu_ON();
#ifdef SERIAL_OUTPUT
Serial.println("ON");
#endif
}
void loop_1() {
keyboard.process(millis());
const i32 keycode = keyboard.get_key(PRESS);
if(keycode >= 0) {
debug_key_info(keycode);
}
}
void key_press_handler(i32 keycode) {
const TMK61_cross_key cross_key = KeyPairs[keycode]; // трансляция кода клавиши в координаты клавиши mk61
debug_key_info(keycode);
keyboard.reset_scan_line();
lcd.setCursor(MNEMO_LCD.x, MNEMO_LCD.y); lcd.print(mnemo_code[keycode]);
MK61Emu_SetKeyPress(cross_key.x, cross_key.y); // передача нажатия в MK61s
}
inline void mk61_automate(void) {
/*
1. Взять кнопку, если она есть то:
1.1. преобразовать в x,y координату контака для МК61
1.2. DoKeyPrees(x,y)
1.3. DoStep();
2. exeq очистить
3. Флаг отображения сбросить - _SetDisplayed(0);
4. НАЧАЛО ЦИКЛА
5. _DoStep()
6. если exeq != 0, это "НЕ ПЕРВЫЕ ШАГИ В РЕЖИМЕ ПРОГРАММА" то:
6.1. (отображаем это)
6.2. проверяем в какой позиции запятая _GetComma() если она не в 11 позиции то ВЫХОД
7. иначе: если posComma позиция запятой равна 11 "ПЕРВЫЙ ШАГ В РЕЖИМЕ ПРОГРАММА" exeq = 1 то:
7.1. отобразим это
7.2. устанавливаем exeq = 1
8. иначе: "РЕЖИМ АВТО" проверяем флаг _GetDisplayed если он установлен обновляем отображение и ВЫХОД
9. в НАЧАЛО ЦИКЛА
*/
i32 keycode;
switch(core_stage) {
case START:
keycode = keyboard.get_key(PRESS);
if(keycode >= 0) {
key_press_handler(keycode);
MK61Emu_DoStep();
}
exeq = 0;
MK61Emu_SetDisplayed(0);
core_stage = NEXT;
break;
case NEXT:
MK61Emu_DoStep();
if(exeq != 0) {
#ifdef SERIAL_OUTPUT
Serial.println("mk61 next steps on PROGRAMM");
#endif
mk61_display_refresh();
keycode = keyboard.get_key(PRESS);
if(keycode >= 0) key_press_handler(keycode);
if(MK61Emu_GetComma() != 11) { // Останов программы
#ifdef SERIAL_OUTPUT
Serial.println("mk61 STOP PROGRAMM");
#endif
core_stage = START;
}
} else if(MK61Emu_GetComma() == 11) {
#ifdef SERIAL_OUTPUT
Serial.println("mk61 first step on PROGRAMM");
#endif
exeq = 1;
} else {
if(MK61Emu_GetDisplayed() != 0) {
mk61_display_refresh();
core_stage = START;
}
}
}
}
void serial_input_handler(void) {
if(*recive_char == CR) {
recive_char[0] = 0;
Serial.println((char*) input_from_serial);
const u32 token = *(u32*) input_from_serial;
Serial.println(token, HEX);
if(token == 0x00726576) {
output_version();
}
recive_char = (u8*)((u32)(&input_from_serial[0]) - 1);
}
}
void loop() {
keyboard.next_scan_line();
mk61_automate();
#ifdef SERIAL_OUTPUT
serial_input_handler();
#endif
keyboard.check_scan_line();
}
#ifdef SERIAL_OUTPUT
void serialEvent() {
if(Serial.available() && *recive_char != CR) { // В UART что то свалилось и не выставлен флаг нуждается в обработке, принимаем
const u8 inChar = Serial.read(); // вычитываем один символ
*++recive_char = inChar;
}
}
#endif
Loading
stm32-bluepill
stm32-bluepill