Shorter paths to HAL, ExtUI (#17156)

This commit is contained in:
Scott Lahteine
2020-03-13 16:29:29 -05:00
committed by GitHub
parent ad980a72f7
commit 6bead0c1b0
600 changed files with 228 additions and 227 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,317 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/* DGUS implementation written by coldtobi in 2019 for Marlin */
#include "../../../../inc/MarlinConfigPre.h"
#include "../../../../MarlinCore.h"
#if HAS_BED_PROBE
#include "../../../../module/probe.h"
#endif
#include "DGUSVPVariable.h"
enum DGUSLCD_Screens : uint8_t;
#define DEBUG_OUT ENABLED(DEBUG_DGUSLCD)
#include "../../../../core/debug_out.h"
typedef enum : uint8_t {
DGUS_IDLE, //< waiting for DGUS_HEADER1.
DGUS_HEADER1_SEEN, //< DGUS_HEADER1 received
DGUS_HEADER2_SEEN, //< DGUS_HEADER2 received
DGUS_WAIT_TELEGRAM, //< LEN received, Waiting for to receive all bytes.
} rx_datagram_state_t;
// Low-Level access to the display.
class DGUSDisplay {
public:
DGUSDisplay() = default;
static void InitDisplay();
// Variable access.
static void WriteVariable(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false);
static void WriteVariablePGM(uint16_t adr, const void* values, uint8_t valueslen, bool isstr=false);
template<typename T>
static void WriteVariable(uint16_t adr, T value) {
WriteVariable(adr, static_cast<const void*>(&value), sizeof(T));
}
// Until now I did not need to actively read from the display. That's why there is no ReadVariable
// (I extensively use the auto upload of the display)
// Force display into another screen.
// (And trigger update of containing VPs)
// (to implement a pop up message, which may not be nested)
static void RequestScreen(DGUSLCD_Screens screen);
// Periodic tasks, eg. Rx-Queue handling.
static void loop();
public:
// Helper for users of this class to estimate if an interaction would be blocking.
static size_t GetFreeTxBuffer();
// Checks two things: Can we confirm the presence of the display and has we initiliazed it.
// (both boils down that the display answered to our chatting)
static inline bool isInitialized() { return Initialized; }
private:
static void WriteHeader(uint16_t adr, uint8_t cmd, uint8_t payloadlen);
static void WritePGM(const char str[], uint8_t len);
static void ProcessRx();
static rx_datagram_state_t rx_datagram_state;
static uint8_t rx_datagram_len;
static bool Initialized, no_reentrance;
};
extern DGUSDisplay dgusdisplay;
// compile-time x^y
constexpr float cpow(const float x, const int y) { return y == 0 ? 1.0 : x * cpow(x, y - 1); }
class DGUSScreenVariableHandler {
public:
DGUSScreenVariableHandler() = default;
static bool loop();
/// Send all 4 strings that are displayed on the infoscreen, confirmation screen and kill screen
/// The bools specifing whether the strings are in RAM or FLASH.
static void sendinfoscreen(const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool liinflash);
static void HandleUserConfirmationPopUp(uint16_t ConfirmVP, const char* line1, const char* line2, const char* line3, const char* line4, bool l1inflash, bool l2inflash, bool l3inflash, bool liinflash);
/// "M117" Message -- msg is a RAM ptr.
static void setstatusmessage(const char* msg);
/// The same for messages from Flash
static void setstatusmessagePGM(PGM_P const msg);
// Callback for VP "Display wants to change screen on idle printer"
static void ScreenChangeHookIfIdle(DGUS_VP_Variable &var, void *val_ptr);
// Callback for VP "Screen has been changed"
static void ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr);
// Callback for VP "All Heaters Off"
static void HandleAllHeatersOff(DGUS_VP_Variable &var, void *val_ptr);
// Hook for "Change this temperature"
static void HandleTemperatureChanged(DGUS_VP_Variable &var, void *val_ptr);
// Hook for "Change Flowrate"
static void HandleFlowRateChanged(DGUS_VP_Variable &var, void *val_ptr);
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
// Hook for manual move option
static void HandleManualMoveOption(DGUS_VP_Variable &var, void *val_ptr);
#endif
// Hook for manual move.
static void HandleManualMove(DGUS_VP_Variable &var, void *val_ptr);
// Hook for manual extrude.
static void HandleManualExtrude(DGUS_VP_Variable &var, void *val_ptr);
// Hook for motor lock and unlook
static void HandleMotorLockUnlock(DGUS_VP_Variable &var, void *val_ptr);
#if ENABLED(POWER_LOSS_RECOVERY)
// Hook for power loss recovery.
static void HandlePowerLossRecovery(DGUS_VP_Variable &var, void *val_ptr);
#endif
// Hook for settings
static void HandleSettings(DGUS_VP_Variable &var, void *val_ptr);
static void HandleStepPerMMChanged(DGUS_VP_Variable &var, void *val_ptr);
static void HandleStepPerMMExtruderChanged(DGUS_VP_Variable &var, void *val_ptr);
#if HAS_PID_HEATING
// Hook for "Change this temperature PID para"
static void HandleTemperaturePIDChanged(DGUS_VP_Variable &var, void *val_ptr);
// Hook for PID autotune
static void HandlePIDAutotune(DGUS_VP_Variable &var, void *val_ptr);
#endif
#if HAS_BED_PROBE
// Hook for "Change probe offset z"
static void HandleProbeOffsetZChanged(DGUS_VP_Variable &var, void *val_ptr);
#endif
#if ENABLED(BABYSTEPPING)
// Hook for live z adjust action
static void HandleLiveAdjustZ(DGUS_VP_Variable &var, void *val_ptr);
#endif
#if FAN_COUNT > 0
// Hook for fan control
static void HandleFanControl(DGUS_VP_Variable &var, void *val_ptr);
#endif
// Hook for heater control
static void HandleHeaterControl(DGUS_VP_Variable &var, void *val_ptr);
#if ENABLED(DGUS_PREHEAT_UI)
// Hook for preheat
static void HandlePreheat(DGUS_VP_Variable &var, void *val_ptr);
#endif
#if ENABLED(DGUS_FILAMENT_LOADUNLOAD)
// Hook for filament load and unload filament option
static void HandleFilamentOption(DGUS_VP_Variable &var, void *val_ptr);
// Hook for filament load and unload
static void HandleFilamentLoadUnload(DGUS_VP_Variable &var);
#endif
#if ENABLED(SDSUPPORT)
// Callback for VP "Display wants to change screen when there is a SD card"
static void ScreenChangeHookIfSD(DGUS_VP_Variable &var, void *val_ptr);
/// Scroll buttons on the file listing screen.
static void DGUSLCD_SD_ScrollFilelist(DGUS_VP_Variable &var, void *val_ptr);
/// File touched.
static void DGUSLCD_SD_FileSelected(DGUS_VP_Variable &var, void *val_ptr);
/// start print after confirmation received.
static void DGUSLCD_SD_StartPrint(DGUS_VP_Variable &var, void *val_ptr);
/// User hit the pause, resume or abort button.
static void DGUSLCD_SD_ResumePauseAbort(DGUS_VP_Variable &var, void *val_ptr);
/// User confirmed the abort action
static void DGUSLCD_SD_ReallyAbort(DGUS_VP_Variable &var, void *val_ptr);
/// User hit the tune button
static void DGUSLCD_SD_PrintTune(DGUS_VP_Variable &var, void *val_ptr);
/// Send a single filename to the display.
static void DGUSLCD_SD_SendFilename(DGUS_VP_Variable &var);
/// Marlin informed us that a new SD has been inserted.
static void SDCardInserted();
/// Marlin informed us that the SD Card has been removed().
static void SDCardRemoved();
/// Marlin informed us about a bad SD Card.
static void SDCardError();
#endif
// OK Button the Confirm screen.
static void ScreenConfirmedOK(DGUS_VP_Variable &var, void *val_ptr);
// Update data after went to new screen (by display or by GotoScreen)
// remember: store the last-displayed screen, so it can get returned to.
// (e.g for pop up messages)
static void UpdateNewScreen(DGUSLCD_Screens newscreen, bool popup=false);
// Recall the remembered screen.
static void PopToOldScreen();
// Make the display show the screen and update all VPs in it.
static void GotoScreen(DGUSLCD_Screens screen, bool ispopup = false);
static void UpdateScreenVPData();
// Helpers to convert and transfer data to the display.
static void DGUSLCD_SendWordValueToDisplay(DGUS_VP_Variable &var);
static void DGUSLCD_SendStringToDisplay(DGUS_VP_Variable &var);
static void DGUSLCD_SendStringToDisplayPGM(DGUS_VP_Variable &var);
static void DGUSLCD_SendTemperaturePID(DGUS_VP_Variable &var);
static void DGUSLCD_SendPercentageToDisplay(DGUS_VP_Variable &var);
static void DGUSLCD_SendPrintProgressToDisplay(DGUS_VP_Variable &var);
static void DGUSLCD_SendPrintTimeToDisplay(DGUS_VP_Variable &var);
#if ENABLED(PRINTCOUNTER)
static void DGUSLCD_SendPrintAccTimeToDisplay(DGUS_VP_Variable &var);
static void DGUSLCD_SendPrintsTotalToDisplay(DGUS_VP_Variable &var);
#endif
#if FAN_COUNT > 0
static void DGUSLCD_SendFanStatusToDisplay(DGUS_VP_Variable &var);
#endif
static void DGUSLCD_SendHeaterStatusToDisplay(DGUS_VP_Variable &var);
#if ENABLED(DGUS_UI_WAITING)
static void DGUSLCD_SendWaitingStatusToDisplay(DGUS_VP_Variable &var);
#endif
/// Send a value from 0..100 to a variable with a range from 0..255
static void DGUSLCD_PercentageToUint8(DGUS_VP_Variable &var, void *val_ptr);
template<typename T>
static void DGUSLCD_SetValueDirectly(DGUS_VP_Variable &var, void *val_ptr) {
if (!var.memadr) return;
union { unsigned char tmp[sizeof(T)]; T t; } x;
unsigned char *ptr = (unsigned char*)val_ptr;
for (uint8_t i = 0; i < sizeof(T); i++) x.tmp[i] = ptr[sizeof(T) - i - 1];
*(T*)var.memadr = x.t;
}
/// Send a float value to the display.
/// Display will get a 4-byte integer scaled to the number of digits:
/// Tell the display the number of digits and it cheats by displaying a dot between...
template<unsigned int decimals>
static void DGUSLCD_SendFloatAsLongValueToDisplay(DGUS_VP_Variable &var) {
if (var.memadr) {
float f = *(float *)var.memadr;
f *= cpow(10, decimals);
union { long l; char lb[4]; } endian;
char tmp[4];
endian.l = f;
tmp[0] = endian.lb[3];
tmp[1] = endian.lb[2];
tmp[2] = endian.lb[1];
tmp[3] = endian.lb[0];
dgusdisplay.WriteVariable(var.VP, tmp, 4);
}
}
/// Send a float value to the display.
/// Display will get a 2-byte integer scaled to the number of digits:
/// Tell the display the number of digits and it cheats by displaying a dot between...
template<unsigned int decimals>
static void DGUSLCD_SendFloatAsIntValueToDisplay(DGUS_VP_Variable &var) {
if (var.memadr) {
float f = *(float *)var.memadr;
DEBUG_ECHOLNPAIR_F(" >> ", f, 6);
f *= cpow(10, decimals);
union { int16_t i; char lb[2]; } endian;
char tmp[2];
endian.i = f;
tmp[0] = endian.lb[1];
tmp[1] = endian.lb[0];
dgusdisplay.WriteVariable(var.VP, tmp, 2);
}
}
/// Force an update of all VP on the current screen.
static inline void ForceCompleteUpdate() { update_ptr = 0; ScreenComplete = false; }
/// Has all VPs sent to the screen
static inline bool IsScreenComplete() { return ScreenComplete; }
static inline DGUSLCD_Screens getCurrentScreen() { return current_screen; }
static inline void SetupConfirmAction( void (*f)()) { confirm_action_cb = f; }
private:
static DGUSLCD_Screens current_screen; ///< currently on screen
static constexpr uint8_t NUM_PAST_SCREENS = 4;
static DGUSLCD_Screens past_screens[NUM_PAST_SCREENS]; ///< LIFO with past screens for the "back" button.
static uint8_t update_ptr; ///< Last sent entry in the VPList for the actual screen.
static uint16_t skipVP; ///< When updating the screen data, skip this one, because the user is interacting with it.
static bool ScreenComplete; ///< All VPs sent to screen?
static uint16_t ConfirmVP; ///< context for confirm screen (VP that will be emulated-sent on "OK").
#if ENABLED(SDSUPPORT)
static int16_t top_file; ///< file on top of file chooser
static int16_t file_to_print; ///< touched file to be confirmed
#endif
static void (*confirm_action_cb)();
};
extern DGUSScreenVariableHandler ScreenHandler;
/// Find the flash address of a DGUS_VP_Variable for the VP.
extern const DGUS_VP_Variable* DGUSLCD_FindVPVar(const uint16_t vp);
/// Helper to populate a DGUS_VP_Variable for a given VP. Return false if not found.
extern bool populate_VPVar(const uint16_t VP, DGUS_VP_Variable * const ramcopy);

View File

@ -0,0 +1,50 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/* DGUS implementation written by coldtobi in 2019 for Marlin */
#include "DGUSVPVariable.h"
// This file defines the interaction between Marlin and the display firmware.
// information on which screen which VP is displayed
// As this is a sparse table, two arrays are needed:
// one to list the VPs of one screen and one to map screens to the lists.
// (Strictly this would not be necessary, but allows to only send data the display needs and reducing load on Marlin)
struct VPMapping {
const uint8_t screen;
const uint16_t *VPList; // The list is null-terminated.
};
extern const struct VPMapping VPMap[];
// List of VPs handled by Marlin / The Display.
extern const struct DGUS_VP_Variable ListOfVP[];
#if ENABLED(DGUS_LCD_UI_ORIGIN)
#include "origin/DGUSDisplayDef.h"
#elif ENABLED(DGUS_LCD_UI_FYSETC)
#include "fysetc/DGUSDisplayDef.h"
#elif ENABLED(DGUS_LCD_UI_HIPRECY)
#include "hiprecy/DGUSDisplayDef.h"
#endif

View File

@ -0,0 +1,47 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* DGUSVPVariable.h
*
* Created on: Feb 9, 2019
* Author: tobi
*/
struct DGUS_VP_Variable {
uint16_t VP;
void* memadr; // If nullptr, the value cannot be uploaded to the display.
uint8_t size;
// Callback that will be called if the display modified the value.
// nullptr makes it readonly for the display.
void (*set_by_display_handler)(DGUS_VP_Variable &var, void *val_ptr);
void (*send_to_display_handler)(DGUS_VP_Variable &var);
template<typename T>
DGUS_VP_Variable& operator =(T &o) {
*(T*)memadr = o; // warning this is not typesafe.
// TODO: Call out the display or mark as dirty for the next update.
return *this;
}
};

View File

@ -0,0 +1,483 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* DGUS VPs changed by George Fu in 2019 for Marlin */
#include "../../../../../inc/MarlinConfigPre.h"
#if ENABLED(DGUS_LCD_UI_FYSETC)
#include "../DGUSDisplayDef.h"
#include "../DGUSDisplay.h"
#include "../../../../../module/temperature.h"
#include "../../../../../module/motion.h"
#include "../../../../../module/planner.h"
#include "../../../ui_api.h"
#include "../../../../ultralcd.h"
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
uint16_t distanceToMove = 0.1;
#endif
const uint16_t VPList_Boot[] PROGMEM = {
VP_MARLIN_VERSION,
0x0000
};
const uint16_t VPList_Main[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded. */
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set, VP_E0_STATUS,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set, VP_BED_STATUS,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage, VP_FAN0_STATUS,
#endif
VP_XPos, VP_YPos, VP_ZPos,
VP_Fan0_Percentage,
VP_Feedrate_Percentage,
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
VP_PrintProgress_Percentage,
#endif
0x0000
};
const uint16_t VPList_Temp[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_Status[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#endif
VP_XPos, VP_YPos, VP_ZPos,
VP_Fan0_Percentage,
VP_Feedrate_Percentage,
VP_PrintProgress_Percentage,
0x0000
};
const uint16_t VPList_Status2[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_Flowrate_E0,
#endif
#if HOTENDS >= 2
VP_Flowrate_E1,
#endif
VP_PrintProgress_Percentage,
VP_PrintTime,
0x0000
};
const uint16_t VPList_Preheat[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_ManualMove[] PROGMEM = {
VP_XPos, VP_YPos, VP_ZPos,
0x0000
};
const uint16_t VPList_ManualExtrude[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
VP_EPos,
0x0000
};
const uint16_t VPList_FanAndFeedrate[] PROGMEM = {
VP_Feedrate_Percentage, VP_Fan0_Percentage,
0x0000
};
const uint16_t VPList_SD_FlowRates[] PROGMEM = {
VP_Flowrate_E0, VP_Flowrate_E1,
0x0000
};
const uint16_t VPList_Filament_heating[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
VP_E0_FILAMENT_LOAD_UNLOAD,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
VP_E1_FILAMENT_LOAD_UNLOAD,
#endif
0x0000
};
const uint16_t VPList_Filament_load_unload[] PROGMEM = {
#if HOTENDS >= 1
VP_E0_FILAMENT_LOAD_UNLOAD,
#endif
#if HOTENDS >= 2
VP_E1_FILAMENT_LOAD_UNLOAD,
#endif
0x0000
};
const uint16_t VPList_SDFileList[] PROGMEM = {
VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4,
0x0000
};
const uint16_t VPList_SD_PrintManipulation[] PROGMEM = {
VP_PrintProgress_Percentage, VP_PrintTime,
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#if FAN_COUNT > 1
VP_Fan1_Percentage,
#endif
#endif
VP_Flowrate_E0,
0x0000
};
const uint16_t VPList_SDPrintTune[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set, VP_Flowrate_E0,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set, VP_Flowrate_E1,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
VP_Feedrate_Percentage,
VP_SD_Print_ProbeOffsetZ,
0x0000
};
const uint16_t VPList_StepPerMM[] PROGMEM = {
VP_X_STEP_PER_MM,
VP_Y_STEP_PER_MM,
VP_Z_STEP_PER_MM,
#if HOTENDS >= 1
VP_E0_STEP_PER_MM,
#endif
#if HOTENDS >= 2
VP_E1_STEP_PER_MM,
#endif
0x0000
};
const uint16_t VPList_PIDE0[] PROGMEM = {
#if ENABLED(PIDTEMP)
VP_E0_PID_P,
VP_E0_PID_I,
VP_E0_PID_D,
#endif
0x0000
};
const uint16_t VPList_PIDBED[] PROGMEM = {
#if ENABLED(PIDTEMP)
VP_BED_PID_P,
VP_BED_PID_I,
VP_BED_PID_D,
#endif
0x0000
};
const uint16_t VPList_Infos[] PROGMEM = {
VP_MARLIN_VERSION,
VP_PrintTime,
#if ENABLED(PRINTCOUNTER)
VP_PrintAccTime,
VP_PrintsTotal,
#endif
0x0000
};
const uint16_t VPList_PIDTuningWaiting[] PROGMEM = {
VP_WAITING_STATUS,
0x0000
};
const uint16_t VPList_FLCPreheat[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_FLCPrinting[] PROGMEM = {
#if HOTENDS >= 1
VP_SD_Print_ProbeOffsetZ,
#endif
0x0000
};
const uint16_t VPList_Z_Offset[] PROGMEM = {
#if HOTENDS >= 1
VP_SD_Print_ProbeOffsetZ,
#endif
0x0000
};
const struct VPMapping VPMap[] PROGMEM = {
{ DGUSLCD_SCREEN_BOOT, VPList_Boot },
{ DGUSLCD_SCREEN_MAIN, VPList_Main },
{ DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp },
{ DGUSLCD_SCREEN_STATUS, VPList_Status },
{ DGUSLCD_SCREEN_STATUS2, VPList_Status2 },
{ DGUSLCD_SCREEN_PREHEAT, VPList_Preheat },
{ DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove },
{ DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude },
{ DGUSLCD_SCREEN_FILAMENT_HEATING, VPList_Filament_heating },
{ DGUSLCD_SCREEN_FILAMENT_LOADING, VPList_Filament_load_unload },
{ DGUSLCD_SCREEN_FILAMENT_UNLOADING, VPList_Filament_load_unload },
{ DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation },
{ DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList },
{ DGUSLCD_SCREEN_SDPRINTTUNE, VPList_SDPrintTune },
{ DGUSLCD_SCREEN_WAITING, VPList_PIDTuningWaiting },
{ DGUSLCD_SCREEN_FLC_PREHEAT, VPList_FLCPreheat },
{ DGUSLCD_SCREEN_FLC_PRINTING, VPList_FLCPrinting },
{ DGUSLCD_SCREEN_Z_OFFSET, VPList_Z_Offset },
{ DGUSLCD_SCREEN_STEPPERMM, VPList_StepPerMM },
{ DGUSLCD_SCREEN_PID_E, VPList_PIDE0 },
{ DGUSLCD_SCREEN_PID_BED, VPList_PIDBED },
{ DGUSLCD_SCREEN_INFOS, VPList_Infos },
{ 0 , nullptr } // List is terminated with an nullptr as table entry.
};
const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION;
// Helper to define a DGUS_VP_Variable for common use cases.
#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string)
#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
// Helper to detect touch events
VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr),
VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr),
VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr),
VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr),
VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr),
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr),
#endif
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#else
VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#endif
VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr),
#if ENABLED(POWER_LOSS_RECOVERY)
VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr),
#endif
VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr),
#if ENABLED(SINGLE_Z_CALIBRATION)
VPHELPER(VP_Z_CALIBRATE, nullptr, &DGUSScreenVariableHandler::HandleZCalibration, nullptr),
#endif
#if ENABLED(FIRST_LAYER_CAL)
VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &DGUSScreenVariableHandler::HandleFirstLayerCal, nullptr),
#endif
{ .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
// M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr
{ .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay },
// Temperature Data
#if HOTENDS >= 1
VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E0, &planner.flow_percentage[ExtUI::extruder_t::E0], DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(DGUS_PREHEAT_UI)
VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr),
#endif
#if ENABLED(PIDTEMP)
VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#if ENABLED(DGUS_FILAMENT_LOADUNLOAD)
VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload),
#endif
#endif
#if HOTENDS >= 2
VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E1, &planner.flow_percentage[ExtUI::extruder_t::E1], DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(PIDTEMP)
VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
VPHELPER(VP_E1_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload),
#endif
#if HAS_HEATED_BED
VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(PIDTEMPBED)
VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#endif
// Fan Data
#if FAN_COUNT
#define FAN_VPHELPER(N) \
VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \
VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \
VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay),
REPEAT(FAN_COUNT, FAN_VPHELPER)
#endif
// Feedrate
VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly<int16_t>, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ),
// Position Data
VPHELPER(VP_XPos, &current_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_YPos, &current_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_ZPos, &current_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
// Print Progress
VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintProgressToDisplay ),
// Print Time
VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay),
#if ENABLED(PRINTCOUNTER)
VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay),
VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay),
#endif
VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#if HOTENDS >= 1
VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
#if HOTENDS >= 2
VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
// SDCard File listing.
#if ENABLED(SDSUPPORT)
VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr),
VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr),
VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr),
VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename),
VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename),
VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename),
VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename),
VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename),
VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr),
VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr),
VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr),
#if HAS_BED_PROBE
VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>),
#if ENABLED(BABYSTEPPING)
VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr),
#endif
#endif
#endif
#if ENABLED(DGUS_UI_WAITING)
VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay),
#endif
// Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content.
{ .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
VPHELPER(0, 0, 0, 0) // must be last entry.
};
#endif // DGUS_LCD_UI_FYSETC

View File

@ -0,0 +1,291 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
enum DGUSLCD_Screens : uint8_t {
DGUSLCD_SCREEN_BOOT = 0,
DGUSLCD_SCREEN_MAIN = 1,
DGUSLCD_SCREEN_STATUS = 1,
DGUSLCD_SCREEN_STATUS2 = 1,
DGUSLCD_SCREEN_TEMPERATURE = 10,
DGUSLCD_SCREEN_PREHEAT = 18,
DGUSLCD_SCREEN_POWER_LOSS = 100,
DGUSLCD_SCREEN_MANUALMOVE = 192,
DGUSLCD_SCREEN_UTILITY = 120,
DGUSLCD_SCREEN_FILAMENT_HEATING = 146,
DGUSLCD_SCREEN_FILAMENT_LOADING = 148,
DGUSLCD_SCREEN_FILAMENT_UNLOADING = 158,
DGUSLCD_SCREEN_MANUALEXTRUDE = 160,
DGUSLCD_SCREEN_SDFILELIST = 71,
DGUSLCD_SCREEN_SDPRINTMANIPULATION = 73,
DGUSLCD_SCREEN_SDPRINTTUNE = 75,
DGUSLCD_SCREEN_FLC_PREHEAT = 94,
DGUSLCD_SCREEN_FLC_PRINTING = 96,
DGUSLCD_SCREEN_STEPPERMM = 212,
DGUSLCD_SCREEN_PID_E = 214,
DGUSLCD_SCREEN_PID_BED = 218,
DGUSLCD_SCREEN_Z_OFFSET = 222,
DGUSLCD_SCREEN_INFOS = 36,
DGUSLCD_SCREEN_CONFIRM = 240,
DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version")
DGUSLCD_SCREEN_WAITING = 251,
DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen"
DGUSLDC_SCREEN_UNUSED = 255
};
// Display Memory layout used (T5UID)
// Except system variables this is arbitrary, just to organize stuff....
// 0x0000 .. 0x0FFF -- System variables and reserved by the display
// 0x1000 .. 0x1FFF -- Variables to never change location, regardless of UI Version
// 0x2000 .. 0x2FFF -- Controls (VPs that will trigger some action)
// 0x3000 .. 0x4FFF -- Marlin Data to be displayed
// 0x5000 .. -- SPs (if we want to modify display elements, e.g change color or like) -- currently unused
// As there is plenty of space (at least most displays have >8k RAM), we do not pack them too tight,
// so that we can keep variables nicely together in the address space.
// UI Version always on 0x1000...0x1002 so that the firmware can check this and bail out.
constexpr uint16_t VP_UI_VERSION_MAJOR = 0x1000; // Major -- incremented when incompatible
constexpr uint16_t VP_UI_VERSION_MINOR = 0x1001; // Minor -- incremented on new features, but compatible
constexpr uint16_t VP_UI_VERSION_PATCH = 0x1002; // Patch -- fixed which do not change functionality.
constexpr uint16_t VP_UI_FLAVOUR = 0x1010; // lets reserve 16 bytes here to determine if UI is suitable for this Marlin. tbd.
// Storage space for the Killscreen messages. 0x1100 - 0x1200 . Reused for the popup.
constexpr uint16_t VP_MSGSTR1 = 0x1100;
constexpr uint8_t VP_MSGSTR1_LEN = 0x20; // might be more place for it...
constexpr uint16_t VP_MSGSTR2 = 0x1140;
constexpr uint8_t VP_MSGSTR2_LEN = 0x20;
constexpr uint16_t VP_MSGSTR3 = 0x1180;
constexpr uint8_t VP_MSGSTR3_LEN = 0x20;
constexpr uint16_t VP_MSGSTR4 = 0x11C0;
constexpr uint8_t VP_MSGSTR4_LEN = 0x20;
// Screenchange request for screens that only make sense when printer is idle.
// e.g movement is only allowed if printer is not printing.
// Marlin must confirm by setting the screen manually.
constexpr uint16_t VP_SCREENCHANGE_ASK = 0x2000;
constexpr uint16_t VP_SCREENCHANGE = 0x2001; // Key-Return button to new menu pressed. Data contains target screen in low byte and info in high byte.
constexpr uint16_t VP_TEMP_ALL_OFF = 0x2002; // Turn all heaters off. Value arbitrary ;)=
constexpr uint16_t VP_SCREENCHANGE_WHENSD = 0x2003; // "Print" Button touched -- go only there if there is an SD Card.
constexpr uint16_t VP_CONFIRMED = 0x2010; // OK on confirm screen.
// Buttons on the SD-Card File listing.
constexpr uint16_t VP_SD_ScrollEvent = 0x2020; // Data: 0 for "up a directory", numbers are the amount to scroll, e.g -1 one up, 1 one down
constexpr uint16_t VP_SD_FileSelected = 0x2022; // Number of file field selected.
constexpr uint16_t VP_SD_FileSelectConfirm = 0x2024; // (This is a virtual VP and emulated by the Confirm Screen when a file has been confirmed)
constexpr uint16_t VP_SD_ResumePauseAbort = 0x2026; // Resume(Data=0), Pause(Data=1), Abort(Data=2) SD Card prints
constexpr uint16_t VP_SD_AbortPrintConfirmed = 0x2028; // Abort print confirmation (virtual, will be injected by the confirm dialog)
constexpr uint16_t VP_SD_Print_Setting = 0x2040;
constexpr uint16_t VP_SD_Print_LiveAdjustZ = 0x2050; // Data: 0 down, 1 up
// Controls for movement (we can't use the incremental / decremental feature of the display at this feature works only with 16 bit values
// (which would limit us to 655.35mm, which is likely not a problem for common setups, but i don't want to rule out hangprinters support)
// A word about the coding: The VP will be per axis and the return code will be an signed 16 bit value in 0.01 mm resolution, telling us
// the relative travel amount t he user wants to do. So eg. if the display sends us VP=2100 with value 100, the user wants us to move X by +1 mm.
constexpr uint16_t VP_MOVE_X = 0x2100;
constexpr uint16_t VP_MOVE_Y = 0x2102;
constexpr uint16_t VP_MOVE_Z = 0x2104;
constexpr uint16_t VP_MOVE_E0 = 0x2110;
constexpr uint16_t VP_MOVE_E1 = 0x2112;
//constexpr uint16_t VP_MOVE_E2 = 0x2114;
//constexpr uint16_t VP_MOVE_E3 = 0x2116;
//constexpr uint16_t VP_MOVE_E4 = 0x2118;
//constexpr uint16_t VP_MOVE_E5 = 0x211A;
constexpr uint16_t VP_HOME_ALL = 0x2120;
constexpr uint16_t VP_MOTOR_LOCK_UNLOK = 0x2130;
// Power loss recovery
constexpr uint16_t VP_POWER_LOSS_RECOVERY = 0x2180;
// Fan Control Buttons , switch between "off" and "on"
constexpr uint16_t VP_FAN0_CONTROL = 0x2200;
constexpr uint16_t VP_FAN1_CONTROL = 0x2202;
constexpr uint16_t VP_FAN2_CONTROL = 0x2204;
constexpr uint16_t VP_FAN3_CONTROL = 0x2206;
// Heater Control Buttons , triged between "cool down" and "heat PLA" state
constexpr uint16_t VP_E0_CONTROL = 0x2210;
constexpr uint16_t VP_E1_CONTROL = 0x2212;
//constexpr uint16_t VP_E2_CONTROL = 0x2214;
//constexpr uint16_t VP_E3_CONTROL = 0x2216;
//constexpr uint16_t VP_E4_CONTROL = 0x2218;
//constexpr uint16_t VP_E5_CONTROL = 0x221A;
constexpr uint16_t VP_BED_CONTROL = 0x221C;
// Preheat
constexpr uint16_t VP_E0_BED_PREHEAT = 0x2220;
constexpr uint16_t VP_E1_BED_PREHEAT = 0x2222;
//constexpr uint16_t VP_E2_BED_PREHEAT = 0x2224;
//constexpr uint16_t VP_E3_BED_PREHEAT = 0x2226;
//constexpr uint16_t VP_E4_BED_PREHEAT = 0x2228;
//constexpr uint16_t VP_E5_BED_PREHEAT = 0x222A;
// Filament load and unload
constexpr uint16_t VP_E0_FILAMENT_LOAD_UNLOAD = 0x2300;
constexpr uint16_t VP_E1_FILAMENT_LOAD_UNLOAD = 0x2302;
// Settings store , reset
constexpr uint16_t VP_SETTINGS = 0x2400;
// PID autotune
constexpr uint16_t VP_PID_AUTOTUNE_E0 = 0x2410;
//constexpr uint16_t VP_PID_AUTOTUNE_E1 = 0x2412;
//constexpr uint16_t VP_PID_AUTOTUNE_E2 = 0x2414;
//constexpr uint16_t VP_PID_AUTOTUNE_E3 = 0x2416;
//constexpr uint16_t VP_PID_AUTOTUNE_E4 = 0x2418;
//constexpr uint16_t VP_PID_AUTOTUNE_E5 = 0x241A;
constexpr uint16_t VP_PID_AUTOTUNE_BED = 0x2420;
// Calibrate Z
constexpr uint16_t VP_Z_CALIBRATE = 0x2430;
// First layer cal
constexpr uint16_t VP_Z_FIRST_LAYER_CAL = 0x2500; // Data: 0 - Cancel first layer cal progress, >0 filament type have loaded
// Firmware version on the boot screen.
constexpr uint16_t VP_MARLIN_VERSION = 0x3000;
constexpr uint8_t VP_MARLIN_VERSION_LEN = 16; // there is more space on the display, if needed.
// Place for status messages.
constexpr uint16_t VP_M117 = 0x3020;
constexpr uint8_t VP_M117_LEN = 0x20;
// Temperatures.
constexpr uint16_t VP_T_E0_Is = 0x3060; // 4 Byte Integer
constexpr uint16_t VP_T_E0_Set = 0x3062; // 2 Byte Integer
constexpr uint16_t VP_T_E1_Is = 0x3064; // 4 Byte Integer
// reserved to support up to 6 Extruders:
constexpr uint16_t VP_T_E1_Set = 0x3066; // 2 Byte Integer
//constexpr uint16_t VP_T_E2_Is = 0x3068; // 4 Byte Integer
//constexpr uint16_t VP_T_E2_Set = 0x306A; // 2 Byte Integer
//constexpr uint16_t VP_T_E3_Is = 0x306C; // 4 Byte Integer
//constexpr uint16_t VP_T_E3_Set = 0x306E; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3070; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3072; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3074; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3076; // 2 Byte Integer
//constexpr uint16_t VP_T_E5_Is = 0x3078; // 4 Byte Integer
//constexpr uint16_t VP_T_E5_Set = 0x307A; // 2 Byte Integer
constexpr uint16_t VP_T_Bed_Is = 0x3080; // 4 Byte Integer
constexpr uint16_t VP_T_Bed_Set = 0x3082; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E0 = 0x3090; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E1 = 0x3092; // 2 Byte Integer
// reserved for up to 6 Extruders:
//constexpr uint16_t VP_Flowrate_E2 = 0x3094;
//constexpr uint16_t VP_Flowrate_E3 = 0x3096;
//constexpr uint16_t VP_Flowrate_E4 = 0x3098;
//constexpr uint16_t VP_Flowrate_E5 = 0x309A;
constexpr uint16_t VP_Fan0_Percentage = 0x3100; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan1_Percentage = 0x3102; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan2_Percentage = 0x3104; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan3_Percentage = 0x3106; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Feedrate_Percentage = 0x3108; // 2 Byte Integer (0..100)
// Actual Position
constexpr uint16_t VP_XPos = 0x3110; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_YPos = 0x3112; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_ZPos = 0x3114; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_EPos = 0x3120; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_PrintProgress_Percentage = 0x3130; // 2 Byte Integer (0..100)
constexpr uint16_t VP_PrintTime = 0x3140;
constexpr uint16_t VP_PrintTime_LEN = 32;
constexpr uint16_t VP_PrintAccTime = 0x3160;
constexpr uint16_t VP_PrintAccTime_LEN = 32;
constexpr uint16_t VP_PrintsTotal = 0x3180;
constexpr uint16_t VP_PrintsTotal_LEN = 16;
// SDCard File Listing
constexpr uint16_t VP_SD_FileName_LEN = 32; // LEN is shared for all entries.
constexpr uint16_t DGUS_SD_FILESPERSCREEN = 5; // FIXME move that info to the display and read it from there.
constexpr uint16_t VP_SD_FileName0 = 0x3200;
constexpr uint16_t VP_SD_FileName1 = 0x3220;
constexpr uint16_t VP_SD_FileName2 = 0x3240;
constexpr uint16_t VP_SD_FileName3 = 0x3260;
constexpr uint16_t VP_SD_FileName4 = 0x3280;
constexpr uint16_t VP_SD_Print_ProbeOffsetZ = 0x32A0; //
constexpr uint16_t VP_SD_Print_Filename = 0x32C0;
// Fan status
constexpr uint16_t VP_FAN0_STATUS = 0x3300;
constexpr uint16_t VP_FAN1_STATUS = 0x3302;
constexpr uint16_t VP_FAN2_STATUS = 0x3304;
constexpr uint16_t VP_FAN3_STATUS = 0x3306;
// Heater status
constexpr uint16_t VP_E0_STATUS = 0x3310;
//constexpr uint16_t VP_E1_STATUS = 0x3312;
//constexpr uint16_t VP_E2_STATUS = 0x3314;
//constexpr uint16_t VP_E3_STATUS = 0x3316;
//constexpr uint16_t VP_E4_STATUS = 0x3318;
//constexpr uint16_t VP_E5_STATUS = 0x331A;
constexpr uint16_t VP_BED_STATUS = 0x331C;
constexpr uint16_t VP_MOVE_OPTION = 0x3400;
// Step per mm
constexpr uint16_t VP_X_STEP_PER_MM = 0x3600; // at the moment , 2 byte unsigned int , 0~1638.4
//constexpr uint16_t VP_X2_STEP_PER_MM = 0x3602;
constexpr uint16_t VP_Y_STEP_PER_MM = 0x3604;
//constexpr uint16_t VP_Y2_STEP_PER_MM = 0x3606;
constexpr uint16_t VP_Z_STEP_PER_MM = 0x3608;
//constexpr uint16_t VP_Z2_STEP_PER_MM = 0x360A;
constexpr uint16_t VP_E0_STEP_PER_MM = 0x3610;
constexpr uint16_t VP_E1_STEP_PER_MM = 0x3612;
//constexpr uint16_t VP_E2_STEP_PER_MM = 0x3614;
//constexpr uint16_t VP_E3_STEP_PER_MM = 0x3616;
//constexpr uint16_t VP_E4_STEP_PER_MM = 0x3618;
//constexpr uint16_t VP_E5_STEP_PER_MM = 0x361A;
// PIDs
constexpr uint16_t VP_E0_PID_P = 0x3700; // at the moment , 2 byte unsigned int , 0~1638.4
constexpr uint16_t VP_E0_PID_I = 0x3702;
constexpr uint16_t VP_E0_PID_D = 0x3704;
constexpr uint16_t VP_BED_PID_P = 0x3710;
constexpr uint16_t VP_BED_PID_I = 0x3712;
constexpr uint16_t VP_BED_PID_D = 0x3714;
// Wating screen status
constexpr uint16_t VP_WAITING_STATUS = 0x3800;
// SPs for certain variables...
// located at 0x5000 and up
// Not used yet!
// This can be used e.g to make controls / data display invisible
constexpr uint16_t SP_T_E0_Is = 0x5000;
constexpr uint16_t SP_T_E0_Set = 0x5010;
constexpr uint16_t SP_T_E1_Is = 0x5020;
constexpr uint16_t SP_T_Bed_Is = 0x5030;
constexpr uint16_t SP_T_Bed_Set = 0x5040;

View File

@ -0,0 +1,474 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* DGUS VPs changed by George Fu in 2019 for Marlin */
#include "../../../../../inc/MarlinConfigPre.h"
#if ENABLED(DGUS_LCD_UI_HIPRECY)
#include "../DGUSDisplayDef.h"
#include "../DGUSDisplay.h"
#include "../../../../../module/temperature.h"
#include "../../../../../module/motion.h"
#include "../../../../../module/planner.h"
#include "../../../ui_api.h"
#include "../../../../ultralcd.h"
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
uint16_t distanceToMove = 0.1;
#endif
const uint16_t VPList_Boot[] PROGMEM = {
VP_MARLIN_VERSION,
0x0000
};
const uint16_t VPList_Main[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded. */
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set, VP_E0_STATUS,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set, VP_BED_STATUS,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage, VP_FAN0_STATUS,
#endif
VP_XPos, VP_YPos, VP_ZPos,
VP_Fan0_Percentage,
VP_Feedrate_Percentage,
#if ENABLED(LCD_SET_PROGRESS_MANUALLY)
VP_PrintProgress_Percentage,
#endif
0x0000
};
const uint16_t VPList_Temp[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_Status[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#endif
VP_XPos, VP_YPos, VP_ZPos,
VP_Fan0_Percentage,
VP_Feedrate_Percentage,
VP_PrintProgress_Percentage,
0x0000
};
const uint16_t VPList_Status2[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_Flowrate_E0,
#endif
#if HOTENDS >= 2
VP_Flowrate_E1,
#endif
VP_PrintProgress_Percentage,
VP_PrintTime,
0x0000
};
const uint16_t VPList_Preheat[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_ManualMove[] PROGMEM = {
VP_XPos, VP_YPos, VP_ZPos,
0x0000
};
const uint16_t VPList_ManualExtrude[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
VP_EPos,
0x0000
};
const uint16_t VPList_FanAndFeedrate[] PROGMEM = {
VP_Feedrate_Percentage, VP_Fan0_Percentage,
0x0000
};
const uint16_t VPList_SD_FlowRates[] PROGMEM = {
VP_Flowrate_E0, VP_Flowrate_E1,
0x0000
};
const uint16_t VPList_Filament_heating[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
VP_E0_FILAMENT_LOAD_UNLOAD,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
0x0000
};
const uint16_t VPList_Filament_load_unload[] PROGMEM = {
#if HOTENDS >= 1
VP_E0_FILAMENT_LOAD_UNLOAD,
#endif
#if HOTENDS >= 2
VP_E1_FILAMENT_LOAD_UNLOAD,
#endif
0x0000
};
const uint16_t VPList_SDFileList[] PROGMEM = {
VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4,
0x0000
};
const uint16_t VPList_SD_PrintManipulation[] PROGMEM = {
VP_PrintProgress_Percentage, VP_PrintTime,
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#if FAN_COUNT > 1
VP_Fan1_Percentage,
#endif
#endif
VP_Flowrate_E0,
0x0000
};
const uint16_t VPList_SDPrintTune[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
VP_Feedrate_Percentage,
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#endif
VP_Flowrate_E0,
VP_SD_Print_ProbeOffsetZ,
0x0000
};
const uint16_t VPList_StepPerMM[] PROGMEM = {
VP_X_STEP_PER_MM,
VP_Y_STEP_PER_MM,
VP_Z_STEP_PER_MM,
#if HOTENDS >= 1
VP_E0_STEP_PER_MM,
#endif
#if HOTENDS >= 2
VP_E1_STEP_PER_MM,
#endif
0x0000
};
const uint16_t VPList_PIDE0[] PROGMEM = {
#if ENABLED(PIDTEMP)
VP_E0_PID_P,
VP_E0_PID_I,
VP_E0_PID_D,
#endif
0x0000
};
const uint16_t VPList_PIDBED[] PROGMEM = {
#if ENABLED(PIDTEMP)
VP_BED_PID_P,
VP_BED_PID_I,
VP_BED_PID_D,
#endif
0x0000
};
const uint16_t VPList_Infos[] PROGMEM = {
VP_MARLIN_VERSION,
VP_PrintTime,
#if ENABLED(PRINTCOUNTER)
VP_PrintAccTime,
VP_PrintsTotal,
#endif
0x0000
};
const uint16_t VPList_PIDTuningWaiting[] PROGMEM = {
VP_WAITING_STATUS,
0x0000
};
const uint16_t VPList_FLCPreheat[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_FLCPrinting[] PROGMEM = {
#if HOTENDS >= 1
VP_SD_Print_ProbeOffsetZ,
#endif
0x0000
};
const struct VPMapping VPMap[] PROGMEM = {
{ DGUSLCD_SCREEN_BOOT, VPList_Boot },
{ DGUSLCD_SCREEN_MAIN, VPList_Main },
{ DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp },
{ DGUSLCD_SCREEN_STATUS, VPList_Status },
{ DGUSLCD_SCREEN_STATUS2, VPList_Status2 },
{ DGUSLCD_SCREEN_PREHEAT, VPList_Preheat },
{ DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove },
{ DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude },
{ DGUSLCD_SCREEN_FILAMENT_HEATING, VPList_Filament_heating },
{ DGUSLCD_SCREEN_FILAMENT_LOADING, VPList_Filament_load_unload },
{ DGUSLCD_SCREEN_FILAMENT_UNLOADING, VPList_Filament_load_unload },
{ DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation },
{ DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList },
{ DGUSLCD_SCREEN_SDPRINTTUNE, VPList_SDPrintTune },
{ DGUSLCD_SCREEN_WAITING, VPList_PIDTuningWaiting },
{ DGUSLCD_SCREEN_FLC_PREHEAT, VPList_FLCPreheat },
{ DGUSLCD_SCREEN_FLC_PRINTING, VPList_FLCPrinting },
{ DGUSLCD_SCREEN_STEPPERMM, VPList_StepPerMM },
{ DGUSLCD_SCREEN_PID_E, VPList_PIDE0 },
{ DGUSLCD_SCREEN_PID_BED, VPList_PIDBED },
{ DGUSLCD_SCREEN_INFOS, VPList_Infos },
{ 0 , nullptr } // List is terminated with an nullptr as table entry.
};
const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION;
// Helper to define a DGUS_VP_Variable for common use cases.
#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string)
#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
// Helper to detect touch events
VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr),
VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr),
VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr),
VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr),
VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr),
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr),
#endif
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#else
VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#endif
VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr),
#if ENABLED(POWER_LOSS_RECOVERY)
VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr),
#endif
VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr),
#if ENABLED(SINGLE_Z_CALIBRATION)
VPHELPER(VP_Z_CALIBRATE, nullptr, &DGUSScreenVariableHandler::HandleZCalibration, nullptr),
#endif
#if ENABLED(FIRST_LAYER_CAL)
VPHELPER(VP_Z_FIRST_LAYER_CAL, nullptr, &DGUSScreenVariableHandler::HandleFirstLayerCal, nullptr),
#endif
{ .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
// M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr
{ .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay },
// Temperature Data
#if HOTENDS >= 1
VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E0, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(DGUS_PREHEAT_UI)
VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr),
#endif
#if ENABLED(DGUS_FILAMENT_LOADUNLOAD)
VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload),
#endif
#if ENABLED(PIDTEMP)
VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#endif
#if HOTENDS >= 2
VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#endif
#if HAS_HEATED_BED
VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(PIDTEMP)
VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_PID_AUTOTUNE_BED, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#endif
// Fan Data
#if FAN_COUNT
#define FAN_VPHELPER(N) \
VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \
VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \
VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay),
REPEAT(FAN_COUNT, FAN_VPHELPER)
#endif
// Feedrate
VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly<int16_t>, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ),
// Position Data
VPHELPER(VP_XPos, &current_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_YPos, &current_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_ZPos, &current_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
// Print Progress
VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintProgressToDisplay ),
// Print Time
VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ),
#if ENABLED(PRINTCOUNTER)
VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay ),
VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay ),
#endif
VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#if HOTENDS >= 1
VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
#if HOTENDS >= 2
VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
// SDCard File listing.
#if ENABLED(SDSUPPORT)
VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr),
VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr),
VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr),
VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr),
VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr),
VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr),
#if HAS_BED_PROBE
VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>),
#if ENABLED(BABYSTEPPING)
VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr),
#endif
#endif
#endif
#if ENABLED(DGUS_UI_WAITING)
VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay),
#endif
// Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content.
{ .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
VPHELPER(0, 0, 0, 0) // must be last entry.
};
#endif // DGUS_LCD_UI_HIPRECY

View File

@ -0,0 +1,289 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
enum DGUSLCD_Screens : uint8_t {
DGUSLCD_SCREEN_BOOT = 160,
DGUSLCD_SCREEN_MAIN = 1,
DGUSLCD_SCREEN_STATUS = 1,
DGUSLCD_SCREEN_STATUS2 = 1,
DGUSLCD_SCREEN_POWER_LOSS = 17,
DGUSLCD_SCREEN_TEMPERATURE = 40,
DGUSLCD_SCREEN_MANUALMOVE = 86,
DGUSLCD_SCREEN_PREHEAT = 48,
DGUSLCD_SCREEN_UTILITY = 70,
DGUSLCD_SCREEN_FILAMENT_HEATING = 80,
DGUSLCD_SCREEN_FILAMENT_LOADING = 76,
DGUSLCD_SCREEN_FILAMENT_UNLOADING = 82,
DGUSLCD_SCREEN_MANUALEXTRUDE = 84,
DGUSLCD_SCREEN_SDFILELIST = 3,
DGUSLCD_SCREEN_SDPRINTMANIPULATION = 7,
DGUSLCD_SCREEN_SDPRINTTUNE = 9,
DGUSLCD_SCREEN_FLC_PREHEAT = 94,
DGUSLCD_SCREEN_FLC_PRINTING = 96,
DGUSLCD_SCREEN_STEPPERMM = 122,
DGUSLCD_SCREEN_PID_E = 126,
DGUSLCD_SCREEN_PID_BED = 128,
DGUSLCD_SCREEN_INFOS = 131,
DGUSLCD_SCREEN_CONFIRM = 240,
DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version")
DGUSLCD_SCREEN_WAITING = 251,
DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen"
DGUSLDC_SCREEN_UNUSED = 255
};
// Display Memory layout used (T5UID)
// Except system variables this is arbitrary, just to organize stuff....
// 0x0000 .. 0x0FFF -- System variables and reserved by the display
// 0x1000 .. 0x1FFF -- Variables to never change location, regardless of UI Version
// 0x2000 .. 0x2FFF -- Controls (VPs that will trigger some action)
// 0x3000 .. 0x4FFF -- Marlin Data to be displayed
// 0x5000 .. -- SPs (if we want to modify display elements, e.g change color or like) -- currently unused
// As there is plenty of space (at least most displays have >8k RAM), we do not pack them too tight,
// so that we can keep variables nicely together in the address space.
// UI Version always on 0x1000...0x1002 so that the firmware can check this and bail out.
constexpr uint16_t VP_UI_VERSION_MAJOR = 0x1000; // Major -- incremented when incompatible
constexpr uint16_t VP_UI_VERSION_MINOR = 0x1001; // Minor -- incremented on new features, but compatible
constexpr uint16_t VP_UI_VERSION_PATCH = 0x1002; // Patch -- fixed which do not change functionality.
constexpr uint16_t VP_UI_FLAVOUR = 0x1010; // lets reserve 16 bytes here to determine if UI is suitable for this Marlin. tbd.
// Storage space for the Killscreen messages. 0x1100 - 0x1200 . Reused for the popup.
constexpr uint16_t VP_MSGSTR1 = 0x1100;
constexpr uint8_t VP_MSGSTR1_LEN = 0x20; // might be more place for it...
constexpr uint16_t VP_MSGSTR2 = 0x1140;
constexpr uint8_t VP_MSGSTR2_LEN = 0x20;
constexpr uint16_t VP_MSGSTR3 = 0x1180;
constexpr uint8_t VP_MSGSTR3_LEN = 0x20;
constexpr uint16_t VP_MSGSTR4 = 0x11C0;
constexpr uint8_t VP_MSGSTR4_LEN = 0x20;
// Screenchange request for screens that only make sense when printer is idle.
// e.g movement is only allowed if printer is not printing.
// Marlin must confirm by setting the screen manually.
constexpr uint16_t VP_SCREENCHANGE_ASK = 0x2000;
constexpr uint16_t VP_SCREENCHANGE = 0x2001; // Key-Return button to new menu pressed. Data contains target screen in low byte and info in high byte.
constexpr uint16_t VP_TEMP_ALL_OFF = 0x2002; // Turn all heaters off. Value arbitrary ;)=
constexpr uint16_t VP_SCREENCHANGE_WHENSD = 0x2003; // "Print" Button touched -- go only there if there is an SD Card.
constexpr uint16_t VP_CONFIRMED = 0x2010; // OK on confirm screen.
// Buttons on the SD-Card File listing.
constexpr uint16_t VP_SD_ScrollEvent = 0x2020; // Data: 0 for "up a directory", numbers are the amount to scroll, e.g -1 one up, 1 one down
constexpr uint16_t VP_SD_FileSelected = 0x2022; // Number of file field selected.
constexpr uint16_t VP_SD_FileSelectConfirm = 0x2024; // (This is a virtual VP and emulated by the Confirm Screen when a file has been confirmed)
constexpr uint16_t VP_SD_ResumePauseAbort = 0x2026; // Resume(Data=0), Pause(Data=1), Abort(Data=2) SD Card prints
constexpr uint16_t VP_SD_AbortPrintConfirmed = 0x2028; // Abort print confirmation (virtual, will be injected by the confirm dialog)
constexpr uint16_t VP_SD_Print_Setting = 0x2040;
constexpr uint16_t VP_SD_Print_LiveAdjustZ = 0x2050; // Data: 0 down, 1 up
// Controls for movement (we can't use the incremental / decremental feature of the display at this feature works only with 16 bit values
// (which would limit us to 655.35mm, which is likely not a problem for common setups, but i don't want to rule out hangprinters support)
// A word about the coding: The VP will be per axis and the return code will be an signed 16 bit value in 0.01 mm resolution, telling us
// the relative travel amount t he user wants to do. So eg. if the display sends us VP=2100 with value 100, the user wants us to move X by +1 mm.
constexpr uint16_t VP_MOVE_X = 0x2100;
constexpr uint16_t VP_MOVE_Y = 0x2102;
constexpr uint16_t VP_MOVE_Z = 0x2104;
constexpr uint16_t VP_MOVE_E0 = 0x2110;
constexpr uint16_t VP_MOVE_E1 = 0x2112;
//constexpr uint16_t VP_MOVE_E2 = 0x2114;
//constexpr uint16_t VP_MOVE_E3 = 0x2116;
//constexpr uint16_t VP_MOVE_E4 = 0x2118;
//constexpr uint16_t VP_MOVE_E5 = 0x211A;
constexpr uint16_t VP_HOME_ALL = 0x2120;
constexpr uint16_t VP_MOTOR_LOCK_UNLOK = 0x2130;
// Power loss recovery
constexpr uint16_t VP_POWER_LOSS_RECOVERY = 0x2180;
// Fan Control Buttons , switch between "off" and "on"
constexpr uint16_t VP_FAN0_CONTROL = 0x2200;
constexpr uint16_t VP_FAN1_CONTROL = 0x2202;
//constexpr uint16_t VP_FAN2_CONTROL = 0x2204;
//constexpr uint16_t VP_FAN3_CONTROL = 0x2206;
// Heater Control Buttons , triged between "cool down" and "heat PLA" state
constexpr uint16_t VP_E0_CONTROL = 0x2210;
constexpr uint16_t VP_E1_CONTROL = 0x2212;
//constexpr uint16_t VP_E2_CONTROL = 0x2214;
//constexpr uint16_t VP_E3_CONTROL = 0x2216;
//constexpr uint16_t VP_E4_CONTROL = 0x2218;
//constexpr uint16_t VP_E5_CONTROL = 0x221A;
constexpr uint16_t VP_BED_CONTROL = 0x221C;
// Preheat
constexpr uint16_t VP_E0_BED_PREHEAT = 0x2220;
//constexpr uint16_t VP_E1_BED_PREHEAT = 0x2222;
//constexpr uint16_t VP_E2_BED_PREHEAT = 0x2224;
//constexpr uint16_t VP_E3_BED_PREHEAT = 0x2226;
//constexpr uint16_t VP_E4_BED_PREHEAT = 0x2228;
//constexpr uint16_t VP_E5_BED_PREHEAT = 0x222A;
// Filament load and unload
constexpr uint16_t VP_E0_FILAMENT_LOAD_UNLOAD = 0x2300;
// Settings store , reset
constexpr uint16_t VP_SETTINGS = 0x2400;
// PID autotune
constexpr uint16_t VP_PID_AUTOTUNE_E0 = 0x2410;
//constexpr uint16_t VP_PID_AUTOTUNE_E1 = 0x2412;
//constexpr uint16_t VP_PID_AUTOTUNE_E2 = 0x2414;
//constexpr uint16_t VP_PID_AUTOTUNE_E3 = 0x2416;
//constexpr uint16_t VP_PID_AUTOTUNE_E4 = 0x2418;
//constexpr uint16_t VP_PID_AUTOTUNE_E5 = 0x241A;
constexpr uint16_t VP_PID_AUTOTUNE_BED = 0x2420;
// Calibrate Z
constexpr uint16_t VP_Z_CALIBRATE = 0x2430;
// First layer cal
constexpr uint16_t VP_Z_FIRST_LAYER_CAL = 0x2500; // Data: 0 - Cancel first layer cal progress, >0 filament type have loaded
// Firmware version on the boot screen.
constexpr uint16_t VP_MARLIN_VERSION = 0x3000;
constexpr uint8_t VP_MARLIN_VERSION_LEN = 16; // there is more space on the display, if needed.
// Place for status messages.
constexpr uint16_t VP_M117 = 0x3020;
constexpr uint8_t VP_M117_LEN = 0x20;
// Temperatures.
constexpr uint16_t VP_T_E0_Is = 0x3060; // 4 Byte Integer
constexpr uint16_t VP_T_E0_Set = 0x3062; // 2 Byte Integer
constexpr uint16_t VP_T_E1_Is = 0x3064; // 4 Byte Integer
// reserved to support up to 6 Extruders:
//constexpr uint16_t VP_T_E1_Set = 0x3066; // 2 Byte Integer
//constexpr uint16_t VP_T_E2_Is = 0x3068; // 4 Byte Integer
//constexpr uint16_t VP_T_E2_Set = 0x306A; // 2 Byte Integer
//constexpr uint16_t VP_T_E3_Is = 0x306C; // 4 Byte Integer
//constexpr uint16_t VP_T_E3_Set = 0x306E; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3070; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3072; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3074; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3076; // 2 Byte Integer
//constexpr uint16_t VP_T_E5_Is = 0x3078; // 4 Byte Integer
//constexpr uint16_t VP_T_E5_Set = 0x307A; // 2 Byte Integer
constexpr uint16_t VP_T_Bed_Is = 0x3080; // 4 Byte Integer
constexpr uint16_t VP_T_Bed_Set = 0x3082; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E0 = 0x3090; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E1 = 0x3092; // 2 Byte Integer
// reserved for up to 6 Extruders:
//constexpr uint16_t VP_Flowrate_E2 = 0x3094;
//constexpr uint16_t VP_Flowrate_E3 = 0x3096;
//constexpr uint16_t VP_Flowrate_E4 = 0x3098;
//constexpr uint16_t VP_Flowrate_E5 = 0x309A;
constexpr uint16_t VP_Fan0_Percentage = 0x3100; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan1_Percentage = 0x3102; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan2_Percentage = 0x3104; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Fan3_Percentage = 0x3106; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Feedrate_Percentage = 0x3108; // 2 Byte Integer (0..100)
// Actual Position
constexpr uint16_t VP_XPos = 0x3110; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_YPos = 0x3112; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_ZPos = 0x3114; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_EPos = 0x3120; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_PrintProgress_Percentage = 0x3130; // 2 Byte Integer (0..100)
constexpr uint16_t VP_PrintTime = 0x3140;
constexpr uint16_t VP_PrintTime_LEN = 32;
constexpr uint16_t VP_PrintAccTime = 0x3160;
constexpr uint16_t VP_PrintAccTime_LEN = 32;
constexpr uint16_t VP_PrintsTotal = 0x3180;
constexpr uint16_t VP_PrintsTotal_LEN = 16;
// SDCard File Listing
constexpr uint16_t VP_SD_FileName_LEN = 32; // LEN is shared for all entries.
constexpr uint16_t DGUS_SD_FILESPERSCREEN = 5; // FIXME move that info to the display and read it from there.
constexpr uint16_t VP_SD_FileName0 = 0x3200;
constexpr uint16_t VP_SD_FileName1 = 0x3220;
constexpr uint16_t VP_SD_FileName2 = 0x3240;
constexpr uint16_t VP_SD_FileName3 = 0x3260;
constexpr uint16_t VP_SD_FileName4 = 0x3280;
constexpr uint16_t VP_SD_Print_ProbeOffsetZ = 0x32A0; //
constexpr uint16_t VP_SD_Print_Filename = 0x32C0; //
// Fan status
constexpr uint16_t VP_FAN0_STATUS = 0x3300;
constexpr uint16_t VP_FAN1_STATUS = 0x3302;
//constexpr uint16_t VP_FAN2_STATUS = 0x3304;
//constexpr uint16_t VP_FAN3_STATUS = 0x3306;
// Heater status
constexpr uint16_t VP_E0_STATUS = 0x3310;
//constexpr uint16_t VP_E1_STATUS = 0x3312;
//constexpr uint16_t VP_E2_STATUS = 0x3314;
//constexpr uint16_t VP_E3_STATUS = 0x3316;
//constexpr uint16_t VP_E4_STATUS = 0x3318;
//constexpr uint16_t VP_E5_STATUS = 0x331A;
constexpr uint16_t VP_BED_STATUS = 0x331C;
constexpr uint16_t VP_MOVE_OPTION = 0x3400;
// Step per mm
constexpr uint16_t VP_X_STEP_PER_MM = 0x3600; // at the moment , 2 byte unsigned int , 0~1638.4
//constexpr uint16_t VP_X2_STEP_PER_MM = 0x3602;
constexpr uint16_t VP_Y_STEP_PER_MM = 0x3604;
//constexpr uint16_t VP_Y2_STEP_PER_MM = 0x3606;
constexpr uint16_t VP_Z_STEP_PER_MM = 0x3608;
//constexpr uint16_t VP_Z2_STEP_PER_MM = 0x360A;
constexpr uint16_t VP_E0_STEP_PER_MM = 0x3610;
//constexpr uint16_t VP_E1_STEP_PER_MM = 0x3612;
//constexpr uint16_t VP_E2_STEP_PER_MM = 0x3614;
//constexpr uint16_t VP_E3_STEP_PER_MM = 0x3616;
//constexpr uint16_t VP_E4_STEP_PER_MM = 0x3618;
//constexpr uint16_t VP_E5_STEP_PER_MM = 0x361A;
// PIDs
constexpr uint16_t VP_E0_PID_P = 0x3700; // at the moment , 2 byte unsigned int , 0~1638.4
constexpr uint16_t VP_E0_PID_I = 0x3702;
constexpr uint16_t VP_E0_PID_D = 0x3704;
constexpr uint16_t VP_BED_PID_P = 0x3710;
constexpr uint16_t VP_BED_PID_I = 0x3712;
constexpr uint16_t VP_BED_PID_D = 0x3714;
// Wating screen status
constexpr uint16_t VP_WAITING_STATUS = 0x3800;
// SPs for certain variables...
// located at 0x5000 and up
// Not used yet!
// This can be used e.g to make controls / data display invisible
constexpr uint16_t SP_T_E0_Is = 0x5000;
constexpr uint16_t SP_T_E0_Set = 0x5010;
constexpr uint16_t SP_T_E1_Is = 0x5020;
constexpr uint16_t SP_T_Bed_Is = 0x5030;
constexpr uint16_t SP_T_Bed_Set = 0x5040;

View File

@ -0,0 +1,306 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* DGUS implementation written by coldtobi in 2019 for Marlin */
#include "../../../../../inc/MarlinConfigPre.h"
#if ENABLED(DGUS_LCD_UI_ORIGIN)
#include "../DGUSDisplayDef.h"
#include "../DGUSDisplay.h"
#include "../../../../../module/temperature.h"
#include "../../../../../module/motion.h"
#include "../../../../../module/planner.h"
#include "../../../../ultralcd.h"
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
uint16_t distanceToMove = 0.1;
#endif
const uint16_t VPList_Boot[] PROGMEM = {
VP_MARLIN_VERSION,
0x0000
};
const uint16_t VPList_Main[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded. */
0x0000
};
const uint16_t VPList_Temp[] PROGMEM = {
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
0x0000
};
const uint16_t VPList_Status[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_T_E0_Is, VP_T_E0_Set,
#endif
#if HOTENDS >= 2
VP_T_E1_Is, VP_T_E1_Set,
#endif
#if HAS_HEATED_BED
VP_T_Bed_Is, VP_T_Bed_Set,
#endif
#if FAN_COUNT > 0
VP_Fan0_Percentage,
#endif
VP_XPos, VP_YPos, VP_ZPos,
VP_Fan0_Percentage,
VP_Feedrate_Percentage,
VP_PrintProgress_Percentage,
0x0000
};
const uint16_t VPList_Status2[] PROGMEM = {
/* VP_M117, for completeness, but it cannot be auto-uploaded */
#if HOTENDS >= 1
VP_Flowrate_E0,
#endif
#if HOTENDS >= 2
VP_Flowrate_E1,
#endif
VP_PrintProgress_Percentage,
VP_PrintTime,
0x0000
};
const uint16_t VPList_ManualMove[] PROGMEM = {
VP_XPos, VP_YPos, VP_ZPos,
0x0000
};
const uint16_t VPList_ManualExtrude[] PROGMEM = {
VP_EPos,
0x0000
};
const uint16_t VPList_FanAndFeedrate[] PROGMEM = {
VP_Feedrate_Percentage, VP_Fan0_Percentage,
0x0000
};
const uint16_t VPList_SD_FlowRates[] PROGMEM = {
VP_Flowrate_E0, VP_Flowrate_E1,
0x0000
};
const uint16_t VPList_SDFileList[] PROGMEM = {
VP_SD_FileName0, VP_SD_FileName1, VP_SD_FileName2, VP_SD_FileName3, VP_SD_FileName4,
0x0000
};
const uint16_t VPList_SD_PrintManipulation[] PROGMEM = {
VP_PrintProgress_Percentage, VP_PrintTime,
0x0000
};
const struct VPMapping VPMap[] PROGMEM = {
{ DGUSLCD_SCREEN_BOOT, VPList_Boot },
{ DGUSLCD_SCREEN_MAIN, VPList_Main },
{ DGUSLCD_SCREEN_TEMPERATURE, VPList_Temp },
{ DGUSLCD_SCREEN_STATUS, VPList_Status },
{ DGUSLCD_SCREEN_STATUS2, VPList_Status2 },
{ DGUSLCD_SCREEN_MANUALMOVE, VPList_ManualMove },
{ DGUSLCD_SCREEN_MANUALEXTRUDE, VPList_ManualExtrude },
{ DGUSLCD_SCREEN_FANANDFEEDRATE, VPList_FanAndFeedrate },
{ DGUSLCD_SCREEN_FLOWRATES, VPList_SD_FlowRates },
{ DGUSLCD_SCREEN_SDPRINTMANIPULATION, VPList_SD_PrintManipulation },
{ DGUSLCD_SCREEN_SDFILELIST, VPList_SDFileList },
{ 0 , nullptr } // List is terminated with an nullptr as table entry.
};
const char MarlinVersion[] PROGMEM = SHORT_BUILD_VERSION;
// Helper to define a DGUS_VP_Variable for common use cases.
#define VPHELPER(VPADR, VPADRVAR, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=sizeof(VPADRVAR), \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
// Helper to define a DGUS_VP_Variable when the sizeo of the var cannot be determined automaticalyl (eg. a string)
#define VPHELPER_STR(VPADR, VPADRVAR, STRLEN, RXFPTR, TXFPTR ) { .VP=VPADR, .memadr=VPADRVAR, .size=STRLEN, \
.set_by_display_handler = RXFPTR, .send_to_display_handler = TXFPTR }
const struct DGUS_VP_Variable ListOfVP[] PROGMEM = {
// Helper to detect touch events
VPHELPER(VP_SCREENCHANGE, nullptr, DGUSScreenVariableHandler::ScreenChangeHook, nullptr),
VPHELPER(VP_SCREENCHANGE_ASK, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfIdle, nullptr),
#if ENABLED(SDSUPPORT)
VPHELPER(VP_SCREENCHANGE_WHENSD, nullptr, DGUSScreenVariableHandler::ScreenChangeHookIfSD, nullptr),
#endif
VPHELPER(VP_CONFIRMED, nullptr, DGUSScreenVariableHandler::ScreenConfirmedOK, nullptr),
VPHELPER(VP_TEMP_ALL_OFF, nullptr, &DGUSScreenVariableHandler::HandleAllHeatersOff, nullptr),
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_OPTION, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMoveOption, nullptr),
#endif
#if ENABLED(DGUS_UI_MOVE_DIS_OPTION)
VPHELPER(VP_MOVE_X, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, &distanceToMove, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#else
VPHELPER(VP_MOVE_X, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Y, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_MOVE_Z, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
VPHELPER(VP_HOME_ALL, nullptr, &DGUSScreenVariableHandler::HandleManualMove, nullptr),
#endif
VPHELPER(VP_MOTOR_LOCK_UNLOK, nullptr, &DGUSScreenVariableHandler::HandleMotorLockUnlock, nullptr),
#if ENABLED(POWER_LOSS_RECOVERY)
VPHELPER(VP_POWER_LOSS_RECOVERY, nullptr, &DGUSScreenVariableHandler::HandlePowerLossRecovery, nullptr),
#endif
VPHELPER(VP_SETTINGS, nullptr, &DGUSScreenVariableHandler::HandleSettings, nullptr),
{ .VP = VP_MARLIN_VERSION, .memadr = (void*)MarlinVersion, .size = VP_MARLIN_VERSION_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
// M117 LCD String (We don't need the string in memory but "just" push it to the display on demand, hence the nullptr
{ .VP = VP_M117, .memadr = nullptr, .size = VP_M117_LEN, .set_by_display_handler = nullptr, .send_to_display_handler =&DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplay },
// Temperature Data
#if HOTENDS >= 1
VPHELPER(VP_T_E0_Is, &thermalManager.temp_hotend[0].celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E0_Set, &thermalManager.temp_hotend[0].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E0, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_EPos, &destination.e, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_MOVE_E0, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E0_CONTROL, &thermalManager.temp_hotend[0].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E0_STATUS, &thermalManager.temp_hotend[0].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(DGUS_PREHEAT_UI)
VPHELPER(VP_E0_BED_PREHEAT, nullptr, &DGUSScreenVariableHandler::HandlePreheat, nullptr),
#endif
#if ENABLED(PIDTEMP)
VPHELPER(VP_E0_PID_P, &thermalManager.temp_hotend[0].pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_I, &thermalManager.temp_hotend[0].pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_E0_PID_D, &thermalManager.temp_hotend[0].pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_PID_AUTOTUNE_E0, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#if ENABLED(DGUS_FILAMENT_LOADUNLOAD)
VPHELPER(VP_E0_FILAMENT_LOAD_UNLOAD, nullptr, &DGUSScreenVariableHandler::HandleFilamentOption, &DGUSScreenVariableHandler::HandleFilamentLoadUnload),
#endif
#endif
#if HOTENDS >= 2
VPHELPER(VP_T_E1_Is, &thermalManager.temp_hotend[1].celsius, nullptr, DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_E1_Set, &thermalManager.temp_hotend[1].target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_Flowrate_E1, nullptr, DGUSScreenVariableHandler::HandleFlowRateChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_MOVE_E1, nullptr, &DGUSScreenVariableHandler::HandleManualExtrude, nullptr),
VPHELPER(VP_E1_CONTROL, &thermalManager.temp_hotend[1].target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_E1_STATUS, &thermalManager.temp_hotend[1].target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(PIDTEMP)
VPHELPER(VP_PID_AUTOTUNE_E1, nullptr, &DGUSScreenVariableHandler::HandlePIDAutotune, nullptr),
#endif
#endif
#if HAS_HEATED_BED
VPHELPER(VP_T_Bed_Is, &thermalManager.temp_bed.celsius, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<0>),
VPHELPER(VP_T_Bed_Set, &thermalManager.temp_bed.target, DGUSScreenVariableHandler::HandleTemperatureChanged, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay),
VPHELPER(VP_BED_CONTROL, &thermalManager.temp_bed.target, &DGUSScreenVariableHandler::HandleHeaterControl, nullptr),
VPHELPER(VP_BED_STATUS, &thermalManager.temp_bed.target, nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendHeaterStatusToDisplay),
#if ENABLED(PIDTEMPBED)
VPHELPER(VP_BED_PID_P, &thermalManager.temp_bed.pid.Kp, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_I, &thermalManager.temp_bed.pid.Ki, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
VPHELPER(VP_BED_PID_D, &thermalManager.temp_bed.pid.Kd, DGUSScreenVariableHandler::HandleTemperaturePIDChanged, DGUSScreenVariableHandler::DGUSLCD_SendTemperaturePID),
#endif
#endif
// Fan Data
#if FAN_COUNT
#define FAN_VPHELPER(N) \
VPHELPER(VP_Fan##N##_Percentage, &thermalManager.fan_speed[N], DGUSScreenVariableHandler::DGUSLCD_PercentageToUint8, &DGUSScreenVariableHandler::DGUSLCD_SendPercentageToDisplay), \
VPHELPER(VP_FAN##N##_CONTROL, &thermalManager.fan_speed[N], &DGUSScreenVariableHandler::HandleFanControl, nullptr), \
VPHELPER(VP_FAN##N##_STATUS, &thermalManager.fan_speed[N], nullptr, &DGUSScreenVariableHandler::DGUSLCD_SendFanStatusToDisplay),
REPEAT(FAN_COUNT, FAN_VPHELPER)
#endif
// Feedrate
VPHELPER(VP_Feedrate_Percentage, &feedrate_percentage, DGUSScreenVariableHandler::DGUSLCD_SetValueDirectly<int16_t>, &DGUSScreenVariableHandler::DGUSLCD_SendWordValueToDisplay ),
// Position Data
VPHELPER(VP_XPos, &current_position.x, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_YPos, &current_position.y, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
VPHELPER(VP_ZPos, &current_position.z, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsLongValueToDisplay<2>),
// Print Progress
VPHELPER(VP_PrintProgress_Percentage, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintProgressToDisplay ),
// Print Time
VPHELPER_STR(VP_PrintTime, nullptr, VP_PrintTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintTimeToDisplay ),
#if ENABLED(PRINTCOUNTER)
VPHELPER_STR(VP_PrintAccTime, nullptr, VP_PrintAccTime_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintAccTimeToDisplay ),
VPHELPER_STR(VP_PrintsTotal, nullptr, VP_PrintsTotal_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendPrintsTotalToDisplay ),
#endif
VPHELPER(VP_X_STEP_PER_MM, &planner.settings.axis_steps_per_mm[X_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Y_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Y_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
VPHELPER(VP_Z_STEP_PER_MM, &planner.settings.axis_steps_per_mm[Z_AXIS], DGUSScreenVariableHandler::HandleStepPerMMChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#if HOTENDS >= 1
VPHELPER(VP_E0_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(0)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
#if HOTENDS >= 2
VPHELPER(VP_E1_STEP_PER_MM, &planner.settings.axis_steps_per_mm[E_AXIS_N(1)], DGUSScreenVariableHandler::HandleStepPerMMExtruderChanged, DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<1>),
#endif
// SDCard File listing.
#if ENABLED(SDSUPPORT)
VPHELPER(VP_SD_ScrollEvent, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ScrollFilelist, nullptr),
VPHELPER(VP_SD_FileSelected, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_FileSelected, nullptr),
VPHELPER(VP_SD_FileSelectConfirm, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_StartPrint, nullptr),
VPHELPER_STR(VP_SD_FileName0, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName1, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName2, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName3, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER_STR(VP_SD_FileName4, nullptr, VP_SD_FileName_LEN, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_SendFilename ),
VPHELPER(VP_SD_ResumePauseAbort, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ResumePauseAbort, nullptr),
VPHELPER(VP_SD_AbortPrintConfirmed, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_ReallyAbort, nullptr),
VPHELPER(VP_SD_Print_Setting, nullptr, DGUSScreenVariableHandler::DGUSLCD_SD_PrintTune, nullptr),
#if HAS_BED_PROBE
VPHELPER(VP_SD_Print_ProbeOffsetZ, &probe.offset.z, DGUSScreenVariableHandler::HandleProbeOffsetZChanged, &DGUSScreenVariableHandler::DGUSLCD_SendFloatAsIntValueToDisplay<2>),
#if ENABLED(BABYSTEPPING)
VPHELPER(VP_SD_Print_LiveAdjustZ, nullptr, DGUSScreenVariableHandler::HandleLiveAdjustZ, nullptr),
#endif
#endif
#endif
#if ENABLED(DGUS_UI_WAITING)
VPHELPER(VP_WAITING_STATUS, nullptr, nullptr, DGUSScreenVariableHandler::DGUSLCD_SendWaitingStatusToDisplay),
#endif
// Messages for the User, shared by the popup and the kill screen. They cant be autouploaded as we do not buffer content.
{ .VP = VP_MSGSTR1, .memadr = nullptr, .size = VP_MSGSTR1_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR2, .memadr = nullptr, .size = VP_MSGSTR2_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR3, .memadr = nullptr, .size = VP_MSGSTR3_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
{ .VP = VP_MSGSTR4, .memadr = nullptr, .size = VP_MSGSTR4_LEN, .set_by_display_handler = nullptr, .send_to_display_handler = &DGUSScreenVariableHandler::DGUSLCD_SendStringToDisplayPGM },
VPHELPER(0, 0, 0, 0) // must be last entry.
};
#endif // DGUS_LCD_UI_ORIGIN

View File

@ -0,0 +1,280 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
enum DGUSLCD_Screens : uint8_t {
DGUSLCD_SCREEN_BOOT = 0,
DGUSLCD_SCREEN_MAIN = 10,
DGUSLCD_SCREEN_TEMPERATURE = 20,
DGUSLCD_SCREEN_STATUS = 30,
DGUSLCD_SCREEN_STATUS2 = 32,
DGUSLCD_SCREEN_MANUALMOVE = 40,
DGUSLCD_SCREEN_MANUALEXTRUDE=42,
DGUSLCD_SCREEN_FANANDFEEDRATE = 44,
DGUSLCD_SCREEN_FLOWRATES = 46,
DGUSLCD_SCREEN_SDFILELIST = 50,
DGUSLCD_SCREEN_SDPRINTMANIPULATION = 52,
DGUSLCD_SCREEN_POWER_LOSS = 100,
DGUSLCD_SCREEN_PREHEAT=120,
DGUSLCD_SCREEN_UTILITY=110,
DGUSLCD_SCREEN_FILAMENT_HEATING=146,
DGUSLCD_SCREEN_FILAMENT_LOADING=148,
DGUSLCD_SCREEN_FILAMENT_UNLOADING=158,
DGUSLCD_SCREEN_SDPRINTTUNE = 170,
DGUSLCD_SCREEN_CONFIRM = 240,
DGUSLCD_SCREEN_KILL = 250, ///< Kill Screen. Must always be 250 (to be able to display "Error wrong LCD Version")
DGUSLCD_SCREEN_WAITING = 251,
DGUSLCD_SCREEN_POPUP = 252, ///< special target, popup screen will also return this code to say "return to previous screen"
DGUSLDC_SCREEN_UNUSED = 255
};
// Display Memory layout used (T5UID)
// Except system variables this is arbitrary, just to organize stuff....
// 0x0000 .. 0x0FFF -- System variables and reserved by the display
// 0x1000 .. 0x1FFF -- Variables to never change location, regardless of UI Version
// 0x2000 .. 0x2FFF -- Controls (VPs that will trigger some action)
// 0x3000 .. 0x4FFF -- Marlin Data to be displayed
// 0x5000 .. -- SPs (if we want to modify display elements, e.g change color or like) -- currently unused
// As there is plenty of space (at least most displays have >8k RAM), we do not pack them too tight,
// so that we can keep variables nicely together in the address space.
// UI Version always on 0x1000...0x1002 so that the firmware can check this and bail out.
constexpr uint16_t VP_UI_VERSION_MAJOR = 0x1000; // Major -- incremented when incompatible
constexpr uint16_t VP_UI_VERSION_MINOR = 0x1001; // Minor -- incremented on new features, but compatible
constexpr uint16_t VP_UI_VERSION_PATCH = 0x1002; // Patch -- fixed which do not change functionality.
constexpr uint16_t VP_UI_FLAVOUR = 0x1010; // lets reserve 16 bytes here to determine if UI is suitable for this Marlin. tbd.
// Storage space for the Killscreen messages. 0x1100 - 0x1200 . Reused for the popup.
constexpr uint16_t VP_MSGSTR1 = 0x1100;
constexpr uint8_t VP_MSGSTR1_LEN = 0x20; // might be more place for it...
constexpr uint16_t VP_MSGSTR2 = 0x1140;
constexpr uint8_t VP_MSGSTR2_LEN = 0x20;
constexpr uint16_t VP_MSGSTR3 = 0x1180;
constexpr uint8_t VP_MSGSTR3_LEN = 0x20;
constexpr uint16_t VP_MSGSTR4 = 0x11C0;
constexpr uint8_t VP_MSGSTR4_LEN = 0x20;
// Screenchange request for screens that only make sense when printer is idle.
// e.g movement is only allowed if printer is not printing.
// Marlin must confirm by setting the screen manually.
constexpr uint16_t VP_SCREENCHANGE_ASK = 0x2000;
constexpr uint16_t VP_SCREENCHANGE = 0x2001; // Key-Return button to new menu pressed. Data contains target screen in low byte and info in high byte.
constexpr uint16_t VP_TEMP_ALL_OFF = 0x2002; // Turn all heaters off. Value arbitrary ;)=
constexpr uint16_t VP_SCREENCHANGE_WHENSD = 0x2003; // "Print" Button touched -- go only there if there is an SD Card.
constexpr uint16_t VP_CONFIRMED = 0x2010; // OK on confirm screen.
// Buttons on the SD-Card File listing.
constexpr uint16_t VP_SD_ScrollEvent = 0x2020; // Data: 0 for "up a directory", numbers are the amount to scroll, e.g -1 one up, 1 one down
constexpr uint16_t VP_SD_FileSelected = 0x2022; // Number of file field selected.
constexpr uint16_t VP_SD_FileSelectConfirm = 0x2024; // (This is a virtual VP and emulated by the Confirm Screen when a file has been confirmed)
constexpr uint16_t VP_SD_ResumePauseAbort = 0x2026; // Resume(Data=0), Pause(Data=1), Abort(Data=2) SD Card prints
constexpr uint16_t VP_SD_AbortPrintConfirmed = 0x2028; // Abort print confirmation (virtual, will be injected by the confirm dialog)
constexpr uint16_t VP_SD_Print_Setting = 0x2040;
constexpr uint16_t VP_SD_Print_LiveAdjustZ = 0x2050; // Data: 0 down, 1 up
// Controls for movement (we can't use the incremental / decremental feature of the display at this feature works only with 16 bit values
// (which would limit us to 655.35mm, which is likely not a problem for common setups, but i don't want to rule out hangprinters support)
// A word about the coding: The VP will be per axis and the return code will be an signed 16 bit value in 0.01 mm resolution, telling us
// the relative travel amount t he user wants to do. So eg. if the display sends us VP=2100 with value 100, the user wants us to move X by +1 mm.
constexpr uint16_t VP_MOVE_X = 0x2100;
constexpr uint16_t VP_MOVE_Y = 0x2102;
constexpr uint16_t VP_MOVE_Z = 0x2104;
constexpr uint16_t VP_MOVE_E0 = 0x2110;
constexpr uint16_t VP_MOVE_E1 = 0x2112;
//constexpr uint16_t VP_MOVE_E2 = 0x2114;
//constexpr uint16_t VP_MOVE_E3 = 0x2116;
//constexpr uint16_t VP_MOVE_E4 = 0x2118;
//constexpr uint16_t VP_MOVE_E5 = 0x211A;
constexpr uint16_t VP_HOME_ALL = 0x2120;
constexpr uint16_t VP_MOTOR_LOCK_UNLOK = 0x2130;
// Power loss recovery
constexpr uint16_t VP_POWER_LOSS_RECOVERY = 0x2180;
// Fan Control Buttons , switch between "off" and "on"
constexpr uint16_t VP_FAN0_CONTROL = 0x2200;
constexpr uint16_t VP_FAN1_CONTROL = 0x2202;
//constexpr uint16_t VP_FAN2_CONTROL = 0x2204;
//constexpr uint16_t VP_FAN3_CONTROL = 0x2206;
// Heater Control Buttons , triged between "cool down" and "heat PLA" state
constexpr uint16_t VP_E0_CONTROL = 0x2210;
constexpr uint16_t VP_E1_CONTROL = 0x2212;
//constexpr uint16_t VP_E2_CONTROL = 0x2214;
//constexpr uint16_t VP_E3_CONTROL = 0x2216;
//constexpr uint16_t VP_E4_CONTROL = 0x2218;
//constexpr uint16_t VP_E5_CONTROL = 0x221A;
constexpr uint16_t VP_BED_CONTROL = 0x221C;
// Preheat
constexpr uint16_t VP_E0_BED_PREHEAT = 0x2220;
constexpr uint16_t VP_E1_BED_CONTROL = 0x2222;
//constexpr uint16_t VP_E2_BED_CONTROL = 0x2224;
//constexpr uint16_t VP_E3_BED_CONTROL = 0x2226;
//constexpr uint16_t VP_E4_BED_CONTROL = 0x2228;
//constexpr uint16_t VP_E5_BED_CONTROL = 0x222A;
// Filament load and unload
constexpr uint16_t VP_E0_FILAMENT_LOAD_UNLOAD = 0x2300;
constexpr uint16_t VP_E1_FILAMENT_LOAD_UNLOAD = 0x2302;
// Settings store , reset
constexpr uint16_t VP_SETTINGS = 0x2400;
// PID autotune
constexpr uint16_t VP_PID_AUTOTUNE_E0 = 0x2410;
//constexpr uint16_t VP_PID_AUTOTUNE_E1 = 0x2412;
//constexpr uint16_t VP_PID_AUTOTUNE_E2 = 0x2414;
//constexpr uint16_t VP_PID_AUTOTUNE_E3 = 0x2416;
//constexpr uint16_t VP_PID_AUTOTUNE_E4 = 0x2418;
//constexpr uint16_t VP_PID_AUTOTUNE_E5 = 0x241A;
constexpr uint16_t VP_PID_AUTOTUNE_BED = 0x2420;
// Firmware version on the boot screen.
constexpr uint16_t VP_MARLIN_VERSION = 0x3000;
constexpr uint8_t VP_MARLIN_VERSION_LEN = 16; // there is more space on the display, if needed.
// Place for status messages.
constexpr uint16_t VP_M117 = 0x3020;
constexpr uint8_t VP_M117_LEN = 0x20;
// Temperatures.
constexpr uint16_t VP_T_E0_Is = 0x3060; // 4 Byte Integer
constexpr uint16_t VP_T_E0_Set = 0x3062; // 2 Byte Integer
constexpr uint16_t VP_T_E1_Is = 0x3064; // 4 Byte Integer
// reserved to support up to 6 Extruders:
//constexpr uint16_t VP_T_E1_Set = 0x3066; // 2 Byte Integer
//constexpr uint16_t VP_T_E2_Is = 0x3068; // 4 Byte Integer
//constexpr uint16_t VP_T_E2_Set = 0x306A; // 2 Byte Integer
//constexpr uint16_t VP_T_E3_Is = 0x306C; // 4 Byte Integer
//constexpr uint16_t VP_T_E3_Set = 0x306E; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3070; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3072; // 2 Byte Integer
//constexpr uint16_t VP_T_E4_Is = 0x3074; // 4 Byte Integer
//constexpr uint16_t VP_T_E4_Set = 0x3076; // 2 Byte Integer
//constexpr uint16_t VP_T_E5_Is = 0x3078; // 4 Byte Integer
//constexpr uint16_t VP_T_E5_Set = 0x307A; // 2 Byte Integer
constexpr uint16_t VP_T_Bed_Is = 0x3080; // 4 Byte Integer
constexpr uint16_t VP_T_Bed_Set = 0x3082; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E0 = 0x3090; // 2 Byte Integer
constexpr uint16_t VP_Flowrate_E1 = 0x3092; // 2 Byte Integer
// reserved for up to 6 Extruders:
//constexpr uint16_t VP_Flowrate_E2 = 0x3094;
//constexpr uint16_t VP_Flowrate_E3 = 0x3096;
//constexpr uint16_t VP_Flowrate_E4 = 0x3098;
//constexpr uint16_t VP_Flowrate_E5 = 0x309A;
constexpr uint16_t VP_Fan0_Percentage = 0x3100; // 2 Byte Integer (0..100)
//constexpr uint16_t VP_Fan1_Percentage = 0x33A2; // 2 Byte Integer (0..100)
//constexpr uint16_t VP_Fan2_Percentage = 0x33A4; // 2 Byte Integer (0..100)
//constexpr uint16_t VP_Fan3_Percentage = 0x33A6; // 2 Byte Integer (0..100)
constexpr uint16_t VP_Feedrate_Percentage = 0x3102; // 2 Byte Integer (0..100)
constexpr uint16_t VP_PrintProgress_Percentage = 0x3104; // 2 Byte Integer (0..100)
constexpr uint16_t VP_PrintTime = 0x3106;
constexpr uint16_t VP_PrintTime_LEN = 10;
constexpr uint16_t VP_PrintAccTime = 0x3160;
constexpr uint16_t VP_PrintAccTime_LEN = 32;
constexpr uint16_t VP_PrintsTotal = 0x3180;
constexpr uint16_t VP_PrintsTotal_LEN = 16;
// Actual Position
constexpr uint16_t VP_XPos = 0x3110; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_YPos = 0x3112; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_ZPos = 0x3114; // 4 Byte Fixed point number; format xxx.yy
constexpr uint16_t VP_EPos = 0x3120; // 4 Byte Fixed point number; format xxx.yy
// SDCard File Listing
constexpr uint16_t VP_SD_FileName_LEN = 32; // LEN is shared for all entries.
constexpr uint16_t DGUS_SD_FILESPERSCREEN = 5; // FIXME move that info to the display and read it from there.
constexpr uint16_t VP_SD_FileName0 = 0x3200;
constexpr uint16_t VP_SD_FileName1 = 0x3220;
constexpr uint16_t VP_SD_FileName2 = 0x3240;
constexpr uint16_t VP_SD_FileName3 = 0x3260;
constexpr uint16_t VP_SD_FileName4 = 0x3280;
constexpr uint16_t VP_SD_Print_ProbeOffsetZ = 0x32A0; //
constexpr uint16_t VP_SD_Print_Filename = 0x32C0; //
// Fan status
constexpr uint16_t VP_FAN0_STATUS = 0x3300;
constexpr uint16_t VP_FAN1_STATUS = 0x3302;
//constexpr uint16_t VP_FAN2_STATUS = 0x3304;
//constexpr uint16_t VP_FAN3_STATUS = 0x3306;
// Heater status
constexpr uint16_t VP_E0_STATUS = 0x3310;
//constexpr uint16_t VP_E1_STATUS = 0x3312;
//constexpr uint16_t VP_E2_STATUS = 0x3314;
//constexpr uint16_t VP_E3_STATUS = 0x3316;
//constexpr uint16_t VP_E4_STATUS = 0x3318;
//constexpr uint16_t VP_E5_STATUS = 0x331A;
constexpr uint16_t VP_BED_STATUS = 0x331C;
constexpr uint16_t VP_MOVE_OPTION = 0x3400;
// Step per mm
constexpr uint16_t VP_X_STEP_PER_MM = 0x3600; // at the moment , 2 byte unsigned int , 0~1638.4
//constexpr uint16_t VP_X2_STEP_PER_MM = 0x3602;
constexpr uint16_t VP_Y_STEP_PER_MM = 0x3604;
//constexpr uint16_t VP_Y2_STEP_PER_MM = 0x3606;
constexpr uint16_t VP_Z_STEP_PER_MM = 0x3608;
//constexpr uint16_t VP_Z2_STEP_PER_MM = 0x360A;
constexpr uint16_t VP_E0_STEP_PER_MM = 0x3610;
//constexpr uint16_t VP_E1_STEP_PER_MM = 0x3612;
//constexpr uint16_t VP_E2_STEP_PER_MM = 0x3614;
//constexpr uint16_t VP_E3_STEP_PER_MM = 0x3616;
//constexpr uint16_t VP_E4_STEP_PER_MM = 0x3618;
//constexpr uint16_t VP_E5_STEP_PER_MM = 0x361A;
// PIDs
constexpr uint16_t VP_E0_PID_P = 0x3700; // at the moment , 2 byte unsigned int , 0~1638.4
constexpr uint16_t VP_E0_PID_I = 0x3702;
constexpr uint16_t VP_E0_PID_D = 0x3704;
constexpr uint16_t VP_BED_PID_P = 0x3710;
constexpr uint16_t VP_BED_PID_I = 0x3712;
constexpr uint16_t VP_BED_PID_D = 0x3714;
// Wating screen status
constexpr uint16_t VP_WAITING_STATUS = 0x3800;
// SPs for certain variables...
// located at 0x5000 and up
// Not used yet!
// This can be used e.g to make controls / data display invisible
constexpr uint16_t SP_T_E0_Is = 0x5000;
constexpr uint16_t SP_T_E0_Set = 0x5010;
constexpr uint16_t SP_T_E1_Is = 0x5020;
constexpr uint16_t SP_T_Bed_Is = 0x5030;
constexpr uint16_t SP_T_Bed_Set = 0x5040;

View File

@ -0,0 +1,559 @@
/*********************
* flash_storage.cpp *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../compat.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "../ftdi_eve_lib/ftdi_eve_lib.h"
#include "media_file_reader.h"
#include "flash_storage.h"
// The following must be changed whenever the layout of the flash
// data is changed in a manner that would render the data invalid.
constexpr uint32_t flash_eeprom_version = 1;
/* SPI Flash Memory Map:
*
* The following offsets and sizes are specified in 4k erase units:
*
* Page Size Description
* 0 16 DATA STORAGE AREA
* 16 1 VERSIONING DATA
* 17 inf MEDIA STORAGE AREA
*
*/
#define DATA_STORAGE_SIZE_64K
using namespace FTDI::SPI;
using namespace FTDI::SPI::most_significant_byte_first;
bool UIFlashStorage::is_present = false;
#ifdef SPI_FLASH_SS
/************************** SPI Flash Chip Interface **************************/
void SPIFlash::wait_while_busy() {
uint8_t status;
safe_delay(1);
do {
spi_flash_select();
spi_write_8(READ_STATUS_1);
status = spi_read_8();
spi_flash_deselect();
safe_delay(1);
} while (status & 1);
}
void SPIFlash::erase_sector_4k(uint32_t addr) {
spi_flash_select();
spi_write_8(WRITE_ENABLE);
spi_flash_deselect();
spi_flash_select();
spi_write_8(ERASE_4K);
spi_write_24(addr);
spi_flash_deselect();
wait_while_busy();
}
void SPIFlash::erase_sector_64k(uint32_t addr) {
spi_flash_select();
spi_write_8(WRITE_ENABLE);
spi_flash_deselect();
spi_flash_select();
spi_write_8(ERASE_64K);
spi_write_24(addr);
spi_flash_deselect();
wait_while_busy();
}
void SPIFlash::spi_write_begin(uint32_t addr) {
spi_flash_select();
spi_write_8(WRITE_ENABLE);
spi_flash_deselect();
spi_flash_select();
spi_write_8(PAGE_PROGRAM);
spi_write_24(addr);
}
void SPIFlash::spi_write_end() {
spi_flash_deselect();
wait_while_busy();
}
void SPIFlash::spi_read_begin(uint32_t addr) {
spi_flash_select();
spi_write_8(READ_DATA);
spi_write_24(addr);
}
void SPIFlash::spi_read_end() {
spi_flash_deselect();
}
void SPIFlash::erase_chip() {
spi_flash_select();
spi_write_8(WRITE_ENABLE);
spi_flash_deselect();
spi_flash_select();
spi_write_8(ERASE_CHIP);
spi_flash_deselect();
wait_while_busy();
}
void SPIFlash::read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity) {
spi_flash_select();
spi_write_8(READ_JEDEC_ID);
manufacturer_id = spi_recv();
device_type = spi_recv();
capacity = spi_recv();
spi_flash_deselect ();
}
/* This function writes "size" bytes from "data" starting at addr, while properly
* taking into account the special case of writing across a 256 byte page boundary.
* Returns the addr directly after the write.
*/
uint32_t SPIFlash::write(uint32_t addr, const void *_data, size_t size) {
const uint8_t *data = (const uint8_t*) _data;
while (size) {
const uint32_t page_start = addr & 0xFFFF00ul;
const uint32_t page_end = page_start + 256;
const uint32_t write_size = min(page_end - addr, size);
spi_write_begin(addr);
spi_write_bulk<ram_write>(data, write_size);
spi_write_end();
addr += write_size;
size -= write_size;
data += write_size;
}
return addr;
}
uint32_t SPIFlash::read(uint32_t addr, void *data, size_t size) {
spi_read_begin(addr);
spi_read_bulk(data, size);
spi_read_end();
return addr + size;
}
/********************************** UTILITY ROUTINES *********************************/
bool UIFlashStorage::check_known_device() {
uint8_t manufacturer_id, device_type, capacity;
read_jedec_id(manufacturer_id, device_type, capacity);
const bool is_known =
((manufacturer_id == 0xEF) && (device_type == 0x40) && (capacity == 0x15)) || // unknown
((manufacturer_id == 0x01) && (device_type == 0x40) && (capacity == 0x15)) || // Cypress S25FL116K
((manufacturer_id == 0xEF) && (device_type == 0x14) && (capacity == 0x15)) || // Winbond W25Q16JV
((manufacturer_id == 0x1F) && (device_type == 0x86) && (capacity == 0x01)) ; // Adesto AT255F161
if (!is_known) {
SERIAL_ECHO_MSG("Unable to locate supported SPI Flash Memory.");
SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(" Manufacturer ID, got: ", manufacturer_id);
SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(" Device Type , got: ", device_type);
SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(" Capacity , got: ", capacity);
}
return is_known;
}
void UIFlashStorage::initialize() {
for(uint8_t i = 0; i < 10; i++) {
if (check_known_device()) {
is_present = true;
break;
}
safe_delay(1000);
}
}
/**************************** DATA STORAGE AREA (first 4K or 64k) ********************/
#ifdef DATA_STORAGE_SIZE_64K
constexpr uint32_t data_storage_area_size = 64 * 1024; // Large erase unit
#else
constexpr uint32_t data_storage_area_size = 4 * 1024; // Small erase unit
#endif
/* In order to provide some degree of wear leveling, each data write to the
* SPI Flash chip is appended to data that was already written before, until
* the data storage area is completely filled. New data is written preceeded
* with a 32-bit delimiter 'LULZ', so that we can distinguish written and
* unwritten data:
*
* 'LULZ' <--- 1st record delimiter
* <data_byte>
* <data_byte>
* <data_byte>
* 'LULZ' <--- 2nd record delimiter
* <data_byte>
* <data_byte>
* <data_byte>
* ...
* 'LULZ' <--- Last record delimiter
* <data_byte>
* <data_byte>
* <data_byte>
* 0xFF <--- Start of free space
* 0xFF
* ...
*
* This function walks down the data storage area, verifying that the
* delimiters are either 'LULZ' or 0xFFFFFFFF. In the case that an invalid
* delimiter is found, this function returns -1, indicating that the Flash
* data is invalid (this will happen if the block_size changed with respect
* to earlier firmware). Otherwise, it returns the offset of the last
* valid delimiter 'LULZ', indicating the most recently written data.
*/
int32_t UIFlashStorage::get_config_read_offset(uint32_t block_size) {
uint16_t stride = 4 + block_size;
int32_t read_offset = -1;
for(uint32_t offset = 0; offset < (data_storage_area_size - stride); offset += stride) {
uint32_t delim;
spi_read_begin(offset);
spi_read_bulk (&delim, sizeof(delim));
spi_read_end();
switch (delim) {
case 0xFFFFFFFFul: return read_offset;
case delimiter: read_offset = offset; break;
default:
SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Invalid delimiter in Flash: ", delim);
return -1;
}
}
SERIAL_ECHO_MSG("No LULZ delimiter found.");
return -1;
}
/* This function returns the offset at which new data should be
* appended, or -1 if the Flash needs to be erased */
int32_t UIFlashStorage::get_config_write_offset(uint32_t block_size) {
int32_t read_offset = get_config_read_offset(block_size);
if (read_offset == -1) return -1; // The SPI flash is invalid
int32_t write_offset = read_offset + 4 + block_size;
if ((write_offset + 4 + block_size) > data_storage_area_size) {
SERIAL_ECHO_MSG("Not enough free space in Flash.");
return -1; // Not enough free space
}
return write_offset;
}
bool UIFlashStorage::verify_config_data(const void *data, size_t size) {
if (!is_present) return false;
int32_t read_addr = get_config_read_offset(size);
if (read_addr == -1) return false;
uint32_t delim;
spi_read_begin(read_addr);
spi_read_bulk (&delim, sizeof(delim));
bool ok = spi_verify_bulk(data,size);
spi_read_end();
return ok && delim == delimiter;
}
bool UIFlashStorage::read_config_data(void *data, size_t size) {
if (!is_present) return false;
int32_t read_addr = get_config_read_offset(size);
if (read_addr == -1) return false;
uint32_t delim;
spi_read_begin(read_addr);
spi_read_bulk (&delim, sizeof(delim));
spi_read_bulk (data, size);
spi_read_end();
return delim == delimiter;
}
void UIFlashStorage::write_config_data(const void *data, size_t size) {
if (!is_present) {
SERIAL_ECHO_MSG("SPI Flash chip not present. Not saving UI settings.");
return;
}
// Since Flash storage has a limited number of write cycles,
// make sure that the data is different before rewriting.
if (verify_config_data(data, size)) {
SERIAL_ECHO_MSG("UI settings already written, skipping write.");
return;
}
int16_t write_addr = get_config_write_offset(size);
if (write_addr == -1) {
SERIAL_ECHO_START();
SERIAL_ECHOPGM("Erasing UI settings from SPI Flash... ");
#ifdef DATA_STORAGE_SIZE_64K
erase_sector_64k(0);
#else
erase_sector_4k(0);
#endif
write_addr = 0;
SERIAL_ECHOLNPGM("DONE");
}
SERIAL_ECHO_START();
SERIAL_ECHOPAIR("Writing UI settings to SPI Flash (offset ", write_addr);
SERIAL_ECHOPGM(")...");
const uint32_t delim = delimiter;
write_addr = write(write_addr, &delim, sizeof(delim));
write_addr = write(write_addr, data, size);
SERIAL_ECHOLNPGM("DONE");
}
/************************** VERSIONING INFO AREA ************************/
/* The version info area follows the data storage area. If the version
* is incorrect, the data on the chip is invalid and format_flash should
* be called.
*/
typedef struct {
uint32_t magic;
uint32_t version;
} flash_version_info;
constexpr uint32_t version_info_addr = data_storage_area_size;
constexpr uint32_t version_info_size = 4 * 1024; // Small erase unit
bool UIFlashStorage::is_valid() {
flash_version_info info;
spi_read_begin(version_info_addr);
spi_read_bulk (&info, sizeof(flash_version_info));
spi_read_end();
return info.magic == delimiter && info.version == flash_eeprom_version;
}
void UIFlashStorage::write_version_info() {
flash_version_info info;
info.magic = delimiter;
info.version = flash_eeprom_version;
spi_write_begin(version_info_addr);
spi_write_bulk<ram_write>(&info, sizeof(flash_version_info));
spi_write_end();
}
/**************************** MEDIA STORAGE AREA *****************************/
/* The media storage area follows the versioning info area. It consists
* of a file index followed by the data for one or more media files.
*
* The file index consists of an array of 32-bit file sizes. If a file
* is not present, the file's size will be set to 0xFFFFFFFF
*/
constexpr uint32_t media_storage_addr = version_info_addr + version_info_size;
constexpr uint8_t media_storage_slots = 4;
void UIFlashStorage::format_flash() {
SERIAL_ECHO_START(); SERIAL_ECHOPGM("Erasing SPI Flash...");
SPIFlash::erase_chip();
SERIAL_ECHOLNPGM("DONE");
write_version_info();
}
uint32_t UIFlashStorage::get_media_file_start(uint8_t slot) {
uint32_t addr = media_storage_addr + sizeof(uint32_t) * media_storage_slots;
spi_read_begin(media_storage_addr);
for(uint8_t i = 0; i < slot; i++) {
addr += spi_read_32();
}
spi_read_end();
return addr;
}
void UIFlashStorage::set_media_file_size(uint8_t slot, uint32_t size) {
spi_write_begin(media_storage_addr + sizeof(uint32_t) * slot);
spi_write_32(size);
spi_write_end();
}
uint32_t UIFlashStorage::get_media_file_size(uint8_t slot) {
spi_read_begin(media_storage_addr + sizeof(uint32_t) * slot);
uint32_t size = spi_read_32();
spi_read_end();
return size;
}
/* Writes a media file from the SD card/USB flash drive into a slot on the SPI Flash. Media
* files must be written sequentially following by a chip erase and it is not possible to
* overwrite files. */
UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str filename, uint8_t slot) {
#if ENABLED(SDSUPPORT)
uint32_t addr;
uint8_t buff[write_page_size];
strcpy_P( (char*) buff, (const char*) filename);
MediaFileReader reader;
if (!reader.open((char*) buff)) {
SERIAL_ECHO_MSG("Unable to find media file");
return FILE_NOT_FOUND;
}
if (get_media_file_size(slot) != 0xFFFFFFFFUL) {
SERIAL_ECHO_MSG("Media file already exists");
return WOULD_OVERWRITE;
}
SERIAL_ECHO_START(); SERIAL_ECHOPGM("Writing SPI Flash...");
set_media_file_size(slot, reader.size());
addr = get_media_file_start(slot);
// Write out the file itself
for(;;) {
const int16_t nBytes = reader.read(buff, write_page_size);
if (nBytes == -1) {
SERIAL_ECHOLNPGM("Failed to read from file");
return READ_ERROR;
}
addr = write(addr, buff, nBytes);
if (nBytes != write_page_size)
break;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::yield();
#endif
}
SERIAL_ECHOLNPGM("DONE");
SERIAL_ECHO_START(); SERIAL_ECHOPGM("Verifying SPI Flash...");
bool verifyOk = true;
// Verify the file index
if (get_media_file_start(slot+1) != (get_media_file_start(slot) + reader.size())) {
SERIAL_ECHOLNPGM("File index verification failed. ");
verifyOk = false;
}
// Verify the file itself
addr = get_media_file_start(slot);
reader.rewind();
while (verifyOk) {
const int16_t nBytes = reader.read(buff, write_page_size);
if (nBytes == -1) {
SERIAL_ECHOPGM("Failed to read from file");
verifyOk = false;
break;
}
spi_read_begin(addr);
if (!spi_verify_bulk(buff, nBytes)) {
verifyOk = false;
spi_read_end();
break;
}
spi_read_end();
addr += nBytes;
if (nBytes != write_page_size) break;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::yield();
#endif
};
if (verifyOk) {
SERIAL_ECHOLNPGM("DONE");
return SUCCESS;
} else {
SERIAL_ECHOLNPGM("FAIL");
return VERIFY_ERROR;
}
#else
return VERIFY_ERROR;
#endif // ENABLED(SDSUPPORT)
}
bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t slot) {
if (!is_present) return false;
bytes_remaining = get_media_file_size(slot);
if (bytes_remaining != 0xFFFFFFFFUL) {
SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR("Boot media file size:", bytes_remaining);
addr = get_media_file_start(slot);
return true;
}
return false;
}
int16_t UIFlashStorage::BootMediaReader::read(void *data, const size_t size) {
if (bytes_remaining == 0xFFFFFFFFUL) return -1;
if (size > bytes_remaining)
return read(data, bytes_remaining);
if (size > 0) {
spi_read_begin(addr);
spi_read_bulk(data, size);
spi_read_end();
addr += size;
bytes_remaining -= size;
}
return size;
}
int16_t UIFlashStorage::BootMediaReader::read(void *obj, void *data, const size_t size) {
return reinterpret_cast<UIFlashStorage::BootMediaReader*>(obj)->read(data, size);
}
#else
void UIFlashStorage::initialize() {}
bool UIFlashStorage::is_valid() {return true;}
void UIFlashStorage::write_config_data(const void *, size_t) {}
bool UIFlashStorage::verify_config_data(const void *, size_t) {return false;}
bool UIFlashStorage::read_config_data(void *, size_t ) {return false;}
UIFlashStorage::error_t UIFlashStorage::write_media_file(progmem_str, uint8_t) {return FILE_NOT_FOUND;}
void UIFlashStorage::format_flash() {}
bool UIFlashStorage::BootMediaReader::isAvailable(uint32_t) {return false;}
int16_t UIFlashStorage::BootMediaReader::read(void *, const size_t) {return -1;}
int16_t UIFlashStorage::BootMediaReader::read(void *, void *, const size_t) {return -1;}
#endif // SPI_FLASH_SS
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,106 @@
/*******************
* flash_storage.h *
*******************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
class SPIFlash {
public:
static constexpr uint32_t erase_unit_size = 4 * 1024; // Minimum erase unit
static constexpr uint32_t write_page_size = 256; // Minimum page write unit
enum {
READ_STATUS_1 = 0x05,
READ_STATUS_2 = 0x35,
READ_STATUS_3 = 0x33,
WRITE_ENABLE = 0x06,
WRITE_DISABLE = 0x04,
READ_ID = 0x90,
READ_JEDEC_ID = 0x9F,
READ_DATA = 0x03,
PAGE_PROGRAM = 0x02,
ERASE_4K = 0x20,
ERASE_64K = 0xD8,
ERASE_CHIP = 0xC7
};
static void wait_while_busy();
static void erase_sector_4k(uint32_t addr);
static void erase_sector_64k(uint32_t addr);
static void erase_chip ();
static void read_jedec_id(uint8_t &manufacturer_id, uint8_t &device_type, uint8_t &capacity);
static void spi_read_begin(uint32_t addr);
static void spi_read_end();
static void spi_write_begin(uint32_t addr);
static void spi_write_end();
static uint32_t write(uint32_t addr, const void *data, size_t size);
static uint32_t read(uint32_t addr, void *data, size_t size);
};
class UIFlashStorage : private SPIFlash {
private:
static bool is_present;
static int32_t get_config_read_offset(uint32_t block_size);
static int32_t get_config_write_offset(uint32_t block_size);
static uint32_t get_media_file_start(uint8_t slot);
static void set_media_file_size(uint8_t slot, uint32_t size);
static uint32_t get_media_file_size(uint8_t slot);
static constexpr uint32_t delimiter = 0x4D524C4E; // 'MRLN'
public:
enum error_t {
SUCCESS,
FILE_NOT_FOUND,
READ_ERROR,
VERIFY_ERROR,
WOULD_OVERWRITE
};
static void initialize ();
static void format_flash ();
static bool check_known_device();
static bool is_valid ();
static void write_version_info();
static void write_config_data (const void *data, size_t size);
static bool verify_config_data (const void *data, size_t size);
static bool read_config_data (void *data, size_t size);
static error_t write_media_file (progmem_str filename, uint8_t slot = 0);
class BootMediaReader;
};
class UIFlashStorage::BootMediaReader {
private:
uint32_t addr;
uint32_t bytes_remaining;
public:
bool isAvailable(uint32_t slot = 0);
int16_t read(void *buffer, size_t const size);
static int16_t read(void *obj, void *buffer, const size_t size);
};

View File

@ -0,0 +1,63 @@
/************************
* media_filereader.cpp *
************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../compat.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "media_file_reader.h"
#if ENABLED(SDSUPPORT)
bool MediaFileReader::open(const char* filename) {
card.init(SPI_SPEED, SDSS);
volume.init(&card);
root.openRoot(&volume);
return file.open(&root, filename, O_READ);
}
int16_t MediaFileReader::read(void *buff, size_t bytes) {
return file.read(buff, bytes);
}
void MediaFileReader::close() {
file.close();
}
uint32_t MediaFileReader::size() {
return file.fileSize();
}
void MediaFileReader::rewind() {
file.rewind();
}
int16_t MediaFileReader::read(void *obj, void *buff, size_t bytes) {
return reinterpret_cast<MediaFileReader*>(obj)->read(buff, bytes);
}
#else
bool MediaFileReader::open(const char*) {return -1;}
int16_t MediaFileReader::read(void *, size_t) {return 0;}
void MediaFileReader::close() {}
uint32_t MediaFileReader::size() {return 0;}
void MediaFileReader::rewind() {}
int16_t MediaFileReader::read(void *, void *, size_t) {return 0;}
#endif
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,48 @@
/**********************
* media_filereader.h *
**********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "../../../../../inc/MarlinConfigPre.h"
#if ENABLED(SDSUPPORT)
#include "../../../../../sd/SdFile.h"
#include "../../../../../sd/cardreader.h"
#endif
class MediaFileReader {
private:
#if ENABLED(SDSUPPORT)
Sd2Card card;
SdVolume volume;
SdFile root, file;
#endif
public:
bool open(const char* filename);
int16_t read(void *buff, size_t bytes);
uint32_t size();
void rewind();
void close();
static int16_t read(void *obj, void *buff, size_t bytes);
};

View File

@ -0,0 +1,52 @@
/************
* compat.h *
************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/**
* This following provides compatibility whether compiling
* as a part of Marlin or outside it
*/
#ifdef __has_include
#if __has_include("../../ui_api.h")
#include "../../ui_api.h"
#endif
#else
#include "../../ui_api.h"
#endif
#ifdef __MARLIN_FIRMWARE__
// __MARLIN_FIRMWARE__ exists when compiled within Marlin.
#include "pin_mappings.h"
#undef max
#define max(a,b) ((a)>(b)?(a):(b))
#undef min
#define min(a,b) ((a)<(b)?(a):(b))
#else
namespace UI {
static inline uint32_t safe_millis() {return millis();};
static inline void yield() {};
};
#endif
class __FlashStringHelper;
typedef const __FlashStringHelper *progmem_str;

View File

@ -0,0 +1,124 @@
/************
* config.h *
************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "compat.h"
// Define the display board used (see "ftdi_eve_boards.h" for definitions)
//#define LCD_FTDI_VM800B35A // FTDI 3.5" 320x240 with FT800
//#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" 480x272
//#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" 480x272
//#define LCD_HAOYU_FT810CB // Haoyu with 5" 800x480
//#define LCD_ALEPHOBJECTS_CLCD_UI // Aleph Objects Color LCD User Interface
// Leave the following commented out to use a board's default resolution.
// If you have changed the LCD panel, you may override the resolution
// below (see "ftdi_eve_resolutions.h" for definitions):
//#define TOUCH_UI_320x240
//#define TOUCH_UI_480x272
//#define TOUCH_UI_800x480
// Define the printer interface or pins used (see "ui_pin_mappings.h" for definitions):
//#define CR10_TFT_PINMAP
//#define AO_EXP1_DEPRECATED_PINMAP // UltraLCD EXP1 connector, old AlephObject's wiring
//#define AO_EXP1_PINMAP // UltraLCD EXP1 connector, new AlephObject's wiring
//#define AO_EXP2_PINMAP // UltraLCD EXP2 connector, new AlephObject's wiring
//#define OTHER_PIN_LAYOUT
// Otherwise. Define all the pins manually:
#ifdef OTHER_PIN_LAYOUT
// Select interfacing pins, the following pin specifiers are supported:
//
// ARDUINO_DIGITAL_1 - Arduino pin via digitalWrite/digitalRead
// AVR_A1 - Fast AVR port access via PORTA/PINA/DDRA
// 1 - When compiling Marlin, use Marlin pin IDs.
// The pins for CS and MOD_RESET (PD) must be chosen.
#define CLCD_MOD_RESET 9
#define CLCD_SPI_CS 10
// If using software SPI, specify pins for SCLK, MOSI, MISO
//#define CLCD_USE_SOFT_SPI
#ifdef CLCD_USE_SOFT_SPI
#define CLCD_SOFT_SPI_MOSI 11
#define CLCD_SOFT_SPI_MISO 12
#define CLCD_SOFT_SPI_SCLK 13
#endif
#endif
// Defines how to orient the display. An inverted (i.e. upside-down) display
// is supported on the FT800. The FT810 or better also support a portrait
// and mirrored orientation.
//#define TOUCH_UI_INVERTED
//#define TOUCH_UI_PORTRAIT
//#define TOUCH_UI_MIRRORED
// Enable UTF8 processing and rendering. Unsupported characters
// will be shown as '?'.
//#define TOUCH_UI_USE_UTF8
#ifdef TOUCH_UI_USE_UTF8
// Western accents support. These accented characters use
// combined bitmaps and require relatively little storage.
#define TOUCH_UI_UTF8_WESTERN_CHARSET
#ifdef TOUCH_UI_UTF8_WESTERN_CHARSET
// Additional character groups. These characters require
// full bitmaps and take up considerable storage:
//#define TOUCH_UI_UTF8_SUPERSCRIPTS // ¹ ² ³
//#define TOUCH_UI_UTF8_COPYRIGHT // © ®
//#define TOUCH_UI_UTF8_GERMANIC // ß
//#define TOUCH_UI_UTF8_SCANDINAVIAN // Æ Ð Ø Þ æ ð ø þ
//#define TOUCH_UI_UTF8_PUNCTUATION // « » ¿ ¡
//#define TOUCH_UI_UTF8_CURRENCY // ¢ £ ¤ ¥
//#define TOUCH_UI_UTF8_ORDINALS // º ª
//#define TOUCH_UI_UTF8_MATHEMATICS // ± × ÷
//#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾
//#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬
#endif
#endif
// When labels do not fit buttons, use smaller font
//#define TOUCH_UI_FIT_TEXT
// Enable support for selection of languages at run-time
// (otherwise will use the value of LCD_LANGUAGE)
//#define TOUCH_UI_LANGUAGE_MENU
// Use a numeric passcode for "Parental lock".
// This is a recommended for smaller displays.
//#define TOUCH_UI_PASSCODE
// The timeout (in ms) to return to the status screen from sub-menus
//#define LCD_TIMEOUT_TO_STATUS 15000
// Enable this to debug the event framework
//#define TOUCH_UI_DEBUG
// Enable the developer's menu and screens
//#define DEVELOPER_SCREENS
// Sets the SPI speed in Hz
#define SPI_FREQUENCY 8000000 >> SPI_SPEED

View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -0,0 +1,28 @@
FTDI EVE Library
----------------
The FTDI EVE Library is a fully open-source library and UI framework for the FTDI
FT800 and FT810 graphics processor.
Although the library has been developed within Lulzbot for providing a user interface
for Marlin, the library has been written so that it can be used in any Arduino sketch.
The library is split into two parts. The "basic" API provides a shallow interface to
the underlying FTDI hardware and command FIFO and provides low-level access to the
hardware as closely as possible to the API described in the FTDI Programmer's Guide.
The "extended" API builds on top of the "basic" API to provide a GUI framework for
handling common challenges in building a usable GUI. The GUI framework provides the
following features:
- Macros for a resolution-independent placement of widgets based on a grid.
- Class-based UI screens, with press and unpress touch events, as well as touch repeat.
- Event loop with button debouncing and button push visual and auditory feedback.
- Easy screen-to-screen navigation including a navigation stack for going backwards.
- Visual feedback for disabled vs enabled buttons, and custom button styles.
- A sound player class for playing individual notes or complete sound sequences.
- Display list caching, for storing static background elements of a screen in RAM_G.
See the "examples" folder for Arduino sketches. Modify the "src/config.h" file in
each to suit your particular setup. The "sample_configs" contain sample configuration
files for running the sketches on our 3D printer boards.

View File

@ -0,0 +1,183 @@
/************
* boards.h *
************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#define HAS_RESOLUTION (defined(TOUCH_UI_320x240) || defined(TOUCH_UI_480x272) || defined(TOUCH_UI_800x480))
#define IS_FT800 \
constexpr uint16_t ftdi_chip = 800; \
using namespace FTDI_FT800; \
namespace DL { \
using namespace FTDI_FT800_DL; \
} \
typedef ft800_memory_map ftdi_memory_map; \
typedef ft800_registers ftdi_registers;
#define IS_FT810 \
constexpr uint16_t ftdi_chip = 810; \
using namespace FTDI_FT810; \
namespace DL { \
using namespace FTDI_FT800_DL; \
using namespace FTDI_FT810_DL; \
} \
typedef ft810_memory_map ftdi_memory_map; \
typedef ft810_registers ftdi_registers;
#ifdef LCD_FTDI_VM800B35A
#if !HAS_RESOLUTION
#define TOUCH_UI_320x240
#endif
#ifndef FTDI_API_LEVEL
#define FTDI_API_LEVEL 800
#endif
namespace FTDI {
IS_FT800
constexpr bool Use_Crystal = true; // 0 = use internal oscillator, 1 = module has a crystal populated
constexpr bool GPIO_0_Audio_Enable = false; /* 1 = does use GPIO00 for amplifier control, 0 = not in use for Audio */
constexpr bool GPIO_1_Audio_Shutdown = true; /* 1 = does use GPIO01 for amplifier control, 0 = not in use for Audio */
constexpr uint8_t Swizzle = 2;
constexpr uint8_t CSpread = 1;
constexpr uint16_t touch_threshold = 1200; /* touch-sensitivity */
}
/*
* Settings for the Haoyu Electronics, 4.3" Graphical LCD Touchscreen, 480x272, SPI, FT800 (FT800CB-HY43B)
* Haoyu Electronics, 5" Graphical LCD Touchscreen, 480x272, SPI, FT800 (FT800CB-HY50B)
*
* http://www.hotmcu.com/43-graphical-lcd-touchscreen-480x272-spi-ft800-p-111.html?cPath=6_16
* http://www.hotmcu.com/5-graphical-lcd-touchscreen-480x272-spi-ft800-p-124.html?cPath=6_16
*
* Datasheet:
*
* http://www.hantronix.com/files/data/1278363262430-3.pdf
* http://www.haoyuelectronics.com/Attachment/HY43-LCD/LCD%20DataSheet.pdf
* http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
*
*/
#elif defined(LCD_HAOYU_FT800CB)
#if !HAS_RESOLUTION
#define TOUCH_UI_480x272
#endif
#ifndef FTDI_API_LEVEL
#define FTDI_API_LEVEL 800
#endif
namespace FTDI {
IS_FT800
constexpr bool Use_Crystal = true; // 0 = use internal oscillator, 1 = module has a crystal populated
constexpr bool GPIO_0_Audio_Enable = false;
constexpr bool GPIO_1_Audio_Shutdown = false;
constexpr uint8_t Swizzle = 0;
constexpr uint8_t CSpread = 1;
constexpr uint16_t touch_threshold = 2000; /* touch-sensitivity */
}
/*
* Settings for the Haoyu Electronics, 5" Graphical LCD Touchscreen, 800x480, SPI, FT810
*
* http://www.hotmcu.com/5-graphical-lcd-touchscreen-800x480-spi-ft810-p-286.html
*
* Datasheet:
*
* http://www.haoyuelectronics.com/Attachment/HY5-LCD-HD/KD50G21-40NT-A1.pdf
*
*/
#elif defined(LCD_HAOYU_FT810CB)
#if !HAS_RESOLUTION
#define TOUCH_UI_800x480
#endif
#ifndef FTDI_API_LEVEL
#define FTDI_API_LEVEL 810
#endif
namespace FTDI {
IS_FT810
constexpr bool Use_Crystal = true; // 0 = use internal oscillator, 1 = module has a crystal populated
constexpr bool GPIO_0_Audio_Enable = false;
constexpr bool GPIO_1_Audio_Shutdown = false;
constexpr uint8_t Swizzle = 0;
constexpr uint8_t CSpread = 1;
constexpr uint16_t touch_threshold = 2000; /* touch-sensitivity */
}
/*
* Settings for the 4D Systems, 4.3" Embedded SPI Display 480x272, SPI, FT800 (4DLCD-FT843)
*
* http://www.4dsystems.com.au/product/4DLCD_FT843/
*
* Datasheet:
*
* http://www.4dsystems.com.au/productpages/4DLCD-FT843/downloads/FT843-4.3-Display_datasheet_R_1_2.pdf
*
*/
#elif defined(LCD_4DSYSTEMS_4DLCD_FT843)
#if !HAS_RESOLUTION
#define TOUCH_UI_480x272
#endif
#ifndef FTDI_API_LEVEL
#define FTDI_API_LEVEL 800
#endif
namespace FTDI {
IS_FT800
constexpr bool Use_Crystal = true; // 0 = use internal oscillator, 1 = module has a crystal populated
constexpr bool GPIO_0_Audio_Enable = false;
constexpr bool GPIO_1_Audio_Shutdown = true;
constexpr uint8_t Swizzle = 0;
constexpr uint8_t CSpread = 1;
constexpr uint16_t touch_threshold = 1200; /* touch-sensitivity */
}
/*
* Settings for the Aleph Objects Color LCD User Interface
*
* https://code.alephobjects.com/source/aotctl/
*
* Datasheet:
*
* http://www.hantronix.com/files/data/s1501799605s500-gh7.pdf
*
*/
#elif defined(LCD_ALEPHOBJECTS_CLCD_UI)
#if !HAS_RESOLUTION
#define TOUCH_UI_800x480
#endif
#ifndef FTDI_API_LEVEL
#define FTDI_API_LEVEL 810
#endif
namespace FTDI {
IS_FT810
constexpr bool Use_Crystal = false; // 0 = use internal oscillator, 1 = module has a crystal populated
constexpr bool GPIO_0_Audio_Enable = true; // The AO CLCD uses GPIO0 to enable audio
constexpr bool GPIO_1_Audio_Shutdown = false;
constexpr uint8_t Swizzle = 0;
constexpr uint8_t CSpread = 0;
constexpr uint16_t touch_threshold = 2000; /* touch-sensitivity */
}
#else
#error "Unknown or no TOUCH_UI_FTDI_EVE board specified. To add a new board, modify 'ftdi_eve_boards.h'."
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,260 @@
/****************
* commands.cpp *
****************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* FUNCTION MAP *
* *
* SPI and FT800/810 Commands *
* *
* CLCD::spi_select() Set CS line to 0 *
* CLCD::spi_deselect() Set CS Line to 1 *
* CLCD::reset() Toggle FT800/810 Power Down Line 50 ms *
* CLCD::spi_init() Configure I/O Lines for SPI *
* CLCD::spi_transfer() Send/Receive 1 SPI Byte *
* CLCD::init() Set FT800/810 Registers *
* CLCD::enable() Turn On FT800/810 PCLK *
* CLCD::disable() Turn Off FT8880/810 PCLK *
* CLCD::set_backlight() Set LCD Backlight Level *
* *
* MEMORY READ FUNCTIONS *
* *
* CLCD::mem_read_addr() Send 32-Bit Address *
* CLCD::mem_read_8() Read 1 Byte *
* CLCD::mem_read_16() Read 2 Bytes *
* CLCD::mem_read_32() Read 4 Bytes *
* *
* MEMORY WRITE FUNCTIONS *
* *
* CLCD::mem_write_addr() Send 24-Bit Address *
* CLCD::mem_write_8() Write 1 Byte *
* CLCD::mem_write_16() Write 2 Bytes *
* CLCD::mem_write_32() Write 4 Bytes *
* *
* HOST COMMAND FUNCTION *
* *
* CLCD::host_cmd() Send 24-Bit Host Command *
* *
* COMMAND BUFFER FUNCTIONS *
* *
* CLCD::cmd() Send 32-Bit Value(4 Bytes)CMD Buffer *
* CLCD::cmd() Send Data Structure with 32-Bit Cmd *
* CLCD::str() Send Text String in 32-Bit Multiples *
* *
* FT800/810 GRAPHIC COMMANDS *
* *
* class CLCD:CommandFifo {} Class to control Cmd FIFO *
* CommandFifo::start() Wait for CP finish - Set FIFO Ptr *
* CommandFifo::execute() Set REG_CMD_WRITE and start CP *
* CommandFifo::reset() Set Cmd Buffer Pointers to 0 *
*
* CommandFifo::fgcolor Set Graphic Item Foreground Color *
* CommandFifo::bgcolor Set Graphic Item Background Color *
* CommandFifo::begin() Begin Drawing a Primative *
* CommandFifo::mem_copy() Copy a Block of Memory *
* CommandFifo::append() Append Commands to Current DL *
* CommandFifo::gradient_color() Set 3D Button Highlight Color *
* CommandFifo::button() Draw Button with Bulk Write *
* CommandFifo::text() Draw Text with Bulk Write *
*****************************************************************************/
/**************************************************
* RAM_G Graphics RAM Allocation *
* *
* Address Use *
* *
* 8000 Extruder Bitmap *
* 8100 Bed Heat Bitmap *
* 8200 Fan Bitmap *
* 8300 Thumb Drive Symbol Bitmap *
* 35000 Static DL Space (FT800) *
* F5000 Static DL Space (FT810) *
**************************************************/
#pragma once
typedef const __FlashStringHelper *progmem_str;
class UIStorage;
class CLCD {
friend class UIStorage;
public:
typedef FTDI::ftdi_registers REG;
typedef FTDI::ftdi_memory_map MAP;
static void spi_write_addr (uint32_t reg_address);
static void spi_read_addr (uint32_t reg_address);
static uint8_t mem_read_8 (uint32_t reg_address);
static uint16_t mem_read_16 (uint32_t reg_address);
static uint32_t mem_read_32 (uint32_t reg_address);
static void mem_read_bulk (uint32_t reg_address, uint8_t *data, uint16_t len);
static void mem_write_8 (uint32_t reg_address, uint8_t w_data);
static void mem_write_16 (uint32_t reg_address, uint16_t w_data);
static void mem_write_32 (uint32_t reg_address, uint32_t w_data);
static void mem_write_bulk (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding = 0);
static void mem_write_pgm (uint32_t reg_address, const void *data, uint16_t len, uint8_t padding = 0);
static void mem_write_bulk (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding = 0);
static void mem_write_xbm (uint32_t reg_address, progmem_str str, uint16_t len, uint8_t padding = 0);
public:
class CommandFifo;
class FontMetrics;
static void init();
static void default_touch_transform();
static void default_display_orientation();
static void turn_on_backlight();
static void enable();
static void disable();
static void set_brightness (uint8_t brightness);
static uint8_t get_brightness();
static void host_cmd (unsigned char host_command, unsigned char byte2);
static void get_font_metrics (uint8_t font, struct FontMetrics &fm);
static uint16_t get_text_width(const uint8_t font, const char *str);
static uint16_t get_text_width_P(const uint8_t font, const char *str);
static uint8_t get_tag () {return mem_read_8(REG::TOUCH_TAG);}
static bool is_touching () {return (mem_read_32(REG::TOUCH_DIRECT_XY) & 0x80000000) == 0;}
static uint8_t get_tracker (uint16_t &value) {
uint32_t tracker = mem_read_32(REG::TRACKER);
value = tracker >> 16;
return tracker & 0xFF;
}
};
/*************************** FT800/810 Font Metrics ****************************/
class CLCD::FontMetrics {
public:
uint8_t char_widths[128];
uint32_t format;
uint32_t stride;
uint32_t width;
uint32_t height;
uint32_t ptr;
FontMetrics() {}
FontMetrics(uint8_t font) {load(font);}
void load(uint8_t font);
// Returns width of string, up to a maximum of n characters.
uint16_t get_text_width(const char *str, size_t n = SIZE_MAX) const;
uint16_t get_text_width(progmem_str str, size_t n = SIZE_MAX) const;
};
/******************* FT800/810 Graphic Commands *********************************/
class CLCD::CommandFifo {
protected:
#if FTDI_API_LEVEL >= 810
uint32_t getRegCmdBSpace();
#else
static uint32_t command_write_ptr;
template <class T> bool _write_unaligned(T data, uint16_t len);
#endif
void start();
public:
template <class T> bool write(T data, uint16_t len);
public:
CommandFifo() {start();}
static void reset();
static bool is_processing();
static bool has_fault();
void execute();
void cmd(uint32_t cmd32);
void cmd(void* data, uint16_t len);
void dlstart() {cmd(FTDI::CMD_DLSTART);}
void swap() {cmd(FTDI::CMD_SWAP);}
void coldstart() {cmd(FTDI::CMD_COLDSTART);}
void screensaver() {cmd(FTDI::CMD_SCREENSAVER);}
void stop() {cmd(FTDI::CMD_STOP);}
void loadidentity() {cmd(FTDI::CMD_LOADIDENTITY);}
void setmatrix() {cmd(FTDI::CMD_SETMATRIX);}
void fgcolor (uint32_t rgb);
void bgcolor (uint32_t rgb);
void gradcolor (uint32_t rgb);
void track (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t tag);
void clock (int16_t x, int16_t y, int16_t r, uint16_t options, int16_t h, int16_t m, int16_t s, int16_t ms);
void gauge (int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t major, uint16_t minor, uint16_t val, uint16_t range);
void dial (int16_t x, int16_t y, int16_t r, uint16_t options, uint16_t val);
void slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
void progress (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
void scrollbar (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t size, uint16_t range);
void number (int16_t x, int16_t y, int16_t font, uint16_t options, int32_t n);
void spinner (int16_t x, int16_t y, uint16_t style, uint16_t scale);
void sketch (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format);
void gradient (int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1);
void snapshot (uint32_t ptr);
void loadimage (uint32_t ptr, uint32_t options);
void getprops (uint32_t ptr, uint32_t width, uint32_t height);
void scale (int32_t sx, int32_t sy);
void rotate (int32_t a);
void translate (int32_t tx, int32_t ty);
#if FTDI_API_LEVEL >= 810
void setbase (uint8_t base);
void setrotate (uint8_t rotation);
void setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h);
void snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h);
void mediafifo (uint32_t ptr, uint32_t size);
void playvideo (uint32_t options);
void videostart();
void videoframe(uint32_t dst, uint32_t ptr);
void romfont (uint8_t font, uint8_t romslot);
#endif
// All the following must be followed by str()
void text (int16_t x, int16_t y, int16_t font, uint16_t options);
void button (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t option);
void toggle (int16_t x, int16_t y, int16_t w, int16_t font, uint16_t options, bool state);
void keys (int16_t x, int16_t y, int16_t w, int16_t h, int16_t font, uint16_t options);
// Sends the string portion of text, button, toggle and keys.
void str (const char * data);
void str (progmem_str data);
void memzero (uint32_t ptr, uint32_t size);
void memset (uint32_t ptr, uint32_t value, uint32_t size);
void memcpy (uint32_t dst, uint32_t src, uint32_t size);
void memcrc (uint32_t ptr, uint32_t num, uint32_t result);
void memwrite (uint32_t ptr, uint32_t value);
void inflate (uint32_t ptr);
void getptr (uint32_t result);
void append (uint32_t ptr, uint32_t size);
};

View File

@ -0,0 +1,414 @@
/***************
* constants.h *
***************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* This header defines constants and commands for the FTDI FT810 LCD Driver *
* chip. *
****************************************************************************/
#pragma once
// OPTIONS
namespace FTDI {
constexpr uint16_t OPT_3D = 0x0000;
constexpr uint16_t OPT_RGB565 = 0x0000;
constexpr uint16_t OPT_MONO = 0x0001;
constexpr uint16_t OPT_NODL = 0x0002;
constexpr uint16_t OPT_FLAT = 0x0100;
constexpr uint16_t OPT_SIGNED = 0x0100;
constexpr uint16_t OPT_CENTERX = 0x0200;
constexpr uint16_t OPT_CENTERY = 0x0400;
constexpr uint16_t OPT_CENTER = (OPT_CENTERX | OPT_CENTERY);
constexpr uint16_t OPT_RIGHTX = 0x0800;
constexpr uint16_t OPT_NOBACK = 0x1000;
constexpr uint16_t OPT_NOTICKS = 0x2000;
constexpr uint16_t OPT_NOHM = 0x4000;
constexpr uint16_t OPT_NOPOINTER = 0x4000;
constexpr uint16_t OPT_NOSECS = 0x8000;
constexpr uint16_t OPT_NOHANDS = (OPT_NOPOINTER | OPT_NOSECS);
}
namespace FTDI_FT810 {
constexpr uint16_t OPT_NOTEAR = 0x0004;
constexpr uint16_t OPT_FULLSCREEN = 0x0008;
constexpr uint16_t OPT_MEDIAFIFO = 0x0010;
constexpr uint16_t OPT_SOUND = 0x0020;
}
// GPIO Bits
namespace FTDI {
constexpr uint8_t GPIO_GP0 = 1 << 0;
constexpr uint8_t GPIO_GP1 = 1 << 1;
constexpr uint8_t GPIO_DISP = 1 << 7;
}
namespace FTDI_FT810 {
constexpr uint16_t GPIOX_GP0 = 1 << 0;
constexpr uint16_t GPIOX_GP1 = 1 << 1;
constexpr uint16_t GPIOX_DISP = 1 << 15;
}
// HOST COMMANDS
namespace FTDI {
constexpr uint8_t ACTIVE = 0x00;
constexpr uint8_t STANDBY = 0x41;
constexpr uint8_t SLEEP = 0x42;
constexpr uint8_t PWRDOWN = 0x50;
constexpr uint8_t CLKEXT = 0x44;
constexpr uint8_t CLKINT = 0x48;
constexpr uint8_t CORESET = 0x68;
}
namespace FTDI_FT800 {
constexpr uint8_t CLK48M = 0x62;
constexpr uint8_t CLK36M = 0x61;
}
namespace FTDI_FT810 {
constexpr uint8_t CLKSEL = 0x61;
}
// DISPLAY LIST COMMANDS
namespace FTDI {
constexpr uint8_t ARGB1555 = 0;
constexpr uint8_t L1 = 1;
constexpr uint8_t L4 = 2;
constexpr uint8_t L8 = 3;
constexpr uint8_t RGB332 = 4;
constexpr uint8_t ARGB2 = 5;
constexpr uint8_t ARGB4 = 6;
constexpr uint8_t RGB565 = 7;
constexpr uint8_t PALETTED = 8;
constexpr uint8_t TEXT8X8 = 9;
constexpr uint8_t TEXTVGA = 10;
constexpr uint8_t BARGRAPH = 11;
constexpr uint8_t ALPHA_FUNC_NEVER = 0;
constexpr uint8_t ALPHA_FUNC_LESS = 1;
constexpr uint8_t ALPHA_FUNC_LEQUAL = 2;
constexpr uint8_t ALPHA_FUNC_GREATER = 3;
constexpr uint8_t ALPHA_FUNC_GEQUAL = 4;
constexpr uint8_t ALPHA_FUNC_EQUAL = 5;
constexpr uint8_t ALPHA_FUNC_NOTEQUAL = 6;
constexpr uint8_t ALPHA_FUNC_ALWAYS = 7;
constexpr uint8_t NEAREST = 0;
constexpr uint8_t BILINEAR = 1;
constexpr uint8_t BORDER = 0;
constexpr uint8_t REPEAT = 1;
constexpr uint8_t BLEND_FUNC_ZERO = 0;
constexpr uint8_t BLEND_FUNC_ONE = 1;
constexpr uint8_t BLEND_FUNC_SRC_ALPHA = 2;
constexpr uint8_t BLEND_FUNC_DST_ALPHA = 3;
constexpr uint8_t BLEND_FUNC_ONE_MINUS_SRC_ALPHA = 4;
constexpr uint8_t BLEND_FUNC_ONE_MINUS_DST_ALPHA = 5;
constexpr uint32_t COLOR_MASK_RED = 8;
constexpr uint32_t COLOR_MASK_GRN = 4;
constexpr uint32_t COLOR_MASK_BLU = 2;
constexpr uint32_t COLOR_MASK_ALPHA = 1;
constexpr uint8_t STENCIL_FUNC_NEVER = 0;
constexpr uint8_t STENCIL_FUNC_LESS = 1;
constexpr uint8_t STENCIL_FUNC_LEQUAL = 2;
constexpr uint8_t STENCIL_FUNC_GREATER = 3;
constexpr uint8_t STENCIL_FUNC_GEQUAL = 4;
constexpr uint8_t STENCIL_FUNC_EQUAL = 5;
constexpr uint8_t STENCIL_FUNC_NOTEQUAL = 6;
constexpr uint8_t STENCIL_FUNC_ALWAYS = 7;
constexpr uint8_t STENCIL_OP_ZERO = 0;
constexpr uint8_t STENCIL_OP_KEEP = 1;
constexpr uint8_t STENCIL_OP_REPLACE = 2;
constexpr uint8_t STENCIL_OP_INCR = 3;
constexpr uint8_t STENCIL_OP_DECR = 4;
constexpr uint8_t STENCIL_OP_INVERT = 5;
typedef enum : uint32_t {
BITMAPS = 1,
POINTS = 2,
LINES = 3,
LINE_STRIP = 4,
EDGE_STRIP_R = 5,
EDGE_STRIP_L = 6,
EDGE_STRIP_A = 7,
EDGE_STRIP_B = 8,
RECTS = 9
} begin_t;
}
namespace FTDI_FT800_DL {
constexpr uint32_t ALPHA_FUNC = 0x09000000;
constexpr uint32_t BEGIN = 0x1F000000;
constexpr uint32_t BITMAP_HANDLE = 0x05000000;
constexpr uint32_t BITMAP_LAYOUT = 0x07000000;
constexpr uint32_t BITMAP_SIZE = 0x08000000;
constexpr uint32_t BITMAP_SOURCE = 0x01000000;
constexpr uint32_t BITMAP_TRANSFORM_A = 0x15000000;
constexpr uint32_t BITMAP_TRANSFORM_B = 0x16000000;
constexpr uint32_t BITMAP_TRANSFORM_C = 0x17000000;
constexpr uint32_t BITMAP_TRANSFORM_D = 0x18000000;
constexpr uint32_t BITMAP_TRANSFORM_E = 0x19000000;
constexpr uint32_t BITMAP_TRANSFORM_F = 0x1A000000;
constexpr uint32_t BLEND_FUNC = 0x0B000000;
constexpr uint32_t CALL = 0x1D000000;
constexpr uint32_t CELL = 0x06000000;
constexpr uint32_t CLEAR = 0x26000000;
constexpr uint32_t CLEAR_COLOR_BUFFER = 0x00000004;
constexpr uint32_t CLEAR_STENCIL_BUFFER = 0x00000002;
constexpr uint32_t CLEAR_TAG_BUFFER = 0x00000001;
constexpr uint32_t CLEAR_COLOR_A = 0x0F000000;
constexpr uint32_t CLEAR_COLOR_RGB = 0x02000000;
constexpr uint32_t CLEAR_STENCIL = 0x11000000;
constexpr uint32_t CLEAR_TAG = 0x12000000;
constexpr uint32_t COLOR_A = 0x10000000;
constexpr uint32_t COLOR_MASK = 0x20000000;
constexpr uint32_t COLOR_RGB = 0x04000000;
constexpr uint32_t DL_DISPLAY = 0x00000000;
constexpr uint32_t END = 0x21000000;
constexpr uint32_t JUMP = 0x1E000000;
constexpr uint32_t LINE_WIDTH = 0x0E000000;
constexpr uint32_t MACRO = 0x25000000;
constexpr uint32_t POINT_SIZE = 0x0D000000;
constexpr uint32_t RESTORE_CONTEXT = 0x23000000;
constexpr uint32_t RETURN = 0x24000000;
constexpr uint32_t SAVE_CONTEXT = 0x22000000;
constexpr uint32_t SCISSOR_SIZE = 0x1C000000;
constexpr uint32_t SCISSOR_XY = 0x1B000000;
constexpr uint32_t STENCIL_FUNC = 0x0A000000;
constexpr uint32_t STENCIL_MASK = 0x13000000;
constexpr uint32_t STENCIL_OP = 0x0C000000;
constexpr uint32_t TAG = 0x03000000;
constexpr uint32_t TAG_MASK = 0x14000000;
constexpr uint32_t VERTEX2F = 0x40000000;
constexpr uint32_t VERTEX2II = 0x80000000;
}
namespace FTDI_FT810_DL {
constexpr uint32_t NOP = 0x25000000;
constexpr uint32_t BITMAP_LAYOUT_H = 0x28000000;
constexpr uint32_t BITMAP_SIZE_H = 0x29000000;
constexpr uint32_t VERTEX_FORMAT = 0x27000000;
constexpr uint32_t VERTEX_TRANSLATE_X = 0x2B000000;
constexpr uint32_t VERTEX_TRANSLATE_Y = 0x2C000000;
}
// CO-PROCESSOR ENGINE COMMANDS
namespace FTDI {
constexpr uint32_t CMD_DLSTART = 0xFFFFFF00;
constexpr uint32_t CMD_SWAP = 0xFFFFFF01;
constexpr uint32_t CMD_COLDSTART = 0xFFFFFF32;
constexpr uint32_t CMD_INTERRUPT = 0xFFFFFF02;
constexpr uint32_t CMD_APPEND = 0xFFFFFF1E;
constexpr uint32_t CMD_REGREAD = 0xFFFFFF19;
constexpr uint32_t CMD_MEMWRITE = 0xFFFFFF1A;
constexpr uint32_t CMD_INFLATE = 0xFFFFFF22;
constexpr uint32_t CMD_LOADIMAGE = 0xFFFFFF24;
constexpr uint32_t CMD_MEMCRC = 0xFFFFFF18;
constexpr uint32_t CMD_MEMZERO = 0xFFFFFF1C;
constexpr uint32_t CMD_MEMSET = 0xFFFFFF1B;
constexpr uint32_t CMD_MEMCPY = 0xFFFFFF1D;
constexpr uint32_t CMD_BUTTON = 0xFFFFFF0D;
constexpr uint32_t CMD_CLOCK = 0xFFFFFF14;
constexpr uint32_t CMD_FGCOLOR = 0xFFFFFF0A;
constexpr uint32_t CMD_BGCOLOR = 0xFFFFFF09;
constexpr uint32_t CMD_GRADCOLOR = 0xFFFFFF34;
constexpr uint32_t CMD_GAUGE = 0xFFFFFF13;
constexpr uint32_t CMD_GRADIENT = 0xFFFFFF0B;
constexpr uint32_t CMD_KEYS = 0xFFFFFF0E;
constexpr uint32_t CMD_PROGRESS = 0xFFFFFF0F;
constexpr uint32_t CMD_SCROLLBAR = 0xFFFFFF11;
constexpr uint32_t CMD_SLIDER = 0xFFFFFF10;
constexpr uint32_t CMD_DIAL = 0xFFFFFF2D;
constexpr uint32_t CMD_TOGGLE = 0xFFFFFF12;
constexpr uint32_t CMD_TEXT = 0xFFFFFF0C;
constexpr uint32_t CMD_NUMBER = 0xFFFFFF2E;
constexpr uint32_t CMD_LOADIDENTITY = 0xFFFFFF26;
constexpr uint32_t CMD_SETMATRIX = 0xFFFFFF2A;
constexpr uint32_t CMD_GETMATRIX = 0xFFFFFF33;
constexpr uint32_t CMD_GETPTR = 0xFFFFFF23;
constexpr uint32_t CMD_GETPROPS = 0xFFFFFF25;
constexpr uint32_t CMD_SCALE = 0xFFFFFF28;
constexpr uint32_t CMD_ROTATE = 0xFFFFFF29;
constexpr uint32_t CMD_TRANSLATE = 0xFFFFFF27;
constexpr uint32_t CMD_CALIBRATE = 0xFFFFFF15;
constexpr uint32_t CMD_SPINNER = 0xFFFFFF16;
constexpr uint32_t CMD_SCREENSAVER = 0xFFFFFF2F;
constexpr uint32_t CMD_SKETCH = 0xFFFFFF30;
constexpr uint32_t CMD_STOP = 0xFFFFFF17;
constexpr uint32_t CMD_SETFONT = 0xFFFFFF2B;
constexpr uint32_t CMD_TRACK = 0xFFFFFF2C;
constexpr uint32_t CMD_SNAPSHOT = 0xFFFFFF1F;
constexpr uint32_t CMD_LOGO = 0xFFFFFF31;
}
namespace FTDI_FT810 {
constexpr uint32_t CMD_SETROTATE = 0xFFFFFF36;
constexpr uint32_t CMD_SNAPSHOT2 = 0xFFFFFF37;
constexpr uint32_t CMD_SETBASE = 0xFFFFFF38;
constexpr uint32_t CMD_MEDIAFIFO = 0xFFFFFF39;
constexpr uint32_t CMD_PLAYVIDEO = 0xFFFFFF3A;
constexpr uint32_t CMD_SETFONT2 = 0xFFFFFF3B;
constexpr uint32_t CMD_SETSCRATCH = 0xFFFFFF3C;
constexpr uint32_t CMD_ROMFONT = 0xFFFFFF3F;
constexpr uint32_t CMD_VIDEOSTART = 0xFFFFFF40;
constexpr uint32_t CMD_VIDEOFRAME = 0xFFFFFF41;
constexpr uint32_t CMD_SETBITMAP = 0xFFFFFF43;
}
namespace FTDI {
enum effect_t : unsigned char {
SILENCE = 0x00,
SQUARE_WAVE = 0x01,
SINE_WAVE = 0x02,
SAWTOOTH_WAVE = 0x03,
TRIANGLE_WAVE = 0x04,
BEEPING = 0x05,
ALARM = 0x06,
WARBLE = 0x07,
CAROUSEL = 0x08,
SHORT_PIPS_1 = 0x10,
SHORT_PIPS_2 = 0x11,
SHORT_PIPS_3 = 0x12,
SHORT_PIPS_4 = 0x13,
SHORT_PIPS_5 = 0x14,
SHORT_PIPS_6 = 0x15,
SHORT_PIPS_7 = 0x16,
SHORT_PIPS_8 = 0x17,
SHORT_PIPS_9 = 0x18,
SHORT_PIPS_10 = 0x19,
SHORT_PIPS_11 = 0x1A,
SHORT_PIPS_12 = 0x1B,
SHORT_PIPS_13 = 0x1C,
SHORT_PIPS_14 = 0x1D,
SHORT_PIPS_15 = 0x1E,
SHORT_PIPS_16 = 0x1F,
DTMF_POUND = 0x23,
DTMF_STAR = 0x2C,
DTMF_0 = 0x30,
DTMF_1 = 0x31,
DTMF_2 = 0x32,
DTMF_3 = 0x33,
DTMF_4 = 0x34,
DTMF_5 = 0x35,
DTMF_6 = 0x36,
DTMF_7 = 0x37,
DTMF_8 = 0x38,
DTMF_9 = 0x39,
HARP = 0x40,
XYLOPHONE = 0x41,
TUBA = 0x42,
GLOCKENSPIEL = 0x43,
ORGAN = 0x44,
TRUMPET = 0x45,
PIANO = 0x46,
CHIMES = 0x47,
MUSIC_BOX = 0x48,
BELL = 0x49,
CLICK = 0x50,
SWITCH = 0x51,
COWBELL = 0x52,
NOTCH = 0x53,
HIHAT = 0x54,
KICKDRUM = 0x55,
POP = 0x56,
CLACK = 0x57,
CHACK = 0x58,
MUTE = 0x60,
UNMUTE = 0x61
};
enum note_t : unsigned char {
END_SONG = 0xFF,
REST = 0x00,
NOTE_C1 = 0x18, // 24
NOTE_C1S = 0x19,
NOTE_D1 = 0x1A,
NOTE_D1S = 0x1B,
NOTE_E1 = 0x1C,
NOTE_F1 = 0x1D,
NOTE_F1S = 0x1E,
NOTE_G1 = 0x1F,
NOTE_G1S = 0x20,
NOTE_A1 = 0x21,
NOTE_A1S = 0x22,
NOTE_B1 = 0x23,
NOTE_C2 = 0x24, //36
NOTE_C2S = 0x25,
NOTE_D2 = 0x26,
NOTE_D2S = 0x27,
NOTE_E2 = 0x28,
NOTE_F2 = 0x29,
NOTE_F2S = 0x2A,
NOTE_G2 = 0x2B,
NOTE_G2S = 0x2C,
NOTE_A2 = 0x2D,
NOTE_A2S = 0x2E,
NOTE_B2 = 0x2F,
NOTE_C3 = 0x30,
NOTE_C3S = 0x31,
NOTE_D3 = 0x32,
NOTE_D3S = 0x33,
NOTE_E3 = 0x34,
NOTE_F3 = 0x35,
NOTE_F3S = 0x36,
NOTE_G3 = 0x37,
NOTE_G3S = 0x38,
NOTE_A3 = 0x39,
NOTE_A3S = 0x3A,
NOTE_B3 = 0x3B,
NOTE_C4 = 0x3C,
NOTE_C4S = 0x3D,
NOTE_D4 = 0x3E,
NOTE_D4S = 0x3F,
NOTE_E4 = 0x40,
NOTE_F4 = 0x41,
NOTE_F4S = 0x42,
NOTE_G4 = 0x43,
NOTE_G4S = 0x44,
NOTE_A4 = 0x45,
NOTE_A4S = 0x46,
NOTE_B4 = 0x47,
NOTE_C5 = 0x48,
NOTE_C5S = 0x49,
NOTE_D5 = 0x4A,
NOTE_D5S = 0x4B,
NOTE_E5 = 0x4C,
NOTE_F5 = 0x4D,
NOTE_F5S = 0x4E,
NOTE_G5 = 0x4F,
NOTE_G5S = 0x50,
NOTE_A5 = 0x51,
NOTE_A5S = 0x52,
NOTE_B5 = 0x53,
};
}

View File

@ -0,0 +1,118 @@
/******************
* display_list.h *
*****************/
/**********************************************************************************
* Adapted from: *
* https://github.com/RudolphRiedel/FT800-FT813 *
* By Rudolph Riedel *
* *
* MIT License *
* *
* Copyright (c) 2017 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
* copies of the Software, and to permit persons to whom the Software is *
* furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in all *
* copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
* SOFTWARE. *
* *
**********************************************************************************/
#pragma once
namespace FTDI {
/* FT8xx graphics engine specific macros useful for static display list generation */
inline uint32_t ALPHA_FUNC(uint8_t func, uint8_t ref) {return DL::ALPHA_FUNC|((func&7UL)<<8)|(ref&255UL);}
inline uint32_t BEGIN(begin_t prim) {return DL::BEGIN|(prim&15UL);}
inline uint32_t BITMAP_SOURCE(uint32_t ram_g_addr) {return DL::BITMAP_SOURCE|(ram_g_addr);}
inline uint32_t BITMAP_HANDLE(uint8_t handle) {return DL::BITMAP_HANDLE|(handle&31UL);}
inline uint32_t BITMAP_LAYOUT(uint8_t format, uint16_t linestride, uint16_t height)
{return DL::BITMAP_LAYOUT|((format&31UL)<<19)|((linestride&1023UL)<<9)|(height&511UL);}
inline uint32_t BITMAP_SIZE(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height)
{return DL::BITMAP_SIZE|((filter&1UL)<<20)|((wrapx&1UL)<<19)|((wrapy&1UL)<<18)|((width&511UL)<<9)|(height&511UL);}
#if FTDI_API_LEVEL >= 810
inline uint32_t BITMAP_LAYOUT_H(uint8_t linestride, uint8_t height)
{return DL::BITMAP_LAYOUT_H|((linestride&3UL)<<2)|(height&3UL);}
inline uint32_t BITMAP_SIZE_H(uint8_t width, uint8_t height)
{return DL::BITMAP_SIZE_H|((width&3UL)<<2)|(height&3UL);}
#endif
inline uint32_t BITMAP_TRANSFORM_A(uint16_t a) {return DL::BITMAP_TRANSFORM_A|(a&131071UL);}
inline uint32_t BITMAP_TRANSFORM_B(uint16_t b) {return DL::BITMAP_TRANSFORM_B|(b&131071UL);}
inline uint32_t BITMAP_TRANSFORM_C(uint32_t c) {return DL::BITMAP_TRANSFORM_C|(c&16777215UL);}
inline uint32_t BITMAP_TRANSFORM_D(uint16_t d) {return DL::BITMAP_TRANSFORM_D|(d&131071UL);}
inline uint32_t BITMAP_TRANSFORM_E(uint16_t e) {return DL::BITMAP_TRANSFORM_E|(e&131071UL);}
inline uint32_t BITMAP_TRANSFORM_F(uint32_t f) {return DL::BITMAP_TRANSFORM_F|(f&16777215UL);}
inline uint32_t BLEND_FUNC(uint8_t src,uint8_t dst) {return DL::BLEND_FUNC|((src&7UL)<<3)|(dst&7UL);}
inline uint32_t CALL(uint16_t dest) {return DL::CALL|(dest&65535UL);}
inline uint32_t CELL(uint8_t cell) {return DL::CELL|(cell&127UL);}
inline uint32_t CLEAR(bool c,bool s,bool t) {return DL::CLEAR|((c?1UL:0UL)<<2)|((s?1UL:0UL)<<1)|(t?1UL:0UL);}
inline uint32_t CLEAR_COLOR_A(uint8_t alpha) {return DL::CLEAR_COLOR_A|(alpha&255UL);}
inline uint32_t CLEAR_COLOR_RGB(uint8_t red, uint8_t green, uint8_t blue)
{return DL::CLEAR_COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);}
inline uint32_t CLEAR_COLOR_RGB(uint32_t rgb) {return DL::CLEAR_COLOR_RGB|rgb;}
inline uint32_t CLEAR_STENCIL(uint8_t s) {return DL::CLEAR_STENCIL|(s&255UL);}
inline uint32_t CLEAR_TAG(uint8_t s) {return DL::CLEAR_TAG|(s&255UL);}
inline uint32_t COLOR_A(uint8_t alpha) {return DL::COLOR_A|(alpha&255UL);}
inline uint32_t COLOR_MASK(bool r, bool g, bool b, bool a) {return DL::COLOR_MASK|((r?1UL:0UL)<<3)|((g?1UL:0UL)<<2)|((b?1UL:0UL)<<1)|(a?1UL:0UL);}
inline uint32_t COLOR_RGB(uint8_t red,uint8_t green,uint8_t blue)
{return DL::COLOR_RGB|((red&255UL)<<16)|((green&255UL)<<8)|(blue&255UL);}
inline uint32_t COLOR_RGB(uint32_t rgb) {return DL::COLOR_RGB|rgb;}
/* inline uint32_t DISPLAY() {return (0UL<<24)) */
inline uint32_t END() {return DL::END;}
inline uint32_t JUMP(uint16_t dest) {return DL::JUMP|(dest&65535UL);}
inline uint32_t LINE_WIDTH(uint16_t width) {return DL::LINE_WIDTH|(width&4095UL);}
inline uint32_t MACRO(uint8_t m) {return DL::MACRO|(m&1UL);}
inline uint32_t POINT_SIZE(uint16_t size) {return DL::POINT_SIZE|(size&8191UL);}
inline uint32_t RESTORE_CONTEXT() {return DL::RESTORE_CONTEXT;}
inline uint32_t RETURN () {return DL::RETURN;}
inline uint32_t SAVE_CONTEXT() {return DL::SAVE_CONTEXT;}
inline uint32_t SCISSOR_XY(uint16_t x,uint16_t y) {
return DL::SCISSOR_XY |
(FTDI::ftdi_chip >= 810
? ((x&2047UL)<<11)|(y&2047UL)
: ((x& 511UL)<<10)|(y&511UL));
}
inline uint32_t SCISSOR_SIZE(uint16_t w,uint16_t h) {
return DL::SCISSOR_SIZE |
(FTDI::ftdi_chip >= 810
? ((w&4095UL)<<12)|(h&4095UL)
: ((w&1023UL)<<10)|(h&1023UL));
}
inline uint32_t SCISSOR_XY() {return DL::SCISSOR_XY;}
inline uint32_t SCISSOR_SIZE() {
return DL::SCISSOR_SIZE |
(FTDI::ftdi_chip >= 810
? (2048UL<<12)|(2048UL)
: ( 512UL<<10)|( 512UL));
}
inline uint32_t STENCIL_FUNC(uint16_t func, uint8_t ref, uint8_t mask)
{return DL::STENCIL_FUNC|((func&7UL)<<16)|((ref&255UL)<<8)|(mask&255UL);}
inline uint32_t STENCIL_MASK(uint8_t mask) {return DL::STENCIL_MASK|(mask&255UL);}
inline uint32_t STENCIL_OP(uint8_t sfail, uint8_t spass) {return DL::STENCIL_OP|(((sfail)&7UL)<<3)|(spass&7UL);}
inline uint32_t TAG(uint8_t s) {return DL::TAG|(s&255UL);}
inline uint32_t TAG_MASK(bool mask) {return DL::TAG_MASK|(mask?1:0);}
inline uint32_t VERTEX2F(uint16_t x, uint16_t y) {return DL::VERTEX2F|((x&32767UL)<<15)|(y&32767UL);}
inline uint32_t VERTEX2II(uint16_t x,uint16_t y, uint8_t handle = 0, uint8_t cell = 0)
{return DL::VERTEX2II|((x&511UL)<<21)|((y&511UL)<<12)|((handle&31UL)<<7)|(cell&127UL);}
#if FTDI_API_LEVEL >= 810
inline uint32_t VERTEX_FORMAT(uint8_t frac) {return DL::VERTEX_FORMAT|(frac&7UL);}
inline uint32_t VERTEX_TRANSLATE_X(int32_t x) {return DL::VERTEX_TRANSLATE_X|(x&131071UL);}
inline uint32_t VERTEX_TRANSLATE_Y(int32_t y) {return DL::VERTEX_TRANSLATE_Y|(y&131071UL);}
#endif
}

View File

@ -0,0 +1,40 @@
/****************
* ftdi_basic.h *
****************/
/****************************************************************************
* Written By Mark Pelletier 2019 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "../compat.h"
#ifndef __MARLIN_FIRMWARE__
#define FTDI_BASIC
#endif
#ifdef FTDI_BASIC
#include "registers_ft800.h"
#include "registers_ft810.h"
#include "constants.h"
#include "boards.h"
#include "commands.h"
#include "spi.h"
#include "display_list.h"
#include "resolutions.h"
#endif

View File

@ -0,0 +1,150 @@
/*********************
* registers_ft800.h *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* This header defines registers for the FTDI FT800 LCD Driver chip. *
****************************************************************************/
/*******************************************************************************
* FT810 *
* *
* START END ADDR SIZE NAME DESCRIPTION *
* *
* 0x000000 0x03FFFF 256 kB RAM_G Main Graphics RAM *
* *
* 0x0C0000 0x0C0003 4 B ROM_CHIPID [0:1] 0x800 Chip Id *
* [1:2] 0x0100 Vers ID *
* *
* 0x0BB23C 0x0FFFFB 275 kB ROM_FONT Font table and bitmap *
* *
* 0x0FFFFC 0x0FFFFF 4 B ROM_FONT_ADDR Font table pointer address *
* *
* 0x100000 0x101FFF 8 kB RAM_DL Display List RAM *
* *
* 0x102000 0x1023FF 1 kB RAM_PAL Palette RAM *
* *
* 0x102400 0x10257F 380 B * Registers *
* *
* 0x108000 0x108FFF 4 kB RAM_CMD Command Buffer *
* *
*******************************************************************************/
#pragma once
namespace FTDI {
struct ft800_memory_map {
// MEMORY LOCATIONS FT800
static constexpr uint32_t RAM_G = 0x000000; // Main Graphics RAM
static constexpr uint32_t ROM_CHIPID = 0x0C0000; // Chip ID/Version ID
static constexpr uint32_t ROM_FONT = 0x0BB23C; // Font ROM
static constexpr uint32_t ROM_FONT_ADDR = 0x0FFFFC; // Font Table Pointer
static constexpr uint32_t RAM_DL = 0x100000; // Display List RAM
static constexpr uint32_t RAM_PAL = 0x102000; // Palette RAM
static constexpr uint32_t RAM_REG = 0x102400; // Registers
static constexpr uint32_t RAM_CMD = 0x108000; // Command Buffer
static constexpr uint32_t RAM_G_SIZE = 256*1024l; // 256k
};
struct ft800_registers {
// REGISTERS AND ADDRESSES FT800
// REGISTER ADDRESS SIZE RESET VALUE TYPE DESCRIPTION
static constexpr uint32_t ID = 0x102400; // 8 0x7C r Identification Register, Always 0x7C
static constexpr uint32_t FRAMES = 0x102404; // 32 0x00000000 r Frame Counter, Since Reset
static constexpr uint32_t CLOCK = 0x102408; // 32 0x00000000 r Clock cycles, Since Reset
static constexpr uint32_t FREQUENCY = 0x10240C; // 28 0x03938700 r/w Main Clock Frequency
static constexpr uint32_t RENDERMODE = 0x102410; // 1 0x00 r/w Rendering Mode: 0 = normal, 1 = single-line
static constexpr uint32_t SNAPY = 0x102414; // 11 0x0000 r/w Scan Line Select for RENDERMODE 1
static constexpr uint32_t SNAPSHOT = 0x102418; // 1 - r Trigger for RENDERMODE 1
static constexpr uint32_t CPURESET = 0x10241C; // 3 0x02 r/w RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
static constexpr uint32_t TAP_CRC = 0x102420; // 32 - r Live Video Tap
static constexpr uint32_t TAP_MASK = 0x102424; // 32 0xFFFFFFFF r/w Live Video Tap Mask
static constexpr uint32_t HCYCLE = 0x102428; // 12 0x224 r/w Horizontal Total Cycle Count
static constexpr uint32_t HOFFSET = 0x10242C; // 12 0x02B r/w Horizontal Display Start Offset
static constexpr uint32_t HSIZE = 0x102430; // 12 0x1E0 r/w Horizontal Display Pixel Count
static constexpr uint32_t HSYNC0 = 0x102434; // 12 0x000 r/w Horizontal Sync Fall Offset
static constexpr uint32_t HSYNC1 = 0x102438; // 12 0x029 r/w Horizontal Sync Rise Offset
static constexpr uint32_t VCYCLE = 0x10243C; // 12 0x124 r/w Vertical Total Cycle Count
static constexpr uint32_t VOFFSET = 0x102440; // 12 0x00C r/w Vertical Display Start Offset
static constexpr uint32_t VSIZE = 0x102444; // 12 0x110 r/w Vertical Display Line Count
static constexpr uint32_t VSYNC0 = 0x102448; // 10 0x000 r/w Vertical Sync Fall Offset
static constexpr uint32_t VSYNC1 = 0x10244C; // 10 0x00A r/w Vertical Sync Rise Offset
static constexpr uint32_t DLSWAP = 0x102450; // 2 0x00 r/w Display List Swap Control
static constexpr uint32_t ROTATE = 0x102454; // 3 0x00 r/w Screen 90,180, 270 degree rotate
static constexpr uint32_t OUTBITS = 0x102458; // 9 0x1B6 r/w Output Resolution, 3x3x3 Bits
static constexpr uint32_t DITHER = 0x10245C; // 1 0x01 r/w Output Dither Enable
static constexpr uint32_t SWIZZLE = 0x102460; // 4 0x00 r/w Output RGB Swizzle, Pin Change for PCB Routing
static constexpr uint32_t CSPREAD = 0x102464; // 1 0x01 r/w Output Clock Spreading Enable
static constexpr uint32_t PCLK_POL = 0x102468; // 1 0x00 r/w PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
static constexpr uint32_t PCLK = 0x10246C; // 8 0x00 r/w PCLK Frequency Divider, 0 = Disable Clock
static constexpr uint32_t TAG_X = 0x102470; // 11 0x000 r/w Tag Query X Coordinate
static constexpr uint32_t TAG_Y = 0x102474; // 11 0x000 r/w Tag Query Y Coordinate
static constexpr uint32_t TAG = 0x102478; // 8 0x00 r Tag Query Result
static constexpr uint32_t VOL_PB = 0x10247C; // 8 0xFF r/w Audio Playback Volume
static constexpr uint32_t VOL_SOUND = 0x102480; // 8 0xFF r/w Audio Synthesizer Volume
static constexpr uint32_t SOUND = 0x102484; // 16 0x0000 r/w Audio Sound Effect Select
static constexpr uint32_t PLAY = 0x102488; // 1 0x00 r/w Audio Start Effect Playback
static constexpr uint32_t GPIO_DIR = 0x10248C; // 8 0x80 r/w GPIO Pin Direction: 0 = Input , 1 = Output
static constexpr uint32_t GPIO = 0x102490; // 8 0x00 r/w GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
static constexpr uint32_t INT_FLAGS = 0x102498; // 8 0x00 r Interrupt Flags, Clear by Reading
static constexpr uint32_t INT_EN = 0x10249C; // 1 0x00 r/w Global Interrupt Enable
static constexpr uint32_t INT_MASK = 0x1024A0; // 8 0xFF r/w Interrupt Enable Mask
static constexpr uint32_t PLAYBACK_START = 0x1024A4; // 20 0x00000 r/w Audio Playback RAM Start Address
static constexpr uint32_t PLAYBACK_LENGTH = 0x1024A8; // 20 0x00000 r/w Audio Playback Sample Length (Bytes)
static constexpr uint32_t PLAYBACK_READPTR = 0x1024AC; // 20 - r Audio Playback Read Pointer
static constexpr uint32_t PLAYBACK_FREQ = 0x1024B0; // 16 0x1F40 r/w Audio Playback Frequency (Hz)
static constexpr uint32_t PLAYBACK_FORMAT = 0x1024B4; // 2 0x00 r/w Audio Playback Format
static constexpr uint32_t PLAYBACK_LOOP = 0x1024B8; // 1 0x00 r/w Audio Playback Loop Enable
static constexpr uint32_t PLAYBACK_PLAY = 0x1024BC; // 1 0x00 r Audio Start Playback
static constexpr uint32_t PWM_HZ = 0x1024C0; // 14 0x00FA r/w Backlight PWM Frequency (Hz)
static constexpr uint32_t PWM_DUTY = 0x1024C4; // 8 0x80 r/w Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
static constexpr uint32_t MACRO_0 = 0x1024C8; // 32 0x00000000 r/w Display List Macro Command 0
static constexpr uint32_t MACRO_1 = 0x1024CC; // 32 0x00000000 r/w Display List Macro Command 1
static constexpr uint32_t CMD_READ = 0x1024E4; // 12 0x000 r/w Command Buffer Read Pointer
static constexpr uint32_t CMD_WRITE = 0x1024E8; // 12 0x000 r/w Command Buffer Write Pointer
static constexpr uint32_t CMD_DL = 0x1024EC; // 13 0x0000 r/w Command Display List Offset
static constexpr uint32_t TOUCH_MODE = 0x1024F0; // 2 0x03 r/w Touch-Screen Sampling Mode
static constexpr uint32_t TOUCH_ADC_MODE = 0x1024F4; // 1 0x01 r/w Select Single Ended or Differential Sampling
static constexpr uint32_t TOUCH_CHARGE = 0x1024F8; // 16 0x1770 r/w Touch Screen Charge Time, n x 6 Clocks
static constexpr uint32_t TOUCH_SETTLE = 0x1024FC; // 4 0x03 r/w Touch-Screen Settle Time, n x 6 Clocks
static constexpr uint32_t TOUCH_OVERSAMPLE = 0x102500; // 4 0x07 r/w Touch-Screen Oversample Factor
static constexpr uint32_t TOUCH_RZTHRESH = 0x102504; // 16 0xFFFF r/w Touch-Screen Resistance Threshold
static constexpr uint32_t TOUCH_RAW_XY = 0x102508; // 32 - r Touch-Screen Raw (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_RZ = 0x10250C; // 16 - r Touch-Screen Resistance
static constexpr uint32_t TOUCH_SCREEN_XY = 0x102510; // 32 - r Touch-Screen Screen (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_TAG_XY = 0x102514; // 32 - r Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_TAG = 0x102518; // 8 - r Touch-Screen Tag 0 Result
static constexpr uint32_t TOUCH_TRANSFORM_A = 0x10251C; // 32 0x00010000 r/w Touch-Screen Transform Coefficient A (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_B = 0x102520; // 32 0x00000000 r/w Touch-Screen Transform Coefficient B (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_C = 0x102524; // 32 0x00000000 r/w Touch-Screen Transform Coefficient C (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_D = 0x102528; // 32 0x00000000 r/w Touch-Screen Transform Coefficient D (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_E = 0x10252C; // 32 0x00010000 r/w Touch-Screen Transform Coefficient E (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_F = 0x102530; // 32 0x00000000 r/w Touch-Screen Transform Coefficient F (s15.16)
// Reserved Addresses 0x102434 - 0x102470
static constexpr uint32_t TOUCH_DIRECT_XY = 0x102574; // 32 - r Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x102578; // 32 - r Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
static constexpr uint32_t TRACKER = 0x109000; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
};
}

View File

@ -0,0 +1,187 @@
/*********************
* registers_ft810.h *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/****************************************************************************
* This header defines registers for the FTDI FT810 LCD Driver chip. *
****************************************************************************/
/*******************************************************************************
* FT810 *
* *
* START END ADDR SIZE NAME DESCRIPTION *
* *
* 0x000000 0x0FFFFF 1024 kB RAM_G Main Graphics RAM (0 to 1048572) *
* *
* 0x0C0000 0x0C0003 4 B ROM_CHIPID [0:1] 0x800 Chip Id *
* [1:2] 0x0100 Vers ID *
* *
* 0x1E0000 0x2FFFFB 1152 kB ROM_FONT Font table and bitmap *
* *
* 0x201EE0 0x2029DC 2812 B ROM_FONT_ROOT ROM font table *
* *
* 0x2FFFFC 0x2FFFFF 4 B ROM_FONT_ADDR Font table pointer address *
* *
* 0x300000 0x301FFF 8 kB RAM_DL Display List RAM *
* *
* 0x302000 0x302FFF 4 kB * Registers *
* *
* 0x308000 0x308FFF 4 kB RAM_CMD Command Buffer *
* *
*******************************************************************************/
#pragma once
namespace FTDI {
struct ft810_memory_map {
// MEMORY LOCATIONS FT810
static constexpr uint32_t RAM_G = 0x000000; // Main Graphics RAM
static constexpr uint32_t ROM_CHIPID = 0x0C0000; // Chip ID/Version ID
static constexpr uint32_t ROM_FONT = 0x1E0000; // Font ROM
static constexpr uint32_t ROM_FONT_ADDR = 0x2FFFFC; // Font Table Pointer
static constexpr uint32_t RAM_DL = 0x300000; // Display List RAM
static constexpr uint32_t RAM_REG = 0x302000; // Registers
static constexpr uint32_t RAM_CMD = 0x308000; // Command Buffer
static constexpr uint32_t RAM_G_SIZE = 1024*1024l; // 1024k
};
struct ft810_registers {
// REGISTERS AND ADDRESSES FT810
// REGISTER ADDRESS SIZE RESET VALUE TYPE DESCRIPTION
static constexpr uint32_t ID = 0x302000; // 8 0x7C r Identification Register, Always 0x7C
static constexpr uint32_t FRAMES = 0x302004; // 32 0x00000000 r Frame Counter, Since Reset
static constexpr uint32_t CLOCK = 0x302008; // 32 0x00000000 r Clock cycles, Since Reset
static constexpr uint32_t FREQUENCY = 0x30200C; // 28 0x03938700 r/w Main Clock Frequency
static constexpr uint32_t RENDERMODE = 0x302010; // 1 0x00 r/w Rendering Mode: 0 = normal, 1 = single-line
static constexpr uint32_t SNAPY = 0x302014; // 11 0x0000 r/w Scan Line Select for RENDERMODE 1
static constexpr uint32_t SNAPSHOT = 0x302018; // 1 - r Trigger for RENDERMODE 1
static constexpr uint32_t SNAPFORMAT = 0x30201C; // 6 0x20 r/w Pixel Format for Scanline Readout
static constexpr uint32_t CPURESET = 0x302020; // 3 0x02 r/w RESET Bit2 Audio - Bit1 Touch - Bit0 Graphics
static constexpr uint32_t TAP_CRC = 0x302024; // 32 - r Live Video Tap
static constexpr uint32_t TAP_MASK = 0x302028; // 32 0xFFFFFFFF r/w Live Video Tap Mask
static constexpr uint32_t HCYCLE = 0x30202C; // 12 0x224 r/w Horizontal Total Cycle Count
static constexpr uint32_t HOFFSET = 0x302030; // 12 0x02B r/w Horizontal Display Start Offset
static constexpr uint32_t HSIZE = 0x302034; // 12 0x1E0 r/w Horizontal Display Pixel Count
static constexpr uint32_t HSYNC0 = 0x302038; // 12 0x000 r/w Horizontal Sync Fall Offset
static constexpr uint32_t HSYNC1 = 0x30203C; // 12 0x029 r/w Horizontal Sync Rise Offset
static constexpr uint32_t VCYCLE = 0x302040; // 12 0x124 r/w Vertical Total Cycle Count
static constexpr uint32_t VOFFSET = 0x302044; // 12 0x00C r/w Vertical Display Start Offset
static constexpr uint32_t VSIZE = 0x302048; // 12 0x110 r/w Vertical Display Line Count
static constexpr uint32_t VSYNC0 = 0x30204C; // 10 0x000 r/w Vertical Sync Fall Offset
static constexpr uint32_t VSYNC1 = 0x302050; // 10 0x00A r/w Vertical Sync Rise Offset
static constexpr uint32_t DLSWAP = 0x302054; // 2 0x00 r/w Display List Swap Control
static constexpr uint32_t ROTATE = 0x302058; // 3 0x00 r/w Screen 90,180, 270 degree rotate
static constexpr uint32_t OUTBITS = 0x30205C; // 9 0x1B6 r/w Output Resolution, 3x3x3 Bits
static constexpr uint32_t DITHER = 0x302060; // 1 0x01 r/w Output Dither Enable
static constexpr uint32_t SWIZZLE = 0x302064; // 4 0x00 r/w Output RGB Swizzle, Pin Change for PCB Routing
static constexpr uint32_t CSPREAD = 0x302068; // 1 0x01 r/w Output Clock Spreading Enable
static constexpr uint32_t PCLK_POL = 0x30206C; // 1 0x00 r/w PCLK Polarity: 0 = Rising Edge, 1 = Falling Edge
static constexpr uint32_t PCLK = 0x302070; // 8 0x00 r/w PCLK Frequency Divider, 0 = Disable Clock
static constexpr uint32_t TAG_X = 0x302074; // 11 0x000 r/w Tag Query X Coordinate
static constexpr uint32_t TAG_Y = 0x302078; // 11 0x000 r/w Tag Query Y Coordinate
static constexpr uint32_t TAG = 0x30207C; // 8 0x00 r Tag Query Result
static constexpr uint32_t VOL_PB = 0x302080; // 8 0xFF r/w Audio Playback Volume
static constexpr uint32_t VOL_SOUND = 0x302084; // 8 0xFF r/w Audio Synthesizer Volume
static constexpr uint32_t SOUND = 0x302088; // 16 0x0000 r/w Audio Sound Effect Select
static constexpr uint32_t PLAY = 0x30208C; // 1 0x00 r/w Audio Start Effect Playback
static constexpr uint32_t GPIO_DIR = 0x302090; // 8 0x80 r/w GPIO Pin Direction: 0 = Input , 1 = Output
static constexpr uint32_t GPIO = 0x302094; // 8 0x00 r/w GPIO Pin Values for 0, 1, 7 Drive Strength 2, 3, 4, 5, 6
static constexpr uint32_t GPIOX_DIR = 0x302098; // 16 0x8000 r/w Extended GPIO Pin Direction
static constexpr uint32_t GPIOX = 0x30209C; // 16 0x0080 r/w Extended GPIO Pin Values
// Reserved Addr 0x3020A0
// Reserved Addr 0x3020A4
static constexpr uint32_t INT_FLAGS = 0x3020A8; // 8 0x00 r Interrupt Flags, Clear by Reading
static constexpr uint32_t INT_EN = 0x3020AC; // 1 0x00 r/w Global Interrupt Enable
static constexpr uint32_t INT_MASK = 0x3020B0; // 8 0xFF r/w Interrupt Enable Mask
static constexpr uint32_t PLAYBACK_START = 0x3020B4; // 20 0x00000 r/w Audio Playback RAM Start Address
static constexpr uint32_t PLAYBACK_LENGTH = 0x3020B8; // 20 0x00000 r/w Audio Playback Sample Length (Bytes)
static constexpr uint32_t PLAYBACK_READPTR = 0x3020BC; // 20 - r Audio Playback Read Pointer
static constexpr uint32_t PLAYBACK_FREQ = 0x3020C0; // 16 0x1F40 r/w Audio Playback Frequency (Hz)
static constexpr uint32_t PLAYBACK_FORMAT = 0x3020C4; // 2 0x00 r/w Audio Playback Format
static constexpr uint32_t PLAYBACK_LOOP = 0x3020C8; // 1 0x00 r/w Audio Playback Loop Enable
static constexpr uint32_t PLAYBACK_PLAY = 0x3020CC; // 1 0x00 r Audio Start Playback
static constexpr uint32_t PWM_HZ = 0x3020D0; // 14 0x00FA r/w Backlight PWM Frequency (Hz)
static constexpr uint32_t PWM_DUTY = 0x3020D4; // 8 0x80 r/w Backlight PWM Duty Cycle: 0 = 0%, 128 = 100%
static constexpr uint32_t MACRO_0 = 0x3020D8; // 32 0x00000000 r/w Display List Macro Command 0
static constexpr uint32_t MACRO_1 = 0x3020DC; // 32 0x00000000 r/w Display List Macro Command 1
// Reserved Addr 0x3020E0
// Reserved Addr 0x3020E4
// Reserved Addr 0x3020E8
// Reserved Addr 0x3020EC
// Reserved Addr 0x3020F0
// Reserved Addr 0x3020F4
static constexpr uint32_t CMD_READ = 0x3020F8; // 12 0x000 r/w Command Buffer Read Pointer
static constexpr uint32_t CMD_WRITE = 0x3020FC; // 12 0x000 r/w Command Buffer Write Pointer
static constexpr uint32_t CMD_DL = 0x302100; // 13 0x0000 r/w Command Display List Offset
static constexpr uint32_t TOUCH_MODE = 0x302104; // 2 0x03 r/w Touch-Screen Sampling Mode
static constexpr uint32_t TOUCH_ADC_MODE = 0x302108; // 1 0x01 r/w Select Single Ended or Differential Sampling
static constexpr uint32_t TOUCH_CHARGE = 0x30210C; // 16 0x1770 r/w Touch Screen Charge Time, n x 6 Clocks
static constexpr uint32_t TOUCH_SETTLE = 0x302110; // 4 0x03 r/w Touch-Screen Settle Time, n x 6 Clocks
static constexpr uint32_t TOUCH_OVERSAMPLE = 0x302114; // 4 0x07 r/w Touch-Screen Oversample Factor
static constexpr uint32_t TOUCH_RZTHRESH = 0x302118; // 16 0xFFFF r/w Touch-Screen Resistance Threshold
static constexpr uint32_t TOUCH_RAW_XY = 0x30211C; // 32 - r Touch-Screen Raw (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_RZ = 0x302120; // 16 - r Touch-Screen Resistance
static constexpr uint32_t TOUCH_SCREEN_XY = 0x302124; // 32 - r Touch-Screen Screen (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_TAG_XY = 0x302128; // 32 - r Touch-Screen Tag 0 Lookup (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_TAG = 0x30212C; // 8 - r Touch-Screen Tag 0 Result
static constexpr uint32_t TOUCH_TAG1_XY = 0x302130; // 32 - r Touch-Screen Tag 1 Lookup
static constexpr uint32_t TOUCH_TAG1 = 0x302134; // 8 - r Touch-Screen Tag 1 Result
static constexpr uint32_t TOUCH_TAG2_XY = 0x302138; // 32 - r Touch-Screen Tag 2 Lookup
static constexpr uint32_t TOUCH_TAG2 = 0x30213C; // 8 - r Touch-Screen Tag 2 Result
static constexpr uint32_t TOUCH_TAG3_XY = 0x302140; // 32 - r Touch-Screen Tag 3 Lookup
static constexpr uint32_t TOUCH_TAG3 = 0x302144; // 8 - r Touch-Screen Tag 3 Result
static constexpr uint32_t TOUCH_TAG4_XY = 0x302148; // 32 - r Touch-Screen Tag 4 Lookup
static constexpr uint32_t TOUCH_TAG4 = 0x30214C; // 8 - r Touch-Screen Tag 4 Result
static constexpr uint32_t TOUCH_TRANSFORM_A = 0x302150; // 32 0x00010000 r/w Touch-Screen Transform Coefficient A (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_B = 0x302154; // 32 0x00000000 r/w Touch-Screen Transform Coefficient B (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_C = 0x302158; // 32 0x00000000 r/w Touch-Screen Transform Coefficient C (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_D = 0x30215C; // 32 0x00000000 r/w Touch-Screen Transform Coefficient D (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_E = 0x302160; // 32 0x00010000 r/w Touch-Screen Transform Coefficient E (s15.16)
static constexpr uint32_t TOUCH_TRANSFORM_F = 0x302164; // 32 0x00000000 r/w Touch-Screen Transform Coefficient F (s15.16)
static constexpr uint32_t TOUCH_CONFIG = 0x302168; // 16 0x8381 r/w Touch Configuration
static constexpr uint32_t CTOUCH_TOUCH4_X = 0x30216C; // 16 - r Extended Mode Touch Screen
// Reserved Addresses 0x302170
static constexpr uint32_t BIST_EN = 0x302174; // 1 0 r/w BIST Memory Mapping Enable
// Reserved Addr 0x302178
// Reserved Addr 0x30217C
static constexpr uint32_t TRIM = 0x302180; // 8 0 r/w Internal Clock Trimming
static constexpr uint32_t ANA_COMP = 0x302184; // 8 0 r/w Analog Control Register
static constexpr uint32_t SPI_WIDTH = 0x302188; // 3 0 r/w QSPI Bus Width Setting
static constexpr uint32_t TOUCH_DIRECT_XY = 0x30218C; // 32 - r Touch-Screen Direct Conversions XY (x-MSB16; y-LSB16)
static constexpr uint32_t TOUCH_DIRECT_Z1Z2 = 0x302190; // 32 - r Touch-Screen Direct Conversions Z (z1-MSB16; z2-LSB16)
// Reserved Addresses 0x302194 - 0x302560
static constexpr uint32_t DATESTAMP = 0x320564; // 128 - r Stamp Date Code
static constexpr uint32_t CMDB_SPACE = 0x302574; // 12 0xFFC r/w Command DL Space Available
static constexpr uint32_t CMDB_WRITE = 0x302578; // 32 0 w Command DL Write
static constexpr uint32_t TRACKER = 0x309000; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
static constexpr uint32_t TRACKER_1 = 0x309004; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
static constexpr uint32_t TRACKER_2 = 0x309008; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
static constexpr uint32_t TRACKER_3 = 0x30900C; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
static constexpr uint32_t TRACKER_4 = 0x309010; // 32 0x00000000 r/w Track Register (Track Value MSB16; Tag Value - LSB8)
static constexpr uint32_t MEDIAFIFO_READ = 0x309014; // 32 0x00000000 r/w Media FIFO read pointer
static constexpr uint32_t MEDIAFIFO_WRITE = 0x309018; // 32 0x00000000 r/w Media FIFO write pointer
};
}

View File

@ -0,0 +1,128 @@
/*****************
* resolutions.h *
*****************/
/****************************************************************************
* Written By Mark Pelletier 2019 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/***
* The FT8xx has odd registers that don't correspond to timing values in
* display datasheets. This macro computes the register values using the
* formulas given in the document:
*
* Bridgetek Application Note
* AN_336 FT8xx
* Selecting an LCD Display
* Version 2.1
* Issue Date: 2017-11-14
*
*/
#define COMPUTE_REGS_FROM_DATASHEET \
constexpr uint16_t Hoffset = thfp + thb - 1; \
constexpr uint16_t Hcycle = th; \
constexpr uint16_t Hsync0 = thfp - 1 ; \
constexpr uint16_t Hsync1 = thfp + thpw - 1; \
constexpr uint16_t Voffset = tvfp + tvb - 1; \
constexpr uint16_t Vcycle = tv; \
constexpr uint16_t Vsync0 = tvfp - 1; \
constexpr uint16_t Vsync1 = tvfp + tvpw - 1; \
static_assert(thfp + thb + Hsize == th, "Mismatch in display th"); \
static_assert(tvfp + tvb + Vsize == tv, "Mismatch in display tv");
#ifdef TOUCH_UI_320x240
namespace FTDI {
constexpr uint8_t Pclk = 8;
constexpr uint8_t Pclkpol = 0;
constexpr uint16_t Hsize = 320;
constexpr uint16_t Vsize = 240;
constexpr uint16_t Vsync0 = 0;
constexpr uint16_t Vsync1 = 2;
constexpr uint16_t Voffset = 13;
constexpr uint16_t Vcycle = 263;
constexpr uint16_t Hsync0 = 0;
constexpr uint16_t Hsync1 = 10;
constexpr uint16_t Hoffset = 70;
constexpr uint16_t Hcycle = 408;
constexpr uint32_t default_transform_a = 0x000054ad;
constexpr uint32_t default_transform_b = 0xffffff52;
constexpr uint32_t default_transform_c = 0xfff7f6e4;
constexpr uint32_t default_transform_d = 0x00000065;
constexpr uint32_t default_transform_e = 0xffffbe3b;
constexpr uint32_t default_transform_f = 0x00f68e75;
}
#elif defined(TOUCH_UI_480x272)
namespace FTDI {
constexpr uint8_t Pclk = 7;
constexpr uint8_t Pclkpol = 1;
constexpr uint16_t Hsize = 480;
constexpr uint16_t Vsize = 272;
constexpr uint16_t th = 525; // One horizontal line
constexpr uint16_t thfp = 43; // HS Front porch
constexpr uint16_t thb = 2; // HS Back porch (blanking)
constexpr uint16_t thpw = 41; // HS pulse width
constexpr uint16_t tv = 286; // Vertical period time
constexpr uint16_t tvfp = 12; // VS Front porch
constexpr uint16_t tvb = 2; // VS Back porch (blanking)
constexpr uint16_t tvpw = 10; // VS pulse width
COMPUTE_REGS_FROM_DATASHEET
constexpr uint32_t default_transform_a = 0x00008100;
constexpr uint32_t default_transform_b = 0x00000000;
constexpr uint32_t default_transform_c = 0xFFF18000;
constexpr uint32_t default_transform_d = 0x00000000;
constexpr uint32_t default_transform_e = 0xFFFFB100;
constexpr uint32_t default_transform_f = 0x0120D000;
}
#elif defined(TOUCH_UI_800x480)
namespace FTDI {
constexpr uint8_t Pclk = 3;
constexpr uint8_t Pclkpol = 1;
constexpr uint16_t Hsize = 800;
constexpr uint16_t Vsize = 480;
constexpr uint16_t th = 1056; // One horizontal line
constexpr uint16_t thfp = 210; // HS Front porch
constexpr uint16_t thb = 46; // HS Back porch (blanking)
constexpr uint16_t thpw = 23; // HS pulse width
constexpr uint16_t tv = 525; // Vertical period time
constexpr uint16_t tvfp = 22; // VS Front porch
constexpr uint16_t tvb = 23; // VS Back porch (blanking)
constexpr uint16_t tvpw = 10; // VS pulse width
COMPUTE_REGS_FROM_DATASHEET
constexpr uint32_t default_transform_a = 0x0000D8B9;
constexpr uint32_t default_transform_b = 0x00000124;
constexpr uint32_t default_transform_c = 0xFFE23926;
constexpr uint32_t default_transform_d = 0xFFFFFF51;
constexpr uint32_t default_transform_e = 0xFFFF7E4F;
constexpr uint32_t default_transform_f = 0x01F0AF70;
}
#else
#error "Unknown or no TOUCH_UI_FTDI_EVE display resolution specified. To add a display resolution, modify 'ftdi_eve_resolutions.h'."
#endif

View File

@ -0,0 +1,161 @@
/***********
* spi.cpp *
***********/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_basic.h"
#ifdef FTDI_BASIC
/********************************* SPI Functions *********************************/
namespace FTDI {
#ifndef CLCD_USE_SOFT_SPI
SPISettings SPI::spi_settings(SPI_FREQUENCY, MSBFIRST, SPI_MODE0);
#endif
void SPI::spi_init() {
SET_OUTPUT(CLCD_MOD_RESET); // Module Reset (a.k.a. PD, not SPI)
WRITE(CLCD_MOD_RESET, 0); // start with module in power-down
SET_OUTPUT(CLCD_SPI_CS);
WRITE(CLCD_SPI_CS, 1);
#ifdef SPI_FLASH_SS
SET_OUTPUT(SPI_FLASH_SS);
WRITE(SPI_FLASH_SS, 1);
#endif
#ifdef CLCD_USE_SOFT_SPI
SET_OUTPUT(CLCD_SOFT_SPI_MOSI);
WRITE(CLCD_SOFT_SPI_MOSI, 1);
SET_OUTPUT(CLCD_SOFT_SPI_SCLK);
WRITE(CLCD_SOFT_SPI_SCLK, 0);
SET_INPUT_PULLUP(CLCD_SOFT_SPI_MISO);
#else
::SPI.begin();
#endif
}
#ifdef CLCD_USE_SOFT_SPI
uint8_t SPI::_soft_spi_xfer (uint8_t spiOutByte) {
uint8_t spiIndex = 0x80;
uint8_t spiInByte = 0;
uint8_t k;
noInterrupts();
for (k = 0; k < 8; k++) { // Output and Read each bit of spiOutByte and spiInByte
WRITE(CLCD_SOFT_SPI_MOSI, (spiOutByte & spiIndex) ? 1 : 0); // Output MOSI Bit
WRITE(CLCD_SOFT_SPI_SCLK, 1); // Pulse Clock
WRITE(CLCD_SOFT_SPI_SCLK, 0);
if (READ(CLCD_SOFT_SPI_MISO)) spiInByte |= spiIndex;
spiIndex >>= 1;
}
interrupts();
return spiInByte;
}
#endif
#ifdef CLCD_USE_SOFT_SPI
void SPI::_soft_spi_send (uint8_t spiOutByte) {
uint8_t k, spiIndex = 0x80;
noInterrupts();
for (k = 0; k < 8; k++) { // Output each bit of spiOutByte
WRITE(CLCD_SOFT_SPI_MOSI, (spiOutByte & spiIndex) ? 1 : 0); // Output MOSI Bit
WRITE(CLCD_SOFT_SPI_SCLK, 1); // Pulse Clock
WRITE(CLCD_SOFT_SPI_SCLK, 0);
spiIndex >>= 1;
}
interrupts();
}
#endif
void SPI::spi_read_bulk (void *data, uint16_t len) {
uint8_t* p = (uint8_t *)data;
#ifndef CLCD_USE_SOFT_SPI
::SPI.transfer(p, len);
#else
while (len--) *p++ = spi_recv();
#endif
}
bool SPI::spi_verify_bulk (const void *data, uint16_t len) {
const uint8_t* p = (const uint8_t *)data;
while (len--) if (*p++ != spi_recv()) return false;
return true;
}
// CLCD SPI - Chip Select
void SPI::spi_ftdi_select() {
#ifndef CLCD_USE_SOFT_SPI
::SPI.beginTransaction(spi_settings);
#endif
WRITE(CLCD_SPI_CS, 0);
delayMicroseconds(1);
}
// CLCD SPI - Chip Deselect
void SPI::spi_ftdi_deselect() {
WRITE(CLCD_SPI_CS, 1);
#ifndef CLCD_USE_SOFT_SPI
::SPI.endTransaction();
#endif
}
#ifdef SPI_FLASH_SS
// Serial SPI Flash SPI - Chip Select
void SPI::spi_flash_select () {
#ifndef CLCD_USE_SOFT_SPI
::SPI.beginTransaction(spi_settings);
#endif
WRITE(SPI_FLASH_SS, 0);
delayMicroseconds(1);
}
// Serial SPI Flash SPI - Chip Deselect
void SPI::spi_flash_deselect () {
WRITE(SPI_FLASH_SS, 1);
#ifndef CLCD_USE_SOFT_SPI
::SPI.endTransaction();
#endif
}
#endif
// Not really a SPI signal...
void SPI::ftdi_reset() {
WRITE(CLCD_MOD_RESET, 0);
delay(6); /* minimum time for power-down is 5ms */
WRITE(CLCD_MOD_RESET, 1);
delay(21); /* minimum time to allow from rising PD_N to first access is 20ms */
}
// Not really a SPI signal...
void SPI::test_pulse() {
#ifdef CLCD_AUX_0
WRITE(CLCD_AUX_0, 1);
delayMicroseconds(10);
WRITE(CLCD_AUX_0, 0);
#endif
}
}
#endif // FTDI_BASIC

View File

@ -0,0 +1,128 @@
/*********
* spi.h *
*********/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#ifndef CLCD_USE_SOFT_SPI
#include <SPI.h>
#endif
namespace FTDI {
namespace SPI {
#ifndef CLCD_USE_SOFT_SPI
extern SPISettings spi_settings;
#endif
uint8_t _soft_spi_xfer (uint8_t val);
void _soft_spi_send (uint8_t val);
void spi_init ();
void spi_ftdi_select ();
void spi_ftdi_deselect ();
void spi_flash_select ();
void spi_flash_deselect ();
inline uint8_t spi_recv() {
#ifdef CLCD_USE_SOFT_SPI
return _soft_spi_xfer(0x00);
#else
return ::SPI.transfer(0x00);
#endif
};
inline void spi_send (uint8_t val) {
#ifdef CLCD_USE_SOFT_SPI
_soft_spi_send(val);
#else
::SPI.transfer(val);
#endif
};
inline void spi_write_8 (uint8_t val) {spi_send(val);};
inline uint8_t spi_read_8 () {return spi_recv();};
namespace least_significant_byte_first {
inline void spi_write_16 (uint16_t val) {spi_send(val >> 0);
spi_send(val >> 8);};
inline void spi_write_32 (uint32_t val) {spi_send(val >> 0);
spi_send(val >> 8);
spi_send(val >> 16);
spi_send(val >> 24);};
inline uint8_t spi_read_8 () {return spi_recv();};
inline uint16_t spi_read_16 () {return (((uint16_t) spi_recv()) << 0) |
(((uint16_t) spi_recv()) << 8);};
inline uint32_t spi_read_32 () {return (((uint32_t) spi_recv()) << 0) |
(((uint32_t) spi_recv()) << 8) |
(((uint32_t) spi_recv()) << 16) |
(((uint32_t) spi_recv()) << 24);};
}
namespace most_significant_byte_first {
inline void spi_write_16 (uint16_t val) {spi_send(val >> 8);
spi_send(val >> 0);};
inline void spi_write_24 (uint32_t val) {spi_send(val >> 16);
spi_send(val >> 8);
spi_send(val >> 0);};
inline void spi_write_32 (uint32_t val) {spi_send(val >> 24);
spi_send(val >> 16);
spi_send(val >> 8);
spi_send(val >> 0);};
inline uint16_t spi_read_16 () {return (((uint16_t) spi_recv()) << 8) |
(((uint16_t) spi_recv()) << 0);};
inline uint32_t spi_read_32 () {return (((uint32_t) spi_recv()) << 24) |
(((uint32_t) spi_recv()) << 16) |
(((uint32_t) spi_recv()) << 8) |
(((uint32_t) spi_recv()) << 0);};
}
inline uint8_t ram_write(const uint8_t *p) {return *p;}
inline uint8_t pgm_write(const uint8_t *p) {return pgm_read_byte(p);}
typedef uint8_t (*bulk_write_op)(const uint8_t*);
// Generic template for function for writing multiple bytes, plus padding bytes.
// The template parameter op is an inlineable function which is applied to each byte.
template<bulk_write_op byte_op>
void spi_write_bulk(const void *data, uint16_t len, uint8_t padding) {
const uint8_t* p = (const uint8_t *)data;
while (len--) spi_send(byte_op(p++));
while (padding--) spi_send(0);
}
template<bulk_write_op byte_op>
void spi_write_bulk(const void *data, uint16_t len) {
const uint8_t* p = (const uint8_t *)data;
while (len--) spi_send(byte_op(p++));
}
void spi_read_bulk( void *data, uint16_t len);
bool spi_verify_bulk(const void *data, uint16_t len);
void ftdi_reset();
void test_pulse();
}
}

View File

@ -0,0 +1,226 @@
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "../config.h"
#ifdef __MARLIN_FIRMWARE__
// Marlin will define the I/O functions for us
#if ENABLED(TOUCH_UI_FTDI_EVE)
#define FTDI_BASIC
#define FTDI_EXTENDED
#endif
#else // !__MARLIN_FIRMWARE__
#include <Arduino.h>
#ifndef CLCD_USE_SOFT_SPI
#include <SPI.h>
#endif
namespace fast_io {
template<typename port_t,uint8_t bits>
struct port_pin {
typedef port_t port;
static inline void set_high() {port::port() = (port::port() | bits);}
static inline void set_low() {port::port() = (port::port() & (~bits));}
static inline void set_input() {port::ddr() = (port::ddr() & (~bits));}
static inline void set_input_pullup() {set_input(); set_high();}
static inline void set_output() {port::ddr() = (port::ddr() | bits);}
static inline uint8_t read() {return port::pin() & bits;}
static inline void write(bool v) {if (v) set_high(); else set_low();}
};
#define MAKE_AVR_PORT_PINS(ID) \
struct port_##ID { \
static volatile uint8_t &pin() {return PIN##ID;}; \
static volatile uint8_t &port() {return PORT##ID;}; \
static volatile uint8_t &ddr() {return DDR##ID;}; \
}; \
typedef port_pin<port_##ID, 0b00000001> AVR_##ID##0; \
typedef port_pin<port_##ID, 0b00000010> AVR_##ID##1; \
typedef port_pin<port_##ID, 0b00000100> AVR_##ID##2; \
typedef port_pin<port_##ID, 0b00001000> AVR_##ID##3; \
typedef port_pin<port_##ID, 0b00010000> AVR_##ID##4; \
typedef port_pin<port_##ID, 0b00100000> AVR_##ID##5; \
typedef port_pin<port_##ID, 0b01000000> AVR_##ID##6; \
typedef port_pin<port_##ID, 0b10000000> AVR_##ID##7;
#ifdef PORTA
MAKE_AVR_PORT_PINS(A);
#endif
#ifdef PORTB
MAKE_AVR_PORT_PINS(B);
#endif
#ifdef PORTC
MAKE_AVR_PORT_PINS(C);
#endif
#ifdef PORTD
MAKE_AVR_PORT_PINS(D);
#endif
#ifdef PORTE
MAKE_AVR_PORT_PINS(E);
#endif
#ifdef PORTF
MAKE_AVR_PORT_PINS(F);
#endif
#ifdef PORTG
MAKE_AVR_PORT_PINS(G);
#endif
#ifdef PORTH
MAKE_AVR_PORT_PINS(H);
#endif
#ifdef PORTJ
MAKE_AVR_PORT_PINS(J);
#endif
#ifdef PORTK
MAKE_AVR_PORT_PINS(K);
#endif
#ifdef PORTL
MAKE_AVR_PORT_PINS(L);
#endif
#ifdef PORTQ
MAKE_AVR_PORT_PINS(Q);
#endif
#ifdef PORTR
MAKE_AVR_PORT_PINS(R);
#endif
#undef MAKE_AVR_PORT_PINS
template<uint8_t p>
struct arduino_digital_pin {
static constexpr uint8_t pin = p;
static inline void set_high() {digitalWrite(p, HIGH);}
static inline void set_low() {digitalWrite(p, LOW);}
static inline void set_input() {pinMode(p, INPUT);}
static inline void set_input_pullup() {pinMode(p, INPUT_PULLUP);}
static inline void set_output() {pinMode(p, OUTPUT);}
static inline uint8_t read() {return digitalRead(p);}
static inline void write(bool v) {digitalWrite(p, v ? HIGH : LOW);}
};
#define MAKE_ARDUINO_PINS(ID) typedef arduino_digital_pin<ID> ARDUINO_DIGITAL_##ID;
MAKE_ARDUINO_PINS( 0);
MAKE_ARDUINO_PINS( 1);
MAKE_ARDUINO_PINS( 2);
MAKE_ARDUINO_PINS( 3);
MAKE_ARDUINO_PINS( 4);
MAKE_ARDUINO_PINS( 5);
MAKE_ARDUINO_PINS( 6);
MAKE_ARDUINO_PINS( 7);
MAKE_ARDUINO_PINS( 8);
MAKE_ARDUINO_PINS( 9);
MAKE_ARDUINO_PINS(10);
MAKE_ARDUINO_PINS(11);
MAKE_ARDUINO_PINS(12);
MAKE_ARDUINO_PINS(13);
MAKE_ARDUINO_PINS(14);
MAKE_ARDUINO_PINS(15);
MAKE_ARDUINO_PINS(16);
MAKE_ARDUINO_PINS(17);
MAKE_ARDUINO_PINS(18);
MAKE_ARDUINO_PINS(19);
MAKE_ARDUINO_PINS(10);
MAKE_ARDUINO_PINS(21);
MAKE_ARDUINO_PINS(22);
MAKE_ARDUINO_PINS(23);
MAKE_ARDUINO_PINS(24);
MAKE_ARDUINO_PINS(25);
MAKE_ARDUINO_PINS(26);
MAKE_ARDUINO_PINS(27);
MAKE_ARDUINO_PINS(28);
MAKE_ARDUINO_PINS(29);
MAKE_ARDUINO_PINS(30);
MAKE_ARDUINO_PINS(31);
MAKE_ARDUINO_PINS(32);
MAKE_ARDUINO_PINS(33);
MAKE_ARDUINO_PINS(34);
MAKE_ARDUINO_PINS(35);
MAKE_ARDUINO_PINS(36);
MAKE_ARDUINO_PINS(37);
MAKE_ARDUINO_PINS(38);
MAKE_ARDUINO_PINS(39);
MAKE_ARDUINO_PINS(40);
MAKE_ARDUINO_PINS(41);
MAKE_ARDUINO_PINS(42);
MAKE_ARDUINO_PINS(43);
MAKE_ARDUINO_PINS(44);
MAKE_ARDUINO_PINS(45);
MAKE_ARDUINO_PINS(46);
MAKE_ARDUINO_PINS(47);
MAKE_ARDUINO_PINS(48);
MAKE_ARDUINO_PINS(49);
MAKE_ARDUINO_PINS(50);
MAKE_ARDUINO_PINS(51);
MAKE_ARDUINO_PINS(52);
MAKE_ARDUINO_PINS(53);
#undef MAKE_ARDUINO_PINS
} // namespace fast_io
#define SET_INPUT(pin) fast_io::pin::set_input()
#define SET_INPUT_PULLUP(pin) fast_io::pin::set_input(); fast_io::pin::set_high()
#define SET_OUTPUT(pin) fast_io::pin::set_output()
#define READ(pin) fast_io::pin::read()
#define WRITE(pin, value) fast_io::pin::write(value)
#ifndef pgm_read_word_far
#define pgm_read_word_far pgm_read_word
#endif
#ifndef pgm_read_dword_far
#define pgm_read_dword_far pgm_read_dword
#endif
#ifndef pgm_read_ptr_far
#define pgm_read_ptr_far pgm_read_ptr
#endif
#define SERIAL_ECHO_START()
#define SERIAL_ECHOLNPGM(str) Serial.println(F(str))
#define SERIAL_ECHOPGM(str) Serial.print(F(str))
#define SERIAL_ECHO_MSG(str) Serial.println(str)
#define SERIAL_ECHOLNPAIR(str, val) {Serial.print(F(str)); Serial.println(val);}
#define SERIAL_ECHOPAIR(str, val) {Serial.print(F(str)); Serial.print(val);}
#define safe_delay delay
// Define macros for compatibility
#define _CAT(a, ...) a ## __VA_ARGS__
#define SWITCH_ENABLED_ 1
#define ENABLED(b) _CAT(SWITCH_ENABLED_, b)
#define DISABLED(b) !ENABLED(b)
#define ANY(A,B) (ENABLED(A) || ENABLED(B))
#define EITHER(A,B) (ENABLED(A) || ENABLED(B))
#define BOTH(A,B) (ENABLED(A) && ENABLED(B))
#define NONE(A,B) (DISABLED(A) && DISABLED(B))
// Remove compiler warning on an unused variable
#ifndef UNUSED
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#define UNUSED(X) (void)X
#else
#define UNUSED(x) ((void)(x))
#endif
#endif
#endif // !__MARLIN_FIRMWARE__

View File

@ -0,0 +1,49 @@
/*****************
* bitmap_info.h *
*****************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#ifndef FORCEDINLINE
#define FORCEDINLINE __attribute__((always_inline)) inline
#endif
namespace FTDI {
// The following functions *must* be inlined since we are relying on the compiler to do
// substitution of the constants from the data structure rather than actually storing
// it in PROGMEM (which would fail, since we are not using pgm_read to read them).
// Plus, by inlining, all the equations are evaluated at compile-time as everything
// should be a constant.
typedef struct {
const uint8_t format;
const uint16_t linestride;
const uint8_t filter;
const uint8_t wrapx;
const uint8_t wrapy;
const uint32_t RAMG_offset;
const uint16_t width;
const uint16_t height;
} bitmap_info_t;
FORCEDINLINE uint32_t BITMAP_SOURCE (const bitmap_info_t& info) {return BITMAP_SOURCE (ftdi_memory_map::RAM_G + info.RAMG_offset);};
FORCEDINLINE uint32_t BITMAP_LAYOUT (const bitmap_info_t& info) {return BITMAP_LAYOUT (info.format, info.linestride, info.height);};
FORCEDINLINE uint32_t BITMAP_SIZE (const bitmap_info_t& info) {return BITMAP_SIZE (info.filter, info.wrapx, info.wrapy, info.width, info.height);}
}

View File

@ -0,0 +1,29 @@
/*************************
* command_processor.cpp *
*************************/
/****************************************************************************
* Written By Marcio Teixeira 2018 *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
CommandProcessor::btn_style_func_t *CommandProcessor::_btn_style_callback = CommandProcessor::default_button_style_func;
bool CommandProcessor::is_tracking = false;
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,434 @@
/***********************
* command_processor.h *
***********************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
typedef struct {
uint32_t bg;
uint32_t grad;
uint32_t fg;
uint32_t rgb;
} btn_colors;
// Disable TOUCH_UI_FIT_TEXT on a case-by-case basis
namespace FTDI {
constexpr uint16_t OPT_NOFIT = OPT_NOTICKS;
}
/**************************** Enhanced Command Processor **************************/
/* The CommandProcessor class wraps the CommandFifo with several features to make
* defining user interfaces much easier.
*
* - Implements chaining on all methods
* - Automatically adds text to button, toggle, text and keys.
* - Constrains all widgets to fit inside a box for ease of layout.
* - Font size is specified using a chained modifier.
* - Option argument is given the default OPT_3D value.
*/
class CommandProcessor : public CLCD::CommandFifo {
public:
static constexpr uint8_t STYLE_DISABLED = 0x80;
private:
static bool default_button_style_func(CommandProcessor &, uint8_t tag, uint8_t & /*style*/, uint16_t &options, bool) {
if (tag != 0 && FTDI::EventLoop::get_pressed_tag() == tag) {
options = FTDI::OPT_FLAT;
}
return false;
}
typedef bool btn_style_func_t(CommandProcessor &cmd, uint8_t tag, uint8_t &style, uint16_t &options, bool post);
static btn_style_func_t *_btn_style_callback;
static bool is_tracking;
int8_t _font = 26, _tag = 0;
uint8_t _style = 0;
protected:
// Returns the cannonical thickness of a widget (i.e. the height of a toggle element)
uint16_t widget_thickness() {
CLCD::FontMetrics fm(_font);
return fm.height * 20.0/16;
}
FORCEDINLINE void linear_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h, bool tracker = false) {
const uint16_t th = widget_thickness() / 2;
if (w > h) {
x += tracker ? th * 2.5 : th;
y += (h - th) / 2;
w -= tracker ? th * 5.0 : th * 2;
h = th;
} else {
x += (w - th) / 2;
y += tracker ? th * 2.5 : th;
w = th;
h -= tracker ? th * 5.0 : th * 2;
}
}
FORCEDINLINE uint16_t circular_widget_box(int16_t &x, int16_t &y, int16_t &w, int16_t &h) {
const uint16_t r = min(w,h) / 2;
x += w / 2;
y += h / 2;
w = 1;
h = 1;
return r;
}
public:
// Helper method for setting all colors at once
inline CommandProcessor& colors(const btn_colors &colors) {
cmd(FTDI::COLOR_RGB(colors.rgb))
.gradcolor(colors.grad)
.fgcolor(colors.fg)
.bgcolor(colors.bg);
return *this;
}
inline CommandProcessor& bitmap_size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height) {
cmd(FTDI::BITMAP_SIZE(filter, wrapx, wrapy, width, height));
#if FTDI_API_LEVEL >= 810
if (FTDI::ftdi_chip >= 810)
cmd(FTDI::BITMAP_SIZE_H(width >> 9, height >> 9));
#endif
return *this;
}
inline CommandProcessor& bitmap_layout(uint8_t format, uint16_t linestride, uint16_t height) {
cmd(FTDI::BITMAP_LAYOUT(format, linestride, height));
#if FTDI_API_LEVEL >= 810
if (FTDI::ftdi_chip >= 810)
cmd(FTDI::BITMAP_LAYOUT_H(linestride >> 10, height >> 9));
#endif
return *this;
}
inline CommandProcessor& set_button_style_callback(const btn_style_func_t *func) {
_btn_style_callback = func ? func : default_button_style_func;
return *this;
}
inline CommandProcessor& tag (uint8_t tag) {_tag = tag; cmd(FTDI::TAG(tag)); return *this;}
inline CommandProcessor& font (int16_t font) {_font = font; return *this;}
inline CommandProcessor& enabled (bool enabled=false) {
if (enabled)
_style &= ~STYLE_DISABLED;
else
_style |= STYLE_DISABLED;
return *this;
}
inline CommandProcessor& style (uint8_t style) {
_style = (_style & STYLE_DISABLED) | style;
return *this;
}
// Wrap all the CommandFifo routines to allow method chaining
inline CommandProcessor& cmd (uint32_t cmd32) {CLCD::CommandFifo::cmd(cmd32); return *this;}
inline CommandProcessor& cmd (void* data, uint16_t len) {CLCD::CommandFifo::cmd(data, len); return *this;}
inline CommandProcessor& execute() {CLCD::CommandFifo::execute(); return *this;}
inline CommandProcessor& fgcolor (uint32_t rgb) {CLCD::CommandFifo::fgcolor(rgb); return *this;}
inline CommandProcessor& bgcolor (uint32_t rgb) {CLCD::CommandFifo::bgcolor(rgb); return *this;}
inline CommandProcessor& gradcolor(uint32_t rgb) {CLCD::CommandFifo::gradcolor(rgb); return *this;}
inline CommandProcessor& snapshot (uint32_t ptr) {CLCD::CommandFifo::snapshot(ptr); return *this;}
inline CommandProcessor& loadimage(uint32_t ptr, uint32_t options)
{CLCD::CommandFifo::loadimage(ptr, options); return *this;}
inline CommandProcessor& sketch (int16_t x, int16_t y, uint16_t w, uint16_t h, uint32_t ptr, uint16_t format)
{CLCD::CommandFifo::sketch(x, y, w, h, ptr, format); return *this;}
inline CommandProcessor& screensaver () {CLCD::CommandFifo::screensaver(); return *this;}
#if FTDI_API_LEVEL >= 810
inline CommandProcessor& setbase (uint8_t base) {CLCD::CommandFifo::setbase(base); return *this;}
#endif
inline CommandProcessor& loadidentity () {CLCD::CommandFifo::loadidentity(); return *this;}
inline CommandProcessor& scale (int32_t sx, int32_t sy) {CLCD::CommandFifo::scale(sx,sy); return *this;}
inline CommandProcessor& rotate (int32_t a) {CLCD::CommandFifo::rotate(a); return *this;}
inline CommandProcessor& translate(int32_t tx, int32_t ty) {CLCD::CommandFifo::translate(tx,ty); return *this;}
inline CommandProcessor& setmatrix () {CLCD::CommandFifo::setmatrix(); return *this;}
inline CommandProcessor& stop () {CLCD::CommandFifo::stop(); return *this;}
inline CommandProcessor& memzero (uint32_t ptr, uint32_t size)
{CLCD::CommandFifo::memzero(ptr, size); return *this;}
inline CommandProcessor& memset (uint32_t ptr, uint32_t val, uint32_t size)
{CLCD::CommandFifo::memset(ptr, val, size); return *this;}
inline CommandProcessor& memcpy (uint32_t src, uint32_t dst, uint32_t size)
{CLCD::CommandFifo::memcpy(src, dst, size); return *this;}
inline CommandProcessor& memcrc (uint32_t ptr, uint32_t num, uint32_t result)
{CLCD::CommandFifo::memcrc(ptr, num, result); return *this;}
inline CommandProcessor& memwrite (uint32_t ptr, uint32_t value)
{CLCD::CommandFifo::memwrite(ptr, value); return *this;}
inline CommandProcessor& inflate (uint32_t ptr)
{CLCD::CommandFifo::inflate(ptr); return *this;}
inline CommandProcessor& getptr (uint32_t result)
{CLCD::CommandFifo::getptr(result); return *this;}
inline CommandProcessor& getprops (uint32_t ptr, uint32_t width, uint32_t height)
{CLCD::CommandFifo::getprops(ptr, width, height); return *this;}
#if FTDI_API_LEVEL >= 810
inline CommandProcessor& setbitmap (uint32_t ptr, uint16_t fmt, uint16_t w, uint16_t h)
{CLCD::CommandFifo::setbitmap(ptr,fmt,w,h); return *this;}
inline CommandProcessor& snapshot2 (uint32_t fmt, uint32_t ptr, int16_t x, int16_t y, uint16_t w, uint16_t h)
{CLCD::CommandFifo::snapshot2(fmt,ptr,x,y,w,h); return *this;}
inline CommandProcessor& mediafifo (uint32_t p, uint32_t s) {CLCD::CommandFifo::mediafifo(p, s); return *this;}
inline CommandProcessor& playvideo(uint32_t options) {CLCD::CommandFifo::playvideo(options); return *this;}
inline CommandProcessor& romfont(uint8_t font, uint8_t slot) {CLCD::CommandFifo::romfont(font, slot); return *this;}
#endif
inline CommandProcessor& gradient(int16_t x0, int16_t y0, uint32_t rgb0, int16_t x1, int16_t y1, uint32_t rgb1)
{CLCD::CommandFifo::gradient(x0,y0,rgb0,x1,y1,rgb1); return *this;}
inline CommandProcessor& rectangle(int16_t x, int16_t y, int16_t w, int16_t h) {
using namespace FTDI;
CLCD::CommandFifo::cmd(BEGIN(RECTS));
CLCD::CommandFifo::cmd(VERTEX2F(x * 16, y * 16));
CLCD::CommandFifo::cmd(VERTEX2F((x + w) * 16, (y + h) * 16));
return *this;
}
template<typename T>
FORCEDINLINE CommandProcessor& toggle(int16_t x, int16_t y, int16_t w, int16_t h, T text, bool state, uint16_t options = FTDI::OPT_3D) {
CLCD::FontMetrics fm(_font);
const int16_t widget_h = fm.height * 20.0 / 16;
//const int16_t outer_bar_r = widget_h / 2;
//const int16_t knob_r = outer_bar_r - 1.5;
// The y coordinate of the toggle is the baseline of the text,
// so we must introduce a fudge factor based on the line height to
// actually center the control.
const int16_t fudge_y = fm.height * 5 / 16;
CLCD::CommandFifo::toggle(x + h / 2, y + (h - widget_h) / 2 + fudge_y, w - h, _font, options, state);
CLCD::CommandFifo::str(text);
return *this;
}
CommandProcessor& toggle2(int16_t x, int16_t y, int16_t w, int16_t h, progmem_str no, progmem_str yes, bool state, uint16_t options = FTDI::OPT_3D) {
char text[strlen_P((const char *)no) + strlen_P((const char *)yes) + 2];
strcpy_P(text, (const char *)no);
strcat(text, "\xFF");
strcat_P(text, (const char *)yes);
return toggle(x, y, w, h, text, state, options);
}
// Contrained drawing routines. These constrain the widget inside a box for easier layout.
// The FORCEDINLINE ensures that the code is inlined so that all the math is done at compile time.
FORCEDINLINE CommandProcessor& track_linear(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) {
linear_widget_box(x, y, w, h, true);
CLCD::CommandFifo::track(x, y, w, h, tag);
is_tracking = true;
return *this;
}
FORCEDINLINE CommandProcessor& track_circular(int16_t x, int16_t y, int16_t w, int16_t h, int16_t tag) {
circular_widget_box(x,y, w, h);
CLCD::CommandFifo::track(x, y, w, h, tag);
is_tracking = true;
return *this;
}
uint8_t track_tag (uint16_t &value) {
if (is_tracking) {
if (FTDI::EventLoop::is_touch_held()) {
return CLCD::get_tracker(value);
} else {
CLCD::CommandFifo::track(0, 0, 0, 0, 0);
CLCD::CommandFifo::execute();
is_tracking = false;
}
}
return 0;
}
FORCEDINLINE CommandProcessor& clock(int16_t x, int16_t y, int16_t w, int16_t h, int16_t hr, int16_t m, int16_t s, int16_t ms, uint16_t options = FTDI::OPT_3D) {
const uint16_t r = circular_widget_box(x, y, w, h);
CLCD::CommandFifo::clock(x, y, r, options, hr, m, s, ms);
return *this;
}
FORCEDINLINE CommandProcessor& gauge(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t major, uint16_t minor, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
const uint16_t r = circular_widget_box(x, y, w, h);
CLCD::CommandFifo::gauge(x, y, r, options, major, minor, val, range);
return *this;
}
FORCEDINLINE CommandProcessor& dial(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t options = FTDI::OPT_3D) {
const uint16_t r = circular_widget_box(x, y, w, h);
CLCD::CommandFifo::dial(x, y, r, options, val);
return *this;
}
FORCEDINLINE CommandProcessor& slider(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
linear_widget_box(x, y, w, h);
CLCD::CommandFifo::slider(x, y, w, h, options, val, range);
return *this;
}
FORCEDINLINE CommandProcessor& progress(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t range, uint16_t options = FTDI::OPT_3D) {
linear_widget_box(x, y, w, h);
CLCD::CommandFifo::progress(x, y, w, h, options, val, range);
return *this;
}
FORCEDINLINE CommandProcessor& scrollbar(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t val, uint16_t size, uint16_t range, uint16_t options = 0) {
linear_widget_box(x, y, w, h);
CLCD::CommandFifo::scrollbar(x, y, w, h, options, val, size, range);
return *this;
}
void apply_text_alignment(int16_t &x, int16_t &y, int16_t w, int16_t h, uint16_t options) {
using namespace FTDI;
x += ((options & OPT_CENTERX) ? w/2 : ((options & OPT_RIGHTX) ? w : 0));
y += ((options & OPT_CENTERY) ? h/2 : h);
}
// Reduce font size until text fits the enclosing box.
template<typename T>
int8_t apply_fit_text(int16_t w, int16_t h, T text) {
using namespace FTDI;
int8_t font = _font;
#ifdef TOUCH_UI_USE_UTF8
const bool is_utf8 = has_utf8_chars(text);
#endif
for (;font >= 26;) {
int16_t width, height;
#ifdef TOUCH_UI_USE_UTF8
if (is_utf8) {
width = get_utf8_text_width(text, font_size_t::from_romfont(font));
height = font_size_t::from_romfont(font).get_height();
} else
#endif
{
CLCD::FontMetrics fm(font);
width = fm.get_text_width(text);
height = fm.height;
}
if (width < w && height < h) break;
font--;
}
return font;
}
CommandProcessor& number(int16_t x, int16_t y, int16_t w, int16_t h, int32_t n, uint16_t options = FTDI::OPT_CENTER) {
using namespace FTDI;
apply_text_alignment(x, y, w, h, options);
CLCD::CommandFifo::number(x, y, _font, options, n);
return *this;
}
template<typename T>
uint16_t text_width(T text) {
using namespace FTDI;
#ifdef TOUCH_UI_USE_UTF8
if (has_utf8_chars(text))
return get_utf8_text_width(text, font_size_t::from_romfont(_font));
#endif
CLCD::FontMetrics fm(_font);
return fm.get_text_width(text);
}
template<typename T>
CommandProcessor& text(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_CENTER) {
using namespace FTDI;
apply_text_alignment(x, y, w, h, options);
#ifdef TOUCH_UI_FIT_TEXT
const int8_t font = (options & OPT_NOFIT) ? _font : apply_fit_text(w, h, text);
#else
const int8_t font = _font;
#endif
#ifdef TOUCH_UI_USE_UTF8
if (has_utf8_chars(text))
draw_utf8_text(*this, x, y, text, font_size_t::from_romfont(font), options);
else
#endif
{
CLCD::CommandFifo::text(x, y, font, options);
CLCD::CommandFifo::str(text);
}
return *this;
}
FORCEDINLINE CommandProcessor& icon(int16_t x, int16_t y, int16_t w, int16_t h, const FTDI::bitmap_info_t& info, const float scale = 1) {
using namespace FTDI;
cmd(BEGIN(BITMAPS));
if (scale != 1) {
cmd(BITMAP_TRANSFORM_A(uint32_t(float(256)/scale)));
cmd(BITMAP_TRANSFORM_E(uint32_t(float(256)/scale)));
}
cmd(BITMAP_SIZE(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale));
cmd(VERTEX2F((x + w/2 - info.width*scale/2)*16, (y + h/2 - info.height*scale/2)*16));
if (scale != 1) {
cmd(BITMAP_TRANSFORM_A(256));
cmd(BITMAP_TRANSFORM_E(256));
}
return *this;
}
template<typename T>
CommandProcessor& button(int16_t x, int16_t y, int16_t w, int16_t h, T text, uint16_t options = FTDI::OPT_3D) {
using namespace FTDI;
bool styleModified = false;
if (_btn_style_callback) styleModified = _btn_style_callback(*this, _tag, _style, options, false);
#ifdef TOUCH_UI_FIT_TEXT
const int8_t font = (options & OPT_NOFIT) ? _font : apply_fit_text(w, h, text);
#else
const int8_t font = _font;
#endif
CLCD::CommandFifo::button(x, y, w, h, font, options);
#ifdef TOUCH_UI_USE_UTF8
if (has_utf8_chars(text)) {
CLCD::CommandFifo::str(F(""));
apply_text_alignment(x, y, w, h, OPT_CENTER);
if (!(options & FTDI::OPT_FLAT)) {
// Reproduce the black "shadow" the FTDI adds to the button label
CLCD::CommandFifo::cmd(SAVE_CONTEXT());
CLCD::CommandFifo::cmd(COLOR_RGB(0x00000));
draw_utf8_text(*this, x-1, y-1, text, font_size_t::from_romfont(font), OPT_CENTER);
CLCD::CommandFifo::cmd(RESTORE_CONTEXT());
}
// Draw the button label
draw_utf8_text(*this, x, y, text, font_size_t::from_romfont(font), OPT_CENTER);
}
else
#endif
CLCD::CommandFifo::str(text);
if (_btn_style_callback && styleModified) _btn_style_callback(*this, _tag, _style, options, true);
return *this;
}
template<typename T>
CommandProcessor& keys(int16_t x, int16_t y, int16_t w, int16_t h, T keys, uint16_t options = FTDI::OPT_3D) {
CLCD::CommandFifo::keys(x, y, w, h, _font, options);
CLCD::CommandFifo::str(keys);
return *this;
}
FORCEDINLINE CommandProcessor& spinner(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t style = 0, uint16_t scale = 0) {
circular_widget_box(x, y, w, h);
CLCD::CommandFifo::spinner(x, y, style, scale);
return *this;
}
};

View File

@ -0,0 +1,175 @@
/****************
* dl_cache.cpp *
****************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
/* The Display List Cache mechanism stores the display list corresponding
* to a menu into RAM_G so that on subsequent calls drawing the menu does
* not require as much SPI traffic.
*
* Layout of Cache memory:
*
* The cache memory begins with a table at
* DL_CACHE_START: each table entry contains
* an address and size for a cached DL slot.
*
* Immediately following the table is the
* DL_FREE_ADDR, which points to free cache
* space; following this is occupied DL space,
* and after that free space that is yet to
* be used.
*
* location data sizeof
*
* DL_CACHE_START slot0_addr 4
* slot0_size 4
* slot1_addr 4
* slot1_size 4
* ...
* slotN_addr 4
* slotN_size 4
* DL_FREE_ADDR dl_free_ptr 4
* cached data
* ...
* dl_free_ptr empty space
* ...
*/
#define DL_CACHE_START MAP::RAM_G_SIZE - 0xFFFF
#define DL_FREE_ADDR DL_CACHE_START + DL_CACHE_SLOTS * 8
using namespace FTDI;
// The init function ensures all cache locations are marked as empty
void DLCache::init() {
CLCD::mem_write_32(DL_FREE_ADDR, DL_FREE_ADDR + 4);
for(uint8_t slot = 0; slot < DL_CACHE_SLOTS; slot++) {
save_slot(slot, 0, 0);
}
}
bool DLCache::has_data() {
return dl_size != 0;
}
bool DLCache::wait_until_idle() {
const unsigned long startTime = millis();
do {
if ((millis() - startTime) > 250) {
SERIAL_ECHO_MSG("Timeout on DL_Cache::Wait_Until_Idle()");
CLCD::CommandFifo::reset();
return false;
}
#ifdef __MARLIN_FIRMWARE__
ExtUI::yield();
#endif
} while (CLCD::CommandFifo::is_processing());
return true;
}
/* This caches the current display list in RAMG so
* that it can be appended later. The memory is
* dynamically allocated following DL_FREE_ADDR.
*
* If num_bytes is provided, then that many bytes
* will be reserved so that the cache may be re-written
* later with potentially a bigger DL.
*/
bool DLCache::store(uint32_t num_bytes /* = 0*/) {
CLCD::CommandFifo cmd;
// Execute any commands already in the FIFO
cmd.execute();
if (!wait_until_idle())
return false;
// Figure out how long the display list is
uint32_t new_dl_size = CLCD::mem_read_32(REG::CMD_DL) & 0x1FFF;
uint32_t free_space = 0;
uint32_t dl_alloc = 0;
if (dl_addr == 0) {
// If we are allocating new space...
dl_addr = CLCD::mem_read_32(DL_FREE_ADDR);
free_space = MAP::RAM_G_SIZE - dl_addr;
dl_alloc = num_bytes ?: new_dl_size;
dl_size = new_dl_size;
} else {
// Otherwise, we can only store as much space
// as was previously allocated.
free_space = num_bytes ?: dl_size;
dl_alloc = 0;
dl_size = new_dl_size;
}
if (dl_size > free_space) {
// Not enough memory to cache the display list.
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOPAIR ("Not enough space in GRAM to cache display list, free space: ", free_space);
SERIAL_ECHOLNPAIR(" Required: ", dl_size);
#endif
return false;
} else {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOPAIR ("Saving DL to RAMG cache, bytes: ", dl_size);
SERIAL_ECHOLNPAIR(" Free space: ", free_space);
#endif
cmd.memcpy(dl_addr, MAP::RAM_DL, dl_size);
cmd.execute();
save_slot(dl_slot, dl_addr, dl_size);
if (dl_alloc > 0) {
// If we allocated space dynamically, then adjust dl_free_addr.
CLCD::mem_write_32(DL_FREE_ADDR, dl_addr + dl_alloc);
}
return true;
}
}
void DLCache::save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size) {
CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 0, dl_addr);
CLCD::mem_write_32(DL_CACHE_START + dl_slot * 8 + 4, dl_size);
}
void DLCache::load_slot() {
dl_addr = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 0);
dl_size = CLCD::mem_read_32(DL_CACHE_START + dl_slot * 8 + 4);
}
void DLCache::append() {
CLCD::CommandFifo cmd;
cmd.append(dl_addr, dl_size);
#if ENABLED(TOUCH_UI_DEBUG)
cmd.execute();
wait_until_idle();
SERIAL_ECHO_START();
SERIAL_ECHOPAIR ("Appending to DL from RAMG cache, bytes: ", dl_size);
SERIAL_ECHOLNPAIR(" REG_CMD_DL: ", CLCD::mem_read_32(REG::CMD_DL));
#endif
}
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,69 @@
/**************
* dl_cache.h *
**************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/******************* DISPLAY LIST CACHE MANAGEMENT ************************/
/* The Display List Cache mechanism stores the display list corresponding
* to a menu into RAM_G so that on subsequent calls drawing the menu does
* not require as much SPI traffic. Dynamic content, such as indicators,
* should not be cached.
*
* The DLCache can be used like so:
*
* void some_function() {
* DLCache dlcache(UNIQUE_ID);
*
* if (dlcache.hasData()) {
* dlcache.append();
* } else {
* // Add stuff to the DL
* dlcache.store();
* }
*/
class DLCache {
private:
typedef FTDI::ftdi_registers REG;
typedef FTDI::ftdi_memory_map MAP;
uint8_t dl_slot;
uint32_t dl_addr;
uint16_t dl_size;
void load_slot();
static void save_slot(uint8_t dl_slot, uint32_t dl_addr, uint32_t dl_size);
bool wait_until_idle();
public:
static void init();
DLCache(uint8_t slot) {
dl_slot = slot;
load_slot();
}
bool has_data();
bool store(uint32_t num_bytes = 0);
void append();
};
#define DL_CACHE_SLOTS 250

View File

@ -0,0 +1,232 @@
/******************
* event_loop.cpp *
******************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
using namespace FTDI;
enum {
UNPRESSED = 0x00
};
tiny_timer_t touch_timer;
UIData::flags_t UIData::flags;
uint8_t pressed_tag = UNPRESSED;
uint8_t UIData::get_persistent_data_mask() {
// A bit mask for flags that should be stored to the EEPROM.
// Others are considered temporarily values that need not be
// saved.
constexpr flags_t persistent_flags = {
bits: {
touch_start_sound: true,
touch_end_sound: true,
touch_repeat_sound: true,
show_animations: true
}
};
return persistent_flags.value;
}
void UIData::reset_persistent_data() {
// Default values for persistent data
constexpr flags_t default_flags = {
bits: {
touch_start_sound: true,
touch_end_sound: true,
touch_repeat_sound: true,
show_animations: true,
touch_debouncing: false,
ignore_unpress: false
}
};
flags.value = default_flags.value;
}
uint8_t UIData::get_persistent_data() {
return flags.value & get_persistent_data_mask();
}
void UIData::set_persistent_data(uint8_t value) {
flags.value = value & get_persistent_data_mask();
}
void UIData::enable_touch_sounds(bool enabled) {
UIData::flags.bits.touch_start_sound = enabled;
UIData::flags.bits.touch_end_sound = enabled;
UIData::flags.bits.touch_repeat_sound = enabled;
}
bool UIData::touch_sounds_enabled() {
return UIData::flags.bits.touch_start_sound || UIData::flags.bits.touch_end_sound || UIData::flags.bits.touch_repeat_sound;
}
void UIData::enable_animations(bool enabled) {
UIData::flags.bits.show_animations = enabled;
}
bool UIData::animations_enabled() {
return UIData::flags.bits.show_animations;
}
namespace FTDI {
uint8_t EventLoop::get_pressed_tag() {
return pressed_tag;
}
bool EventLoop::is_touch_held() {
return pressed_tag != 0;
}
/**
* process_events(): Process events from the touch panel.
*
* This function consists of a state machine that accomplishes the following:
*
* - Reads the tag register from the touch panel
* - Dispatches onTouchStart and onTouchEnd events to the active screen.
* - Handles auto-repetition by sending onTouchHeld to the active screen periodically.
* - Plays touch feedback "click" sounds when appropriate.
* - Performs debouncing to supress spurious touch events.
*
*/
void EventLoop::process_events() {
// If the LCD is processing commands, don't check
// for tags since they may be changing and could
// cause spurious events.
if (!touch_timer.elapsed(TOUCH_UPDATE_INTERVAL) || CLCD::CommandFifo::is_processing()) {
return;
}
const uint8_t tag = CLCD::get_tag();
switch (pressed_tag) {
case UNPRESSED:
if (tag != 0) {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Touch start: ", tag);
#endif
pressed_tag = tag;
current_screen.onRefresh();
// When the user taps on a button, activate the onTouchStart handler
const uint8_t lastScreen = current_screen.getScreen();
if (current_screen.onTouchStart(tag)) {
touch_timer.start();
if (UIData::flags.bits.touch_start_sound) sound.play(press_sound);
}
if (lastScreen != current_screen.getScreen()) {
// In the case in which a touch event triggered a new screen to be
// drawn, we don't issue a touchEnd since it would be sent to the
// wrong screen.
UIData::flags.bits.ignore_unpress = true;
} else {
UIData::flags.bits.ignore_unpress = false;
}
} else {
touch_timer.start();
}
break;
default: // PRESSED
if (!UIData::flags.bits.touch_debouncing) {
if (tag == pressed_tag) {
// The user is holding down a button.
if (touch_timer.elapsed(1000 / TOUCH_REPEATS_PER_SECOND)) {
if (current_screen.onTouchHeld(tag)) {
current_screen.onRefresh();
if (UIData::flags.bits.touch_repeat_sound) sound.play(repeat_sound);
}
touch_timer.start();
}
}
else if (tag == 0) {
touch_timer.start();
UIData::flags.bits.touch_debouncing = true;
}
}
else {
// Debouncing...
if (tag == pressed_tag) {
// If while debouncing, we detect a press, then cancel debouncing.
UIData::flags.bits.touch_debouncing = false;
}
else if (touch_timer.elapsed(DEBOUNCE_PERIOD)) {
UIData::flags.bits.touch_debouncing = false;
if (UIData::flags.bits.ignore_unpress) {
UIData::flags.bits.ignore_unpress = false;
pressed_tag = UNPRESSED;
break;
}
if (UIData::flags.bits.touch_end_sound) sound.play(unpress_sound);
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Touch end: ", tag);
#endif
const uint8_t saved_pressed_tag = pressed_tag;
pressed_tag = UNPRESSED;
current_screen.onTouchEnd(saved_pressed_tag);
current_screen.onRefresh();
}
}
break;
} // switch (pressed_tag)
} // processEvents()
void EventLoop::setup() {
CLCD::init();
DLCache::init();
UIData::reset_persistent_data();
current_screen.start();
}
void EventLoop::loop() {
sound.onIdle();
/**
* Guard against re-entry of UI methods, which can
* crash. Re-entry can happen because some functions
* (e.g. planner.synchronize) call idle().
*/
if (!UIData::flags.bits.prevent_reentry) {
UIData::flags.bits.prevent_reentry = true;
current_screen.onIdle();
process_events();
UIData::flags.bits.prevent_reentry = false;
}
}
} // namespace FTDI
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,74 @@
/****************
* event_loop.h *
****************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#define STATUS_UPDATE_INTERVAL 1000
#define TOUCH_UPDATE_INTERVAL 50
#define TOUCH_REPEATS_PER_SECOND 4
#define DEBOUNCE_PERIOD 150
class UIData {
private:
typedef union {
struct {
uint8_t touch_start_sound : 1;
uint8_t touch_end_sound : 1;
uint8_t touch_repeat_sound : 1;
uint8_t show_animations : 1;
uint8_t touch_debouncing : 1;
uint8_t ignore_unpress : 1;
uint8_t prevent_reentry : 1;
} bits;
uint8_t value;
} flags_t;
public:
static flags_t flags;
static uint8_t get_persistent_data_mask();
static uint8_t get_persistent_data();
static void set_persistent_data(uint8_t value);
static void reset_persistent_data();
static void enable_touch_sounds(bool enabled);
static bool touch_sounds_enabled();
static void enable_animations(bool enabled);
static bool animations_enabled();
};
namespace FTDI {
class EventLoop {
private:
static constexpr FTDI::effect_t press_sound = FTDI::CHACK;
static constexpr FTDI::effect_t repeat_sound = FTDI::CHACK;
static constexpr FTDI::effect_t unpress_sound = FTDI::POP;
static void process_events();
public:
static void setup();
static void loop();
static uint8_t get_pressed_tag();
static bool is_touch_held();
};
}

View File

@ -0,0 +1,50 @@
/*******************
* ftdi_extended.h *
*******************/
/****************************************************************************
* Written By Mark Pelletier 2019 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 201( - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "../compat.h"
#include "../basic/ftdi_basic.h"
#ifndef __MARLIN_FIRMWARE__
#define FTDI_EXTENDED
#endif
#ifdef FTDI_EXTENDED
#include "unicode/font_size_t.h"
#include "unicode/unicode.h"
#include "unicode/standard_char_set.h"
#include "unicode/western_char_set.h"
#include "unicode/font_bitmaps.h"
#include "rgb_t.h"
#include "bitmap_info.h"
#include "tiny_timer.h"
#include "grid_layout.h"
#include "dl_cache.h"
#include "event_loop.h"
#include "command_processor.h"
#include "screen_types.h"
#include "sound_player.h"
#include "sound_list.h"
#include "polygon.h"
#include "text_box.h"
#endif

View File

@ -0,0 +1,98 @@
/*****************
* grid_layout.h *
*****************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/* The grid layout macros allow buttons to be arranged on a grid so
* that their locations become independent of the display size. The
* layout model is similar to that of HTML TABLEs.
*
* These macros are meant to be evaluated into constants at compile
* time, so resolution independence can be as efficient as using
* hard-coded coordinates.
*/
// Margin defines the margin (in pixels) on each side of a button in
// the layout
#ifdef TOUCH_UI_800x480
#define MARGIN_L 5
#define MARGIN_R 5
#define MARGIN_T 5
#define MARGIN_B 5
#define MARGIN_DEFAULT 5
#else
#define MARGIN_L 3
#define MARGIN_R 3
#define MARGIN_T 3
#define MARGIN_B 3
#define MARGIN_DEFAULT 3
#endif
// EDGE_R adds some black space on the right edge of the display
// This shifts some of the screens left to visually center them.
#define EDGE_R 0
// GRID_X and GRID_Y computes the positions of the divisions on
// the layout grid.
#define GRID_X(x) ((x)*(FTDI::display_width-EDGE_R)/GRID_COLS)
#define GRID_Y(y) ((y)*FTDI::display_height/GRID_ROWS)
// BTN_X, BTN_Y, BTN_W and BTN_X returns the top-left and width
// and height of a button, taking into account the button margins.
#define BTN_X(x) (GRID_X((x)-1) + MARGIN_L)
#define BTN_Y(y) (GRID_Y((y)-1) + MARGIN_T)
#define BTN_W(w) (GRID_X(w) - MARGIN_L - MARGIN_R)
#define BTN_H(h) (GRID_Y(h) - MARGIN_T - MARGIN_B)
// Abbreviations for common phrases, to allow a button to be
// defined in one line of source.
#define BTN_POS(x,y) BTN_X(x), BTN_Y(y)
#define BTN_SIZE(w,h) BTN_W(w), BTN_H(h)
// Draw a reference grid for ease of spacing out widgets.
#define DRAW_LAYOUT_GRID \
{ \
cmd.cmd(LINE_WIDTH(4)); \
for(int i = 1; i <= GRID_COLS; i++) { \
cmd.cmd(BEGIN(LINES)); \
cmd.cmd(VERTEX2F(GRID_X(i) *16, 0 *16)); \
cmd.cmd(VERTEX2F(GRID_X(i) *16, FTDI::display_height *16)); \
} \
for(int i = 1; i < GRID_ROWS; i++) { \
cmd.cmd(BEGIN(LINES)); \
cmd.cmd(VERTEX2F(0 *16, GRID_Y(i) *16)); \
cmd.cmd(VERTEX2F(FTDI::display_width *16, GRID_Y(i) *16)); \
} \
cmd.cmd(LINE_WIDTH(16)); \
}
namespace FTDI {
#ifdef TOUCH_UI_PORTRAIT
constexpr uint16_t display_width = Vsize;
constexpr uint16_t display_height = Hsize;
#else
constexpr uint16_t display_width = Hsize;
constexpr uint16_t display_height = Vsize;
#endif
}

View File

@ -0,0 +1,96 @@
/*************
* polygon.h *
*************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/**
* The Polygon class helps drawing filled or stroked polygons on the FTDI EVE:
*
* CommandProcessor cmd;
* cmd.cmd(COLOR_RGB(0x00FF00));
*
* Polygon p(cmd);
* p.begin_fill();
* p.begin_loop();
* p(10,10);
* p(20,10);
* p(20,20);
* p(10,20);
* p.end_loop();
* p.begin_loop();
* ... // Additional closed paths
* p.end_loop();
* ...
* p.end_fill();
*
* Based on the example from "Applicaton Note AN_334, FT801 Polygon Application":
*
* https://brtchip.com/wp-content/uploads/Support/Documentation/Application_Notes/ICs/EVE/AN_334-FT801_Polygon_Application.pdf
*/
namespace FTDI {
class Polygon {
private:
FTDI::begin_t path_initiator = FTDI::LINE_STRIP;
public:
CommandProcessor &cmd;
Polygon(CommandProcessor &c) : cmd(c) {}
void begin_fill() {
using namespace FTDI;
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(TAG_MASK(0));
cmd.cmd(CLEAR(0,1,0));
cmd.cmd(COLOR_MASK(0,0,0,0));
cmd.cmd(STENCIL_OP(STENCIL_OP_KEEP, STENCIL_OP_INVERT));
cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_ALWAYS, 255, 255));
// Drawing the edge strip along scan lines
// seems to yield the best performance
#ifdef TOUCH_UI_PORTRAIT
path_initiator = EDGE_STRIP_B;
#else
path_initiator = EDGE_STRIP_R;
#endif
}
// Specify a clipping rectangle to paint fewer pixels and reduce rendering time, otherwise all pixels will be painted.
void end_fill(const int16_t x1 = 0, const int16_t y1 = 0, const int16_t x2 = display_width * 16, const int16_t y2 = display_height * 16) {
using namespace FTDI;
cmd.cmd(RESTORE_CONTEXT());
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_NOTEQUAL, 0, 255));
cmd.cmd(BEGIN(RECTS));
cmd.cmd(VERTEX2F(x1, y1));
cmd.cmd(VERTEX2F(x2, y2));
cmd.cmd(RESTORE_CONTEXT());
}
void begin_stroke() {path_initiator = FTDI::LINE_STRIP;}
void begin_loop() {cmd.cmd(FTDI::BEGIN(path_initiator));}
void end_stroke() {}
void end_loop() {}
void operator()(const uint16_t x, const uint16_t y) {cmd.cmd(FTDI::VERTEX2F(x, y));}
};
}

View File

@ -0,0 +1,84 @@
/***********
* rgb_t.h *
***********/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/**
* Implementation of hsl_to_rgb as constexpr functions based on:
*
* https://www.rapidtables.com/convert/color/hsl-to-rgb.html
*/
constexpr float _hsl_fmod(float x, float y) {
return x - int(x/y)*y;
}
constexpr float _hsl_c(float, float S, float L) {
return (1.0f - fabs(2*L-1.0f)) * S;
}
constexpr float _hsl_x(float H, float S, float L) {
return _hsl_c(H,S,L) * (1.0f - fabs(_hsl_fmod(H/60, 2) - 1));
}
constexpr float _hsl_m(float H, float S, float L) {
return L - _hsl_c(H,S,L)/2;
}
constexpr float _hsl_rgb(float H, float S, float L, float r, float g, float b) {
return ((uint32_t((r + _hsl_m(H,S,L))*255+0.5) << 16) |
(uint32_t((g + _hsl_m(H,S,L))*255+0.5) << 8) |
(uint32_t((b + _hsl_m(H,S,L))*255+0.5) << 0));
}
constexpr uint32_t hsl_to_rgb(float H, float S, float L) {
return (H < 60) ? _hsl_rgb(H,S,L,_hsl_c(H,S,L), _hsl_x(H,S,L), 0) :
(H < 120) ? _hsl_rgb(H,S,L,_hsl_x(H,S,L), _hsl_c(H,S,L), 0) :
(H < 180) ? _hsl_rgb(H,S,L, 0, _hsl_c(H,S,L), _hsl_x(H,S,L)) :
(H < 240) ? _hsl_rgb(H,S,L, 0, _hsl_x(H,S,L), _hsl_c(H,S,L)) :
(H < 300) ? _hsl_rgb(H,S,L,_hsl_x(H,S,L), 0, _hsl_c(H,S,L)) :
_hsl_rgb(H,S,L,_hsl_c(H,S,L), 0, _hsl_x(H,S,L));
}
/**
* Structure for RGB colors
*/
struct rgb_t {
union {
struct {
uint8_t b,g,r,a;
};
uint32_t packed;
};
rgb_t() : packed(0) {}
rgb_t(uint32_t rgb) : packed(rgb) {}
rgb_t(uint8_t r, uint8_t g, uint8_t b) : b(b), g(g), r(r), a(0) {}
operator uint32_t() const {return packed;};
static void lerp(float t, const rgb_t a, const rgb_t b, rgb_t &c) {
c.r = a.r + t * (b.r - a.r);
c.g = a.g + t * (b.g - a.g);
c.b = a.b + t * (b.b - a.b);
}
uint8_t luminance() const {return 0.299*r + 0.587*g + 0.114*b;}
};

View File

@ -0,0 +1,106 @@
/******************
* screen_types.h *
******************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
/********************** VIRTUAL DISPATCH DATA TYPE ******************************/
uint8_t ScreenRef::lookupScreen(onRedraw_func_t onRedraw_ptr) {
for(uint8_t type = 0; type < functionTableSize; type++) {
if (GET_METHOD(type, onRedraw) == onRedraw_ptr) {
return type;
}
}
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOPAIR("Screen not found: ", (uintptr_t) onRedraw_ptr);
#endif
return 0xFF;
}
void ScreenRef::setScreen(onRedraw_func_t onRedraw_ptr) {
uint8_t type = lookupScreen(onRedraw_ptr);
if (type != 0xFF) {
setType(type);
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("New screen: ", type);
#endif
}
}
void ScreenRef::initializeAll() {
for(uint8_t type = 0; type < functionTableSize; type++) {
GET_METHOD(type, onStartup)();
}
}
/********************** SCREEN STACK ******************************/
void ScreenStack::start() {
initializeAll();
onEntry();
}
void ScreenStack::push(onRedraw_func_t onRedraw_ptr) {
stack[3] = stack[2];
stack[2] = stack[1];
stack[1] = stack[0];
stack[0] = lookupScreen(onRedraw_ptr);
}
void ScreenStack::push() {
stack[3] = stack[2];
stack[2] = stack[1];
stack[1] = stack[0];
stack[0] = getType();
}
void ScreenStack::pop() {
setType(stack[0]);
forget();
}
void ScreenStack::forget() {
stack[0] = stack[1];
stack[1] = stack[2];
stack[2] = stack[3];
stack[3] = 0;
}
void ScreenStack::goTo(onRedraw_func_t s) {
push();
onExit();
setScreen(s);
onEntry();
}
void ScreenStack::goBack() {
onExit();
pop();
onEntry();
}
ScreenStack current_screen;
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,229 @@
/********************
* screen_types.cpp *
********************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
typedef enum {
BACKGROUND = 1,
FOREGROUND = 2,
BOTH = 3
} draw_mode_t;
/********************** VIRTUAL DISPATCH DATA TYPE ******************************/
// True virtual classes are extremely expensive on the Arduino
// as the compiler stores the virtual function tables in RAM.
// We invent a data type called ScreenRef that gives us
// polymorphism by mapping an ID to virtual methods on various
// classes. This works by keeping a table in PROGMEM of pointers
// to static methods.
#define DECL_SCREEN(className) { \
className::onStartup, \
className::onEntry, \
className::onExit, \
className::onIdle, \
className::onRefresh, \
className::onRedraw, \
className::onTouchStart, \
className::onTouchHeld, \
className::onTouchEnd \
}
#define GET_METHOD(type, method) reinterpret_cast<method##_func_t*>(pgm_read_ptr_far(&functionTable[type].method##_ptr))
#define SCREEN_TABLE PROGMEM const ScreenRef::table_t ScreenRef::functionTable[] =
#define SCREEN_TABLE_POST const uint8_t ScreenRef::functionTableSize = sizeof(ScreenRef::functionTable)/sizeof(ScreenRef::functionTable[0]);
class ScreenRef {
protected:
typedef void onStartup_func_t();
typedef void onEntry_func_t();
typedef void onExit_func_t();
typedef void onIdle_func_t();
typedef void onRefresh_func_t();
typedef void onRedraw_func_t(draw_mode_t);
typedef bool onTouchStart_func_t(uint8_t);
typedef bool onTouchHeld_func_t(uint8_t);
typedef bool onTouchEnd_func_t(uint8_t);
private:
typedef struct {
onStartup_func_t *onStartup_ptr;
onEntry_func_t *onEntry_ptr;
onExit_func_t *onExit_ptr;
onIdle_func_t *onIdle_ptr;
onRefresh_func_t *onRefresh_ptr;
onRedraw_func_t *onRedraw_ptr;
onTouchStart_func_t *onTouchStart_ptr;
onTouchHeld_func_t *onTouchHeld_ptr;
onTouchEnd_func_t *onTouchEnd_ptr;
} table_t;
uint8_t type = 0;
static PROGMEM const table_t functionTable[];
static const uint8_t functionTableSize;
public:
uint8_t getType() {return type;}
void setType(uint8_t t) {
type = t;
}
uint8_t lookupScreen(onRedraw_func_t onRedraw_ptr);
void setScreen(onRedraw_func_t onRedraw_ptr);
void onStartup() {GET_METHOD(type, onStartup)();}
void onEntry() {GET_METHOD(type, onEntry)();}
void onExit() {GET_METHOD(type, onExit)();}
void onIdle() {GET_METHOD(type, onIdle)();}
void onRefresh() {GET_METHOD(type, onRefresh)();}
void onRedraw(draw_mode_t dm) {GET_METHOD(type, onRedraw)(dm);}
bool onTouchStart(uint8_t tag) {return GET_METHOD(type, onTouchStart)(tag);}
bool onTouchHeld(uint8_t tag) {return GET_METHOD(type, onTouchHeld)(tag);}
bool onTouchEnd(uint8_t tag) {return GET_METHOD(type, onTouchEnd)(tag);}
void initializeAll();
};
/********************** SCREEN STACK ******************************/
// To conserve dynamic memory, the screen stack is hard-coded to
// have four values, allowing a menu of up to four levels.
class ScreenStack : public ScreenRef {
private:
uint8_t stack[4];
public:
void start();
void push(onRedraw_func_t);
void push();
void pop();
void forget();
void goTo(onRedraw_func_t);
void goBack();
uint8_t peek() {return stack[0];}
uint8_t getScreen() {return getType();}
};
extern ScreenStack current_screen;
/********************** BASE SCREEN CLASS ******************************/
/* UIScreen is the base class for all user interface screens.
*/
class UIScreen {
public:
static void onStartup() {}
static void onEntry() {current_screen.onRefresh();}
static void onExit() {}
static void onIdle() {}
static bool onTouchStart(uint8_t) {return true;}
static bool onTouchHeld(uint8_t) {return false;}
static bool onTouchEnd(uint8_t) {return true;}
};
#define PUSH_SCREEN(screen) current_screen.push(screen::onRedraw);
#define GOTO_SCREEN(screen) current_screen.goTo(screen::onRedraw);
#define GOTO_PREVIOUS() current_screen.goBack();
#define AT_SCREEN(screen) (current_screen.getType() == current_screen.lookupScreen(screen::onRedraw))
#define IS_PARENT_SCREEN(screen) (current_screen.peek() == current_screen.lookupScreen(screen::onRedraw))
/************************** CACHED VS UNCHACHED SCREENS ***************************/
class UncachedScreen {
public:
static void onRefresh() {
using namespace FTDI;
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART);
#ifdef TOUCH_UI_USE_UTF8
load_utf8_bitmaps(cmd);
#endif
current_screen.onRedraw(BOTH);
cmd.cmd(DL::DL_DISPLAY);
cmd.cmd(CMD_SWAP);
cmd.execute();
}
};
template<uint8_t DL_SLOT,uint32_t DL_SIZE = 0>
class CachedScreen {
protected:
static bool storeBackground() {
DLCache dlcache(DL_SLOT);
if (!dlcache.store(DL_SIZE)) {
SERIAL_ECHO_MSG("CachedScreen::storeBackground() failed: not enough DL cache space");
return false;
}
return true;
}
static void repaintBackground() {
using namespace FTDI;
DLCache dlcache(DL_SLOT);
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART);
#ifdef TOUCH_UI_USE_UTF8
load_utf8_bitmaps(cmd);
#endif
current_screen.onRedraw(BACKGROUND);
dlcache.store(DL_SIZE);
}
public:
static void onRefresh() {
#if ENABLED(TOUCH_UI_DEBUG)
const uint32_t start_time = millis();
#endif
using namespace FTDI;
DLCache dlcache(DL_SLOT);
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART);
if (dlcache.has_data()) {
dlcache.append();
} else {
#ifdef TOUCH_UI_USE_UTF8
load_utf8_bitmaps(cmd);
#endif
current_screen.onRedraw(BACKGROUND);
dlcache.store(DL_SIZE);
}
current_screen.onRedraw(FOREGROUND);
cmd.cmd(DL::DL_DISPLAY);
cmd.cmd(CMD_SWAP);
cmd.execute();
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHOLNPAIR("Time to draw screen (ms): ", millis() - start_time);
#endif
}
};

View File

@ -0,0 +1,38 @@
/****************
* sound_list.h *
****************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
class SoundList {
private:
static PROGMEM const struct list_t {
const char *const PROGMEM name;
const FTDI::SoundPlayer::sound_t* data;
} list[];
public:
static const uint8_t n;
static inline const char* name(uint8_t val) {
return (const char* ) pgm_read_ptr_near(&list[val].name);
}
static inline FTDI::SoundPlayer::sound_t* data(uint8_t val) {
return (FTDI::SoundPlayer::sound_t*) pgm_read_ptr_near(&list[val].data);
}
};

View File

@ -0,0 +1,111 @@
/********************
* sound_player.cpp *
********************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
namespace FTDI {
SoundPlayer sound; // Global sound player object
void SoundPlayer::set_volume(uint8_t vol) {
CLCD::mem_write_8(REG::VOL_SOUND, vol);
}
uint8_t SoundPlayer::get_volume() {
return CLCD::mem_read_8(REG::VOL_SOUND);
}
void SoundPlayer::play(effect_t effect, note_t note) {
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOPAIR ("Playing note ", int(note));
SERIAL_ECHOLNPAIR(", instrument ", int(effect));
#endif
// Play the note
CLCD::mem_write_16(REG::SOUND, (note == REST) ? 0 : (((note ? note : NOTE_C4) << 8) | effect));
CLCD::mem_write_8(REG::PLAY, 1);
}
note_t SoundPlayer::frequency_to_midi_note(const uint16_t frequency_hz) {
const float f0 = 440;
return note_t(NOTE_A4 + (log(frequency_hz)-log(f0))*12/log(2) + 0.5);
}
// Plays a tone of a given frequency and duration. Since the FTDI FT810 only
// supports MIDI notes, we round down to the nearest note.
void SoundPlayer::play_tone(const uint16_t frequency_hz, const uint16_t duration_ms) {
play(ORGAN, frequency_to_midi_note(frequency_hz));
// Schedule silence to squelch the note after the duration expires.
sequence = silence;
wait = duration_ms;
timer.start();
}
void SoundPlayer::play(const sound_t* seq, play_mode_t mode) {
sequence = seq;
wait = 250; // Adding this delay causes the note to not be clipped, not sure why.
timer.start();
if (mode == PLAY_ASYNCHRONOUS) return;
// If playing synchronously, then play all the notes here
while (has_more_notes()) {
onIdle();
#ifdef EXTENSIBLE_UI
ExtUI::yield();
#endif
}
}
bool SoundPlayer::is_sound_playing() {
return CLCD::mem_read_8( REG::PLAY ) & 0x1;
}
void SoundPlayer::onIdle() {
if (!sequence) return;
const bool ready_for_next_note = (wait == 0) ? !is_sound_playing() : timer.elapsed(wait);
if (ready_for_next_note) {
const effect_t fx = effect_t(pgm_read_byte(&sequence->effect));
const note_t nt = note_t(pgm_read_byte(&sequence->note));
const uint32_t ms = uint32_t(pgm_read_byte(&sequence->sixteenths)) * 1000 / 16;
if (ms == 0 && fx == SILENCE && nt == END_SONG) {
sequence = 0;
play(SILENCE, REST);
} else {
wait = ms;
timer.start();
play(fx, nt);
sequence++;
}
}
}
} // namespace FTDI
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,70 @@
/******************
* sound_player.h *
******************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
namespace FTDI {
typedef enum {
PLAY_ASYNCHRONOUS,
PLAY_SYNCHRONOUS
} play_mode_t;
class SoundPlayer {
typedef FTDI::ftdi_registers REG;
typedef FTDI::ftdi_memory_map MAP;
public:
struct sound_t {
effect_t effect; // The sound effect number
note_t note; // The MIDI note value
uint16_t sixteenths; // Duration of note, in sixteeths of a second, or zero to play to completion
};
const uint8_t WAIT = 0;
private:
const sound_t *sequence;
tiny_timer_t timer;
tiny_time_t wait;
note_t frequency_to_midi_note(const uint16_t frequency);
public:
static void set_volume(uint8_t volume);
static uint8_t get_volume();
static void play(effect_t effect, note_t note = NOTE_C4);
static bool is_sound_playing();
void play(const sound_t* seq, play_mode_t mode = PLAY_SYNCHRONOUS);
void play_tone(const uint16_t frequency_hz, const uint16_t duration_ms);
bool has_more_notes() {return sequence != 0;};
void onIdle();
};
extern SoundPlayer sound;
const PROGMEM SoundPlayer::sound_t silence[] = {
{SILENCE, END_SONG, 0}
};
}

View File

@ -0,0 +1,129 @@
/****************
* text_box.cpp *
****************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
namespace FTDI {
/**
* Given a str, end will be set to the position at which a line needs to
* be broken so that the display width is less than w. The line will also
* be broken after a '\n'. Returns the display width of the line.
*/
static uint16_t find_line_break(const FontMetrics &fm, uint16_t w, const char *str, const char *&end) {
w -= fm.get_char_width(' ');
const char *p = str;
end = str;
uint16_t lw = 0, result = 0;
for(;;) {
utf8_char_t c = get_utf8_char_and_inc(p);
if (c == ' ' || c == '\n' || c == '\0') {
if (lw < w || end == str) {
end = (c == '\0') ? p-1 : p;
result = lw;
}
if (c == '\0' || c == '\n') break;
}
lw += fm.get_char_width(c);
}
if (end == str) {
end = p-1;
result = lw;
}
return result;
}
/**
* This function returns a measurements of the word-wrapped text box.
*/
static void measure_text_box(const FontMetrics &fm, const char *str, uint16_t &width, uint16_t &height) {
const char *line_start = (const char*)str;
const char *line_end;
const uint16_t wrap_width = width;
width = height = 0;
for(;;) {
uint16_t line_width = find_line_break(fm, wrap_width, line_start, line_end);
if (line_end == line_start) break;
width = max(width, line_width);
height += fm.get_height();
line_start = line_end;
}
}
/**
* This function draws text inside a bounding box, doing word wrapping and using the largest font that will fit.
*/
void draw_text_box(CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options, uint8_t font) {
uint16_t box_width, box_height;
FontMetrics fm(font);
// Shrink the font until we find a font that fits
for(;;) {
box_width = w;
measure_text_box(fm, str, box_width, box_height);
if (box_width <= (uint16_t)w && box_height <= (uint16_t)h) break;
fm.load(--font);
if (font == 26) break;
}
const uint16_t dx = (options & OPT_RIGHTX) ? w : (options & OPT_CENTERX) ? w/2 : 0;
const uint16_t dy = (options & OPT_CENTERY) ? (h - box_height)/2 : 0;
const char *line_start = str;
const char *line_end;
for(;;) {
find_line_break(fm, w, line_start, line_end);
if (line_end == line_start) break;
const size_t line_len = line_end - line_start;
if (line_len) {
char line[line_len + 1];
strncpy(line, line_start, line_len);
line[line_len] = 0;
if (line[line_len - 1] == '\n' || line[line_len - 1] == ' ')
line[line_len - 1] = 0;
#ifdef TOUCH_UI_USE_UTF8
if (has_utf8_chars(line)) {
draw_utf8_text(cmd, x + dx, y + dy, line, fm.fs, options & ~OPT_CENTERY);
} else
#endif
{
cmd.CLCD::CommandFifo::text(x + dx, y + dy, font, options & ~OPT_CENTERY);
cmd.CLCD::CommandFifo::str(line);
}
}
y += fm.get_height();
line_start = line_end;
}
}
void draw_text_box(CommandProcessor& cmd, int x, int y, int w, int h, progmem_str pstr, uint16_t options, uint8_t font) {
char str[strlen_P((const char*)pstr) + 1];
strcpy_P(str, (const char*)pstr);
draw_text_box(cmd, x, y, w, h, (const char*) str, options, font);
}
} // namespace FTDI
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,30 @@
/**************
* text_box.h *
**************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/**
* This function draws text inside a bounding box, doing word wrapping and using the largest font that will fit.
*/
namespace FTDI {
void draw_text_box(class CommandProcessor& cmd, int x, int y, int w, int h, progmem_str str, uint16_t options = 0, uint8_t font = 31);
void draw_text_box(class CommandProcessor& cmd, int x, int y, int w, int h, const char *str, uint16_t options = 0, uint8_t font = 31);
}

View File

@ -0,0 +1,51 @@
/******************
* tiny_timer.cpp *
******************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "ftdi_extended.h"
#ifdef FTDI_EXTENDED
bool tiny_timer_t::elapsed(tiny_time_t duration) {
uint8_t now = tiny_time_t::tiny_time(
#ifdef __MARLIN_FIRMWARE__
ExtUI::safe_millis()
#else
millis()
#endif
);
uint8_t elapsed = now - _start;
if (elapsed >= duration._duration) {
return true;
} else {
return false;
}
}
void tiny_timer_t::start() {
_start = tiny_time_t::tiny_time(
#ifdef __MARLIN_FIRMWARE__
ExtUI::safe_millis()
#else
millis()
#endif
);
}
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,56 @@
/****************
* tiny_timer.h *
****************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/* Helpful Reference:
*
* https://arduino.stackexchange.com/questions/12587/how-can-i-handle-the-millis-rollover
*/
/* tiny_interval_t downsamples a 32-bit millis() value
into a 8-bit value which can record periods of
a few seconds with a rougly 1/16th of second
resolution. This allows us to measure small
intervals without needing to use four-byte counters.
*/
class tiny_time_t {
private:
friend class tiny_timer_t;
uint8_t _duration;
static uint8_t tiny_time(uint32_t ms) {return ceil(float(ms) / 64);};
public:
tiny_time_t() : _duration(0) {}
tiny_time_t(uint32_t ms) : _duration(tiny_time(ms)) {}
tiny_time_t & operator= (uint32_t ms) {_duration = tiny_time(ms); return *this;}
bool operator == (uint32_t ms) {return _duration == tiny_time(ms);}
};
class tiny_timer_t {
private:
uint8_t _start;
public:
void start();
bool elapsed(tiny_time_t interval);
};

View File

@ -0,0 +1,40 @@
FTDI EVE Unicode Rendering
--------------------------
The FTDI EVE chips have several fonts in ROM, but these fonts only contain a
subset of ASCII characters. Notably, this excludes diacritics and accents
used in most Western languages.
While the FTDI EVE has the capability for user-defined fonts, such fonts only
support 127 character positions, making them as limiting as the built-in fonts.
As a further complication, high resolution TFT displays require high resolution
fonts. It is not feasible to put a complete international font into the limited
flash memory of most microprocessors.
To work around these limitations, this library uses a custom font renderer with
the following characteristics:
1) Rather than providing bitmaps for different font sizes, it uses a single
bitmap for the largest font size (romfont 31) and emulates other sizes by
scaling the bitmaps using BITMAP_TRANSFORM.
2) Rather than loading an entire font, it combines symbols from romfont 31
with a limited number of symbols from a custom font. For accented letters,
the rendering code combine basic letter shapes from romfont 31 with
bitmaps containing only the accent themselves.
3) The custom bitmap is RLE compressed into PROGMEM. For accents, which have
a fairly small number of non-white pixels, the savings are significant.
These characteristics enable an alphabet for Western languages to be
synthesized from only a few dozen custom symbols and modest PROGMEM use (~10k)
The text layout is done by the code in "unicode.cpp" with the help of one of
more character renderers (e.g. "western_char_set.cpp"). Each character render
is responsible for loading the necessary bitmap data into RAMG and drawing
characters as requested.
To add symbols for other languages, it will only be necessary to make a bitmap
and implement a corresponding character renderer.

View File

@ -0,0 +1,55 @@
/*******************
* font_bitmap.cpp *
*******************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../ftdi_extended.h"
#ifdef FTDI_EXTENDED
namespace FTDI {
void write_rle_data(uint16_t addr, const uint8_t *data, size_t n) {
for (; n >= 2; n -= 2) {
uint8_t count = pgm_read_byte(data++);
uint8_t value = pgm_read_byte(data++);
while (count--) CLCD::mem_write_8(addr++, value);
}
}
void set_font_bitmap(CommandProcessor& cmd, CLCD::FontMetrics &fm, uint8_t handle) {
cmd.cmd(BITMAP_HANDLE(handle));
cmd.cmd(BITMAP_SOURCE(fm.ptr));
cmd.bitmap_layout(fm.format, fm.stride, fm.height);
cmd.bitmap_size(BILINEAR, BORDER, BORDER, fm.width, fm.height);
}
void ext_vertex2ii(CommandProcessor &cmd, int x, int y, uint8_t handle, uint8_t cell) {
if (x < 0 || y < 0 || x > 511 || y > 511) {
cmd.cmd(BITMAP_HANDLE(handle));
cmd.cmd(CELL(cell));
cmd.cmd(VERTEX2F(x * 16, y * 16));
} else {
cmd.cmd(VERTEX2II(x, y, handle, cell));
}
}
} // namespace FTDI
#endif // FTDI_EXTENDED

View File

@ -0,0 +1,30 @@
/******************
* font_bitmaps.h *
******************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
class CommandProcessor;
namespace FTDI {
void write_rle_data(uint16_t addr, const uint8_t *data, size_t n);
void set_font_bitmap(CommandProcessor& cmd, CLCD::FontMetrics &fm, uint8_t handle);
void ext_vertex2ii(CommandProcessor &cmd, int x, int y, uint8_t handle, uint8_t cell);
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -0,0 +1,46 @@
/*******************
* font_size_t.cpp *
*******************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../ftdi_extended.h"
#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8)
namespace FTDI {
// Returns the height of a standard FTDI romfont
uint8_t font_size_t::get_romfont_height(uint8_t font) {
static const uint8_t tbl[] PROGMEM = {
8, 8, 16, 16, 13, 17, 20, 22, 29, 38, 16, 20, 25, 28, 36, 49, 63, 83, 108
};
return pgm_read_byte(&tbl[font - 16]);
}
// Sets the scaling coefficient to match a romfont size
font_size_t font_size_t::from_romfont(uint8_t font) {
return font_size_t(uint32_t(std_height) * 256 / get_romfont_height(font));
}
// Returns the height of the font
uint8_t font_size_t::get_height() const {
return scale(std_height);
}
}
#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8

View File

@ -0,0 +1,55 @@
/*****************
* font_size_t.h *
*****************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
class CommandProcessor;
namespace FTDI {
/* The unicode rendering of different font sizes happens by scaling a
* large-sized font bitmap using the FTDI bitmap transformation matrix.
* This keeps us from having to have load bitmaps for all font sizes.
*
* The font_size_t class helps manage this scaling factor.
*/
class font_size_t {
private:
// Standard height for font bitmaps
static constexpr uint8_t std_height = 49;
// 8.8 fixed point scaling coefficient
uint16_t coefficient;
font_size_t(uint16_t v) : coefficient(v) {}
public:
font_size_t() : coefficient(256) {}
static uint8_t get_romfont_height(uint8_t font);
static font_size_t from_romfont(uint8_t size);
template<typename T> T scale(T val) const {return (int32_t(val) * 256 / coefficient);}
uint8_t get_height() const;
uint16_t get_coefficient() const {return coefficient;}
};
}

View File

@ -0,0 +1,106 @@
/*************************
* standard_char_set.cpp *
*************************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../ftdi_extended.h"
#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8)
constexpr static uint8_t std_font = 31;
/* Lookup table of the char widths for standard ROMFONT 31 */
uint8_t FTDI::StandardCharSet::std_char_width(char c) {
static const uint8_t tbl[] PROGMEM = {
10, 11, 15, 26, 25, 31, 26, 10, 15, 14, 18, 24, 9, 18, 11, 17, 24, 24,
24, 24, 24, 24, 24, 24, 24, 24, 10, 10, 21, 23, 22, 20, 37, 27, 27, 26,
28, 23, 22, 28, 29, 12, 23, 26, 22, 35, 29, 28, 26, 29, 27, 26, 26, 28,
27, 36, 27, 26, 25, 12, 18, 12, 18, 21, 13, 23, 24, 22, 24, 22, 15, 24,
24, 10, 11, 22, 10, 36, 24, 24, 24, 24, 15, 22, 14, 24, 21, 32, 21, 21,
22, 15, 10, 15, 29, 10
};
return pgm_read_byte(&tbl[c - ' ']);
}
/**
* Load bitmap data into RAMG. This function is called once at the start
* of the program.
*
* Parameters:
*
* addr - Address in RAMG where the font data is written
*/
void FTDI::StandardCharSet::load_data(uint32_t) {
}
/**
* Populates the bitmap handles for the custom into the display list.
* This function is called once at the start of each display list.
*
* Parameters:
*
* cmd - Object used for writing to the FTDI chip command queue.
*/
void FTDI::StandardCharSet::load_bitmaps(CommandProcessor& cmd) {
CLCD::FontMetrics std_fm(std_font);
set_font_bitmap(cmd, std_fm, std_font);
}
/**
* Renders a character at location x and y. The x position is incremented
* by the width of the character.
*
* Parameters:
*
* cmd - If non-NULL the symbol is drawn to the screen.
* If NULL, only increment position for text measurement.
*
* x, y - The location at which to draw the character. On output,
* incremented to the location of the next character.
*
* fs - A scaling object used to scale the font. The display will
* already be configured to scale bitmaps, but positions
* must be scaled using fs.scale()
*
* c - The unicode code point to draw. If the renderer does not
* support the character, it should draw nothing.
*/
bool FTDI::StandardCharSet::render_glyph(CommandProcessor* cmd, int &x, int &y, font_size_t fs, utf8_char_t c) {
uint8_t which = (c >= ' ' && c < 128) ? c : '?';
uint8_t width = std_char_width(which);
if (c == '\t') {
// Special handling for the tab character
which = ' ';
width = std_char_width(' ');
}
// Draw the character
if (cmd) ext_vertex2ii(*cmd, x, y, std_font, which);
// Increment X to the next character position
x += fs.scale(width);
return true;
}
#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8

View File

@ -0,0 +1,30 @@
/***********************
* standard_char_set.h *
***********************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
namespace FTDI {
class StandardCharSet {
public:
static uint8_t std_char_width(char);
static void load_data(uint32_t addr);
static void load_bitmaps(CommandProcessor&);
static bool render_glyph(CommandProcessor*, int &x, int &y, font_size_t, utf8_char_t);
};
}

View File

@ -0,0 +1,219 @@
/***************
* unicode.cpp *
***************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../ftdi_extended.h"
#if defined(FTDI_EXTENDED) && ENABLED(TOUCH_UI_USE_UTF8)
using namespace FTDI;
/**
* Return true if a string has UTF8 characters
*
* Parameters:
*
* c - Pointer to a string.
*
* Returns: True if the strings has UTF8 characters
*/
bool FTDI::has_utf8_chars(const char *str) {
for (;;) {
const char c = *str++;
if (!c) break;
if ((c & 0xC0) == 0x80) return true;
}
return false;
}
bool FTDI::has_utf8_chars(progmem_str _str) {
const char *str = (const char *) _str;
for (;;) {
const char c = pgm_read_byte(str++);
if (!c) break;
if ((c & 0xC0) == 0x80) return true;
}
return false;
}
/**
* Return a character in a UTF8 string and increment the
* pointer to the next character
*
* Parameters:
*
* c - Pointer to a UTF8 encoded string.
*
* Returns: The packed bytes of a UTF8 encoding of a single
* character (this is not the unicode codepoint)
*/
utf8_char_t FTDI::get_utf8_char_and_inc(const char *&c) {
utf8_char_t val = *(uint8_t*)c++;
while ((*c & 0xC0) == 0x80)
val = (val << 8) | *(uint8_t*)c++;
return val;
}
/**
* Helper function to draw and/or measure a UTF8 string
*
* Parameters:
*
* cmd - If non-NULL the symbol is drawn to the screen.
* If NULL, only increment position for text measurement.
*
* x, y - The location at which to draw the string.
*
* str - The UTF8 string to draw or measure.
*
* fs - A scaling object used to specify the font size.
*/
static uint16_t render_utf8_text(CommandProcessor* cmd, int x, int y, const char *str, font_size_t fs) {
const int start_x = x;
while (*str) {
const utf8_char_t c = get_utf8_char_and_inc(str);
#ifdef TOUCH_UI_UTF8_WESTERN_CHARSET
WesternCharSet::render_glyph(cmd, x, y, fs, c) ||
#endif
StandardCharSet::render_glyph(cmd, x, y, fs, c);
}
return x - start_x;
}
/**
* Load the font bitmap data into RAMG. Called once at program start.
*
* Parameters:
*
* addr - Address in RAMG where the font data is written
*/
void FTDI::load_utf8_data(uint16_t addr) {
#ifdef TOUCH_UI_UTF8_WESTERN_CHARSET
WesternCharSet::load_data(addr);
#endif
StandardCharSet::load_data(addr);
}
/**
* Populate the bitmap handles for the custom fonts into the display list.
* Called once at the start of each display list.
*
* Parameters:
*
* cmd - Object used for writing to the FTDI chip command queue.
*/
void FTDI::load_utf8_bitmaps(CommandProcessor &cmd) {
#ifdef TOUCH_UI_UTF8_WESTERN_CHARSET
WesternCharSet::load_bitmaps(cmd);
#endif
StandardCharSet::load_bitmaps(cmd);
}
/**
* Measure a UTF8 text character
*
* Parameters:
*
* c - The unicode code point to measure.
*
* fs - A scaling object used to specify the font size.
*
* Returns: A width in pixels
*/
uint16_t FTDI::get_utf8_char_width(utf8_char_t c, font_size_t fs) {
int x = 0, y = 0;
#ifdef TOUCH_UI_UTF8_WESTERN_CHARSET
WesternCharSet::render_glyph(NULL, x, y, fs, c) ||
#endif
StandardCharSet::render_glyph(NULL, x, y, fs, c);
return x;
}
/**
* Measure a UTF8 text string
*
* Parameters:
*
* str - The UTF8 string to measure.
*
* fs - A scaling object used to specify the font size.
*
* Returns: A width in pixels
*/
uint16_t FTDI::get_utf8_text_width(const char *str, font_size_t fs) {
return render_utf8_text(NULL, 0, 0, str, fs);
}
uint16_t FTDI::get_utf8_text_width(progmem_str pstr, font_size_t fs) {
char str[strlen_P((const char*)pstr) + 1];
strcpy_P(str, (const char*)pstr);
return get_utf8_text_width(str, fs);
}
/**
* Draw a UTF8 text string
*
* Parameters:
*
* cmd - Object used for writing to the FTDI chip command queue.
*
* x, y - The location at which to draw the string.
*
* str - The UTF8 string to draw.
*
* fs - A scaling object used to specify the font size.
*
* options - Text alignment options (i.e. OPT_CENTERX, OPT_CENTERY, OPT_CENTER or OPT_RIGHTX)
*
*/
void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, const char *str, font_size_t fs, uint16_t options) {
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(BITMAP_TRANSFORM_A(fs.get_coefficient()));
cmd.cmd(BITMAP_TRANSFORM_E(fs.get_coefficient()));
cmd.cmd(BEGIN(BITMAPS));
// Apply alignment options
if (options & OPT_CENTERX)
x -= get_utf8_text_width(str, fs) / 2;
else if (options & OPT_RIGHTX)
x -= get_utf8_text_width(str, fs);
if (options & OPT_CENTERY)
y -= fs.get_height()/2;
// Render the text
render_utf8_text(&cmd, x, y, str, fs);
cmd.cmd(RESTORE_CONTEXT());
}
void FTDI::draw_utf8_text(CommandProcessor& cmd, int x, int y, progmem_str pstr, font_size_t fs, uint16_t options) {
char str[strlen_P((const char*)pstr) + 1];
strcpy_P(str, (const char*)pstr);
draw_utf8_text(cmd, x, y, (const char*) str, fs, options);
}
#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8

View File

@ -0,0 +1,111 @@
/*************
* unicode.h *
*************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
class CommandProcessor;
namespace FTDI {
#ifdef TOUCH_UI_USE_UTF8
typedef uint16_t utf8_char_t;
/**
* Converts a 32-bit codepoint into UTF-8. This compile-time function
* will be useful until the u8'a' character literal becomes more common.
*/
constexpr uint32_t utf8(const uint32_t c) {
return (c < 0x7F ) ? c :
(c < 0x7FF) ? (0x0000C080 | ((c & 0b011111000000) << 2) | (c & 0b111111)) :
(c < 0xFFFF) ? (0x00E08080 | ((c & 0b001111000000000000) << 4) | ((c & 0b111111000000) << 2) | (c & 0b111111)) :
(0xF0808080 | ((c & 0b000111000000000000000000) << 6) | ((c & 0b111111000000000000) << 4) | ((c & 0b111111000000) << 2) | (c & 0b111111));
}
/* Returns true if the string has UTF8 string characters */
bool has_utf8_chars(progmem_str str);
bool has_utf8_chars(const char *str);
/* Returns the next character in a UTF8 string and increments the
* pointer to the next character */
utf8_char_t get_utf8_char_and_inc(const char *&c);
/* Returns the next character in a UTF8 string, without incrementing */
inline utf8_char_t get_utf8_char(const char *c) {return get_utf8_char_and_inc(c);}
void load_utf8_data(uint16_t addr);
#else
typedef char utf8_char_t;
inline utf8_char_t get_utf8_char_and_inc(const char *&c) {return *c++;}
inline utf8_char_t get_utf8_char(const char *c) {return *c;}
inline void load_utf8_data(uint16_t) {}
#endif
void load_utf8_bitmaps(CommandProcessor& cmd);
uint16_t get_utf8_char_width(utf8_char_t, font_size_t);
uint16_t get_utf8_text_width(progmem_str, font_size_t);
uint16_t get_utf8_text_width(const char *, font_size_t);
void draw_utf8_text(CommandProcessor&, int x, int y, progmem_str, font_size_t, uint16_t options = 0);
void draw_utf8_text(CommandProcessor&, int x, int y, const char *, font_size_t, uint16_t options = 0);
// Similar to CLCD::FontMetrics, but can be used with UTF8 encoded strings.
struct FontMetrics {
#ifdef TOUCH_UI_USE_UTF8
font_size_t fs;
#else
CLCD::FontMetrics fm;
#endif
inline void load(uint8_t rom_font_size) {
#ifdef TOUCH_UI_USE_UTF8
fs = font_size_t::from_romfont(rom_font_size);
#else
fm.load(rom_font_size);
#endif
}
inline uint16_t get_char_width(utf8_char_t c) const {
#ifdef TOUCH_UI_USE_UTF8
return get_utf8_char_width(c, fs);
#else
return fm.char_widths[(uint8_t)c];
#endif
}
inline uint8_t get_height() const {
#ifdef TOUCH_UI_USE_UTF8
return fs.get_height();
#else
return fm.height;
#endif
}
inline FontMetrics(uint8_t rom_font_size) {
load(rom_font_size);
}
};
}

View File

@ -0,0 +1,449 @@
/************************
* western_char_set.cpp *
************************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../ftdi_extended.h"
#if defined(FTDI_EXTENDED) && BOTH(TOUCH_UI_USE_UTF8, TOUCH_UI_UTF8_WESTERN_CHARSET)
#include "western_char_set_bitmap_31.h"
#define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
using namespace FTDI;
constexpr static uint8_t std_font = 31;
constexpr static uint8_t alt_font = 1;
static uint32_t bitmap_addr;
/* Glyphs in the WesternCharSet bitmap */
enum {
GRAVE,
ACUTE,
CIRCUMFLEX,
TILDE,
DIAERESIS,
DOT_ABOVE,
CEDILLA,
NO_DOT_I,
#if ENABLED(TOUCH_UI_UTF8_GERMANIC)
SHARP_S,
#endif
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
LRG_O_STROKE,
SML_O_STROKE,
LRG_AE,
SML_AE,
LRG_ETH,
SML_ETH,
LRG_THORN,
SML_THORN,
#endif
#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION)
LEFT_DBL_QUOTE,
RIGHT_DBL_QUOTE,
INV_EXCLAMATION,
INV_QUESTION,
#endif
#if ENABLED(TOUCH_UI_UTF8_CURRENCY)
CENT_SIGN,
POUND_SIGN,
CURRENCY_SIGN,
YEN_SIGN,
#endif
#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS)
SUPERSCRIPT_ONE,
SUPERSCRIPT_TWO,
SUPERSCRIPT_THREE,
#endif
#if ENABLED(TOUCH_UI_UTF8_ORDINALS)
MASCULINE_ORDINAL,
FEMININE_ORDINAL,
#endif
#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT)
COPYRIGHT_SIGN,
REGISTERED_SIGN,
#endif
#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS)
PLUS_MINUS_SIGN,
MULTIPLICATION_SIGN,
DIVISION_SIGN,
#endif
#if ENABLED(TOUCH_UI_UTF8_FRACTIONS)
FRACTION_QUARTER,
FRACTION_HALF,
FRACTION_THREE_FOURTHS,
#endif
#if ENABLED(TOUCH_UI_UTF8_SYMBOLS)
MICRON_SIGN,
PILCROW_SIGN,
BROKEN_BAR,
SECTION_SIGN,
NOT_SIGN
#endif
};
/* Centerline of characters that can take accents */
constexpr int8_t mid_a = 12;
constexpr int8_t mid_e = 12;
constexpr int8_t mid_i = 5;
constexpr int8_t mid_o = 12;
constexpr int8_t mid_u = 12;
constexpr int8_t mid_y = 11;
constexpr int8_t mid_n = 12;
constexpr int8_t mid_c = 12;
constexpr int8_t mid_A = 13;
constexpr int8_t mid_E = 13;
constexpr int8_t mid_I = 6;
constexpr int8_t mid_O = 14;
constexpr int8_t mid_U = 14;
constexpr int8_t mid_Y = 13;
constexpr int8_t mid_N = 15;
constexpr int8_t mid_C = 13;
/* Centerline of accent glyphs */
constexpr int8_t mid_accent = 16;
/* When reusing the DOT_ABOVE accent glyph for the degree sign, we need to trim the leading space */
constexpr uint8_t deg_sign_leading = 9;
/* Look-up table for constructing characters (must be ordered by unicode)
*
* Characters are either complete symbols from the Western Char Set bitmap,
* or they are constructed using a standard letter from the romfont and
* drawing an accent from the Western Char Set bitmap over it.
*/
#define UTF8(A) uint16_t(utf8(U##A))
PROGMEM constexpr struct {
uint16_t unicode;
uint8_t std_char; // Glyph from standard ROMFONT (zero if none)
uint8_t alt_char; // Glyph from Western Char Set bitmap
uint8_t alt_data; // For accented characters, the centerline; else char width
} char_recipe[] = {
{0, 0, NO_DOT_I, 10 },
#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION)
{UTF8('¡'), 0 , INV_EXCLAMATION, 13 },
#endif
#if ENABLED(TOUCH_UI_UTF8_CURRENCY)
{UTF8('¢'), 0 , CENT_SIGN, 23 },
{UTF8('£'), 0 , POUND_SIGN, 24 },
{UTF8('¤'), 0 , CURRENCY_SIGN, 26 },
{UTF8('¥'), 0 , YEN_SIGN, 26 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SYMBOLS)
{UTF8('¦'), 0 , BROKEN_BAR, 11 },
{UTF8('§'), 0 , SECTION_SIGN, 21 },
#endif
#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT)
{UTF8('©'), 0 , COPYRIGHT_SIGN, 38 },
#endif
#if ENABLED(TOUCH_UI_UTF8_ORDINALS)
{UTF8('ª'), 0 , FEMININE_ORDINAL, 19 },
#endif
#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION)
{UTF8('«'), 0 , LEFT_DBL_QUOTE, 23 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SYMBOLS)
{UTF8('¬'), 0 , NOT_SIGN, 32 },
#endif
#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT)
{UTF8('®'), 0 , REGISTERED_SIGN, 38 },
#endif
{UTF8('°'), 0 , DOT_ABOVE, 24 },
#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS)
{UTF8('±'), 0 , NOT_SIGN, 32 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS)
{UTF8('²'), 0 , SUPERSCRIPT_TWO, 16 },
{UTF8('³'), 0 , SUPERSCRIPT_THREE, 16 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SYMBOLS)
{UTF8('µ'), 0 , MICRON_SIGN, 28 },
{UTF8(''), 0 , PILCROW_SIGN, 24 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS)
{UTF8('¹'), 0 , SUPERSCRIPT_ONE, 16 },
#endif
#if ENABLED(TOUCH_UI_UTF8_ORDINALS)
{UTF8('º'), 0 , MASCULINE_ORDINAL, 19 },
#endif
#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION)
{UTF8('»'), 0 , RIGHT_DBL_QUOTE, 24 },
#endif
#if ENABLED(TOUCH_UI_UTF8_FRACTIONS)
{UTF8('¼'), 0 , FRACTION_QUARTER, 40 },
{UTF8('½'), 0 , FRACTION_HALF, 40 },
{UTF8('¾'), 0 , FRACTION_THREE_FOURTHS, 40 },
#endif
#if ENABLED(TOUCH_UI_UTF8_PUNCTUATION)
{UTF8('¿'), 0 , INV_QUESTION, 21 },
#endif
{UTF8('À'), 'A', GRAVE, mid_A},
{UTF8('Á'), 'A', ACUTE, mid_A},
{UTF8('Â'), 'A', CIRCUMFLEX, mid_A},
{UTF8('Ã'), 'A', TILDE, mid_A},
{UTF8('Ä'), 'A', DIAERESIS, mid_A},
{UTF8('Å'), 'A', DOT_ABOVE, mid_A},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('Æ'), 0 , LRG_AE, 40},
#endif
{UTF8('Ç'), 'C', CEDILLA, mid_C},
{UTF8('È'), 'E', GRAVE, mid_E},
{UTF8('É'), 'E', ACUTE, mid_E},
{UTF8('Ê'), 'E', CIRCUMFLEX, mid_E},
{UTF8('Ë'), 'E', DIAERESIS, mid_E},
{UTF8('Ì'), 'I', GRAVE, mid_I},
{UTF8('Í'), 'I', ACUTE, mid_I},
{UTF8('Î'), 'I', CIRCUMFLEX, mid_I},
{UTF8('Ï'), 'I', DIAERESIS, mid_I},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('Ð'), 0, LRG_ETH, 31 },
#endif
{UTF8('Ñ'), 'N', TILDE, mid_N},
{UTF8('Ò'), 'O', GRAVE, mid_O},
{UTF8('Ó'), 'O', ACUTE, mid_O},
{UTF8('Ô'), 'O', CIRCUMFLEX, mid_O},
{UTF8('Õ'), 'O', TILDE, mid_O},
{UTF8('Ö'), 'O', DIAERESIS, mid_O},
#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS)
{UTF8('×'), 0 , MULTIPLICATION_SIGN, 32 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('Ø'), 0 , LRG_O_STROKE, 32 },
#endif
{UTF8('Ù'), 'U', GRAVE, mid_U},
{UTF8('Ú'), 'U', ACUTE, mid_U},
{UTF8('Û'), 'U', CIRCUMFLEX, mid_U},
{UTF8('Ü'), 'U', DIAERESIS, mid_U},
{UTF8('Ý'), 'Y', ACUTE, mid_Y},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('Þ'), 0 , LRG_THORN, 25 },
#endif
#if ENABLED(TOUCH_UI_UTF8_GERMANIC)
{UTF8('ß'), 0 , SHARP_S, 26 },
#endif
{UTF8('à'), 'a', GRAVE, mid_a},
{UTF8('á'), 'a', ACUTE, mid_a},
{UTF8('â'), 'a', CIRCUMFLEX, mid_a},
{UTF8('ã'), 'a', TILDE, mid_a},
{UTF8('ä'), 'a', DIAERESIS, mid_a},
{UTF8('å'), 'a', DOT_ABOVE, mid_a},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('æ'), 0 , SML_AE, 40 },
#endif
{UTF8('ç'), 'c', CEDILLA, mid_c},
{UTF8('è'), 'e', GRAVE, mid_e},
{UTF8('é'), 'e', ACUTE, mid_e},
{UTF8('ê'), 'e', CIRCUMFLEX, mid_e},
{UTF8('ë'), 'e', DIAERESIS, mid_e},
{UTF8('ì'), 'i', GRAVE, mid_i},
{UTF8('í'), 'i', ACUTE, mid_i},
{UTF8('î'), 'i', CIRCUMFLEX, mid_i},
{UTF8('ï'), 'i', DIAERESIS, mid_i},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('ð'), 0, SML_ETH, 24 },
#endif
{UTF8('ñ'), 'n', TILDE, mid_n},
{UTF8('ò'), 'o', GRAVE, mid_o},
{UTF8('ó'), 'o', ACUTE, mid_o},
{UTF8('ô'), 'o', CIRCUMFLEX, mid_o},
{UTF8('õ'), 'o', TILDE, mid_o},
{UTF8('ö'), 'o', DIAERESIS, mid_o},
#if ENABLED(TOUCH_UI_UTF8_MATHEMATICS)
{UTF8('÷'), 0 , DIVISION_SIGN, 32 },
#endif
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('ø'), 0 , SML_O_STROKE, 25 },
#endif
{UTF8('ù'), 'u', GRAVE, mid_u},
{UTF8('ú'), 'u', ACUTE, mid_u},
{UTF8('û'), 'u', CIRCUMFLEX, mid_u},
{UTF8('ü'), 'u', DIAERESIS, mid_u},
{UTF8('ý'), 'y', ACUTE, mid_y},
#if ENABLED(TOUCH_UI_UTF8_SCANDINAVIAN)
{UTF8('þ'), 0 , SML_THORN, 25 },
#endif
{UTF8('ÿ'), 'y', DIAERESIS, mid_y}
};
static_assert(UTF8('¡') == 0xC2A1, "Incorrect encoding for character");
/* Compile-time check that the table is in sorted order */
constexpr bool is_sorted(size_t n) {
return n < 2 ? true : char_recipe[n-2].unicode < char_recipe[n-1].unicode && is_sorted(n-1);
}
static_assert(is_sorted(NUM_ELEMENTS(char_recipe)), "The table must be sorted by unicode value");
/* Performs a binary search to find a unicode character in the table */
static int8_t find_char_data(FTDI::utf8_char_t c) {
int8_t min = 0, max = NUM_ELEMENTS(char_recipe), index;
for (;;) {
index = (min + max)/2;
const uint16_t char_at = pgm_read_word(&char_recipe[index].unicode);
if (char_at == c) break;
if (min == max) return -1;
if (c > char_at)
min = index + 1;
else
max = index;
}
return index;
}
static void get_char_data(uint8_t index, uint8_t &std_char, uint8_t &alt_char, uint8_t &alt_data) {
std_char = pgm_read_byte(&char_recipe[index].std_char);
alt_char = pgm_read_byte(&char_recipe[index].alt_char);
alt_data = pgm_read_byte(&char_recipe[index].alt_data);
}
/**
* Load bitmap data into RAMG. This function is called once at the start
* of the program.
*
* Parameters:
*
* addr - Address in RAMG where the font data is written
*/
void FTDI::WesternCharSet::load_data(uint32_t addr) {
// Load the alternative font metrics
CLCD::FontMetrics alt_fm;
alt_fm.ptr = addr + 148;
alt_fm.format = L4;
alt_fm.stride = 19;
alt_fm.width = 38;
alt_fm.height = 49;
for (uint8_t i = 0; i < 127; i++)
alt_fm.char_widths[i] = 0;
// For special characters, copy the character widths from the char tables
for (uint8_t i = 0; i < NUM_ELEMENTS(char_recipe); i++) {
uint8_t std_char, alt_char, alt_data;
get_char_data(i, std_char, alt_char, alt_data);
if (std_char == 0)
alt_fm.char_widths[alt_char] = alt_data;
}
CLCD::mem_write_bulk(addr, &alt_fm, 148);
// Decode the RLE data and load it into RAMG as a bitmap
write_rle_data(addr + 148, font, sizeof(font));
bitmap_addr = addr;
}
/**
* Populates the bitmap handles for the custom into the display list.
* This function is called once at the start of each display list.
*
* Parameters:
*
* cmd - Object used for writing to the FTDI chip command queue.
*/
void FTDI::WesternCharSet::load_bitmaps(CommandProcessor& cmd) {
CLCD::FontMetrics alt_fm;
alt_fm.ptr = bitmap_addr + 148;
alt_fm.format = L4;
alt_fm.stride = 19;
alt_fm.width = 38;
alt_fm.height = 49;
set_font_bitmap(cmd, alt_fm, alt_font);
}
/**
* Renders a character at location x and y. The x position is incremented
* by the width of the character.
*
* Parameters:
*
* cmd - If non-NULL the symbol is drawn to the screen.
* If NULL, only increment position for text measurement.
*
* x, y - The location at which to draw the character. On output,
* incremented to the location of the next character.
*
* fs - A scaling object used to scale the font. The display will
* already be configured to scale bitmaps, but positions
* must be scaled using fs.scale()
*
* c - The unicode code point to draw. If the renderer does not
* support the character, it should return false.
* Returns: Whether the character was supported.
*/
bool FTDI::WesternCharSet::render_glyph(CommandProcessor* cmd, int &x, int &y, font_size_t fs, utf8_char_t c) {
// A supported character?
if (c < UTF8('¡') || c > UTF8('ÿ')) return false;
int8_t index = find_char_data(c);
if (index == -1) return false;
// Determine character characteristics
uint8_t std_char, alt_char, alt_data;
get_char_data(index, std_char, alt_char, alt_data);
bool base_special;
uint8_t base_width;
uint8_t base_char;
uint8_t accent_char;
int8_t accent_dx, accent_dy;
if (std_char == 0) {
// Special character, non-accented
base_width = alt_data;
base_special = true;
base_char = alt_char;
accent_char = 0;
if (c == UTF8('°'))
x -= fs.scale(deg_sign_leading);
} else {
// Regular character with accent:
accent_dx = alt_data - mid_accent;
accent_dy = isupper(std_char) ? -7 : 0;
accent_char = alt_char;
base_width = StandardCharSet::std_char_width(std_char);
base_special = std_char == 'i';
base_char = base_special ? NO_DOT_I : std_char;
}
// If cmd != NULL, draw the glyph to the screen
if (cmd) {
ext_vertex2ii(*cmd, x, y, base_special ? alt_font : std_font, base_char);
if (accent_char)
ext_vertex2ii(*cmd, x + fs.scale(accent_dx), y + fs.scale(accent_dy), alt_font, accent_char);
}
// Increment X to the next character position
x += fs.scale(base_width);
return true;
}
#endif // FTDI_EXTENDED && TOUCH_UI_USE_UTF8 && TOUCH_UI_UTF8_WESTERN_CHARSET

View File

@ -0,0 +1,29 @@
/**********************
* western_char_set.h *
**********************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
namespace FTDI {
class WesternCharSet {
public:
static void load_data(uint32_t addr);
static void load_bitmaps(CommandProcessor&);
static bool render_glyph(CommandProcessor*, int &x, int &y, font_size_t, utf8_char_t);
};
}

View File

@ -0,0 +1,108 @@
#!/usr/bin/python
# Written By Marcio Teixeira 2019 - Aleph Objects, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License, go to the following
# location: <http://www.gnu.org/licenses/>.
from __future__ import print_function
from PIL import Image
import argparse
import textwrap
def pack_rle(data):
"""Use run-length encoding to pack the bytes"""
rle = []
value = data[0]
count = 0
for i in data:
if i != value or count == 255:
rle.append(count)
rle.append(value)
value = i
count = 1
else:
count += 1
rle.append(count)
rle.append(value)
return rle
class WriteSource:
def __init__(self, lines_in_blocks):
self.blocks = []
self.values = []
self.block_size = lines_in_blocks
self.rows = 0
def add_pixel(self, value):
self.values.append(value)
def convert_to_4bpp(self, data, chunk_size = 0):
# Invert the image
data = map(lambda i: 255 - i, data)
# Quanitize 8-bit values into 4-bits
data = map(lambda i: i >> 4, data)
# Make sure there is an even number of elements
if (len(data) & 1) == 1:
result.append(0)
# Combine each two adjacent values into one
i = iter(data)
data = map(lambda a, b: a << 4 | b, i ,i)
# Pack the data
data = pack_rle(data)
# Convert values into hex strings
return map(lambda a: "0x" + format(a, '02x'), data)
def end_row(self, y):
# Pad each row into even number of values
if len(self.values) & 1:
self.values.append(0)
self.rows += 1
if self.block_size and (self.rows % self.block_size) == 0:
self.blocks.append(self.values)
self.values = []
def write(self):
if len(self.values):
self.blocks.append(self.values)
block_strs = [];
for b in self.blocks:
data = self.convert_to_4bpp(b)
data = ', '.join(data)
data = textwrap.fill(data, 75, initial_indent = ' ', subsequent_indent = ' ')
block_strs.append(data)
print("const unsigned char font[] PROGMEM = {")
for i, b in enumerate(block_strs):
if i:
print(',')
print('\n /* {} */'.format(i))
print(b, end='')
print("\n};")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Converts a grayscale bitmap into a 16-level RLE packed C array for use as font data')
parser.add_argument("input")
parser.add_argument('--char_height', help='Adds a separator every so many lines', type=int)
args = parser.parse_args()
writer = WriteSource(args.char_height)
img = Image.open(args.input).convert('L')
for y in range(img.height):
for x in range(img.width):
writer.add_pixel(img.getpixel((x,y)))
writer.end_row(y)
writer.write()

View File

@ -0,0 +1,105 @@
/***********************
* circular_progress.h *
***********************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/* This function draws a circular progress "ring" */
void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, float percent, char *text, uint32_t bgcolor, uint32_t fgcolor) {
using namespace FTDI;
const float rim = 0.3;
const float a = percent/100.0*2.0*PI;
const float a1 = min(PI/2, a);
const float a2 = min(PI/2, a-a1);
const float a3 = min(PI/2, a-a1-a2);
const float a4 = min(PI/2, a-a1-a2-a3);
const int ro = min(w,h) * 8;
const int rr = ro * rim;
const int cx = x * 16 + w * 8;
const int cy = y * 16 + h * 8;
// Load a rim shape into stencil buffer
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(TAG_MASK(0));
cmd.cmd(CLEAR(0,1,0));
cmd.cmd(COLOR_MASK(0,0,0,0));
cmd.cmd(STENCIL_OP(STENCIL_OP_KEEP, STENCIL_OP_INVERT));
cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_ALWAYS, 255, 255));
cmd.cmd(BEGIN(POINTS));
cmd.cmd(POINT_SIZE(ro));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(POINT_SIZE(ro - rr));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(RESTORE_CONTEXT());
// Mask further drawing by stencil buffer
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(STENCIL_FUNC(STENCIL_FUNC_NOTEQUAL, 0, 255));
// Fill the background
cmd.cmd(COLOR_RGB(bgcolor));
cmd.cmd(BEGIN(POINTS));
cmd.cmd(POINT_SIZE(ro));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(COLOR_RGB(fgcolor));
// Paint upper-right quadrant
cmd.cmd(BEGIN(EDGE_STRIP_A));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(VERTEX2F(cx + ro*sin(a1) + 16,cy - ro*cos(a1) + 8));
// Paint lower-right quadrant
if (a > PI/2) {
cmd.cmd(BEGIN(EDGE_STRIP_R));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(VERTEX2F(cx + ro*cos(a2),cy + ro*sin(a2) + 16));
}
// Paint lower-left quadrant
if (a > PI) {
cmd.cmd(BEGIN(EDGE_STRIP_B));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(VERTEX2F(cx - ro*sin(a3) - 8,cy + ro*cos(a3)));
}
// Paint upper-left quadrant
if (a > 1.5*PI) {
cmd.cmd(BEGIN(EDGE_STRIP_L));
cmd.cmd(VERTEX2F(cx, cy));
cmd.cmd(VERTEX2F(cx - ro*cos(a4),cy - ro*sin(a4)));
}
cmd.cmd(RESTORE_CONTEXT());
// Draw the text
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(COLOR_RGB(fgcolor));
cmd.text(x,y,w,h,text, OPT_CENTERX | OPT_CENTERY);
cmd.cmd(RESTORE_CONTEXT());
}
void draw_circular_progress(CommandProcessor& cmd, int x, int y, int w, int h, float percent, uint32_t bgcolor, uint32_t fgcolor) {
char str[5];
sprintf(str,"%d\%%",int(percent));
draw_circular_progress(cmd, x, y, w, h, percent, str, bgcolor, fgcolor);
}

View File

@ -0,0 +1,396 @@
/*************
* poly_ui.h *
*************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/**
* The PolyReader class iterates over an array of (x,y) pairs.
* For supporting polygons with holes an end-of-loop marker may
* be embedded into the data stream:
*
* const PROGMEM uint16_t data[] = {
* x, y, x, y, ..., eol,
* ...
* x, y, x, y, ..., eol
* }
*
* The PolyReader object can be used to iterate over the points.
*
* PolyReader r(data, N_ELEMENTS(data));
*
* for(r.start();r.has_more(); r.next()) {
* uint16_t x = r.x;
* uint16_t y = r.y;
*
* // Do something with the point
* ...
*
* // Do something else if this point
* // closes a loop.
* if (r.end_of_loop()) {
* ...
* }
* }
*
*/
class PolyReader {
public:
typedef uint16_t type_t;
private:
static constexpr type_t eol = 0xFFFF;
const type_t *p, *top, *end;
type_t start_x, start_y;
void close_loop() {
x = start_x;
y = start_y;
start_x = eol;
start_y = eol;
}
public:
type_t x, y;
// Begin reading a polygon data structure
PolyReader(const uint16_t data[], const size_t n_elements) : top(data), end(data + n_elements) {
start();
}
void start() {
p = top;
start_x = eol;
next();
}
// Reads the next point in the polygon data structure
void next() {
if (!p) return;
if (p == end) {
if (start_x != eol)
close_loop();
else
p = NULL;
} else {
x = pgm_read_word_far(p++);
if (x == eol)
close_loop();
else {
y = pgm_read_word_far(p++);
if (start_x == eol) {
start_x = x;
start_y = y;
}
}
}
}
bool has_more() {return p != NULL;}
bool end_of_loop() {return start_x == eol;}
};
/**
* The TransformedPolyReader class works like the PolyReader,
* but the (x,y) input is assumed to be normalized onto a
* unit square and then mapped to the full 16-bits, i.e.
* (0.0,1.0) => (0x0000,0xFFFE). This class will scale the
* data to fit the entire display, a bounding box, or apply
* some arbitrary affine transform.
*
* This class is suitable for reading data from "svg2cpp.py"
*/
class TransformedPolyReader : public PolyReader {
private:
/**
* Fixed point type for fast transformations, supports
* values from 0 to 1024, with 1/32 precision.
*/
static constexpr uint8_t fract_bits = 5;
typedef int16_t fix_t;
fix_t makefix(float f) {return f * (1 << fract_bits);}
// First two rows of 3x3 transformation matrix
fix_t a, b, c;
fix_t d, e, f;
void transform() {
/**
* Values from PolyReader vary from 0 to FFFE.
* As an approximation to dividing by FFFE,
* we perform a bit shift right by 16.
*/
const int32_t px = PolyReader::x;
const int32_t py = PolyReader::y;
const int32_t round = 1 << (fract_bits-1);
x = (((((a * px) + (b * py)) >> 16) + c) + round) >> fract_bits;
y = (((((d * px) + (e * py)) >> 16) + f) + round) >> fract_bits;
}
void set_transform(
fix_t A, fix_t B, fix_t C,
fix_t D, fix_t E, fix_t F
) {
a = A; b = B; c = C;
d = D; e = E; f = F;
}
public:
typedef int16_t type_t;
type_t x, y;
TransformedPolyReader(const uint16_t data[], const size_t n) : PolyReader(data, n) {
scale_to_fit();
transform();
}
// Set an arbitrary affine transform
void set_transform(
float A, float B, float C,
float D, float E, float F
) {
set_transform(
makefix(A), makefix(B), makefix(C),
makefix(D), makefix(E), makefix(F)
);
}
// Scale the data to fit a specified bounding box
void scale_to_fit(type_t x_min, type_t y_min, type_t x_max, type_t y_max) {
fix_t sx = makefix(x_max - x_min);
fix_t sy = makefix(y_max - y_min);
fix_t tx = makefix(x_min);
fix_t ty = makefix(y_min);
set_transform(
sx, 0, tx,
0, sy, ty
);
}
// Scale to fit the entire display (default)
void scale_to_fit() {
scale_to_fit(0, 0, FTDI::display_width, FTDI::display_height);
}
void next() {
PolyReader::next();
transform();
}
};
/**
* The DeduplicatedPolyReader wraps around another PolyReader
* class to remove repeated points from the data. This could
* happen when scaling down using TransformedPolyReader, for
* example.
*/
template<class POLY_READER>
class DeduplicatedPolyReader : public POLY_READER {
private:
typename POLY_READER::type_t last_x, last_y;
static constexpr typename POLY_READER::type_t eol = 0xFFFF;
public:
DeduplicatedPolyReader(const uint16_t data[], const size_t n) : POLY_READER(data, n) {
last_x = POLY_READER::x;
last_y = POLY_READER::y;
}
void next() {
do {
if (!POLY_READER::has_more()) return;
POLY_READER::next();
} while (POLY_READER::x == last_x && POLY_READER::y == last_y && !POLY_READER::end_of_loop());
if (POLY_READER::end_of_loop()) {
last_x = last_y = eol;
} else {
last_x = POLY_READER::x;
last_y = POLY_READER::y;
}
}
};
/**
* The helper class allows you to build an interface based on arbitrary
* shapes.
*/
template<class POLY_READER=DeduplicatedPolyReader<TransformedPolyReader>>
class GenericPolyUI {
private:
CommandProcessor &cmd;
// Attributes used to paint buttons
uint32_t btn_fill_color = 0x000000;
uint32_t btn_shadow_color = 0xF3E0E0;
uint8_t btn_shadow_depth = 5;
uint32_t btn_stroke_color = 0x000000;
uint8_t btn_stroke_width = 28;
draw_mode_t mode;
public:
typedef POLY_READER poly_reader_t;
GenericPolyUI(CommandProcessor &c, draw_mode_t what = BOTH) : cmd(c), mode(what) {}
// Fills a polygon with the current COLOR_RGB
void fill(poly_reader_t r, bool clip = true) {
using namespace FTDI;
int16_t x, y, w, h;
if (clip) {
// Clipping reduces the number of pixels that are
// filled, allowing more complex shapes to be drawn
// in the alloted time.
bounds(r, x, y, w, h);
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x, y));
cmd.cmd(SCISSOR_SIZE(w, h));
}
Polygon p(cmd);
p.begin_fill();
p.begin_loop();
for(r.start();r.has_more();r.next()) {
p(r.x * 16, r.y * 16);
if (r.end_of_loop()) {
p.end_loop();
p.begin_loop();
}
}
p.end_loop();
p.end_fill();
if (clip)
cmd.cmd(RESTORE_CONTEXT());
}
void shadow(poly_reader_t r, uint8_t offset) {
#if FTDI_API_LEVEL >= 810
using namespace FTDI;
cmd.cmd(VERTEX_TRANSLATE_X(offset * 16));
cmd.cmd(VERTEX_TRANSLATE_Y(offset * 16));
fill(r, false);
cmd.cmd(VERTEX_TRANSLATE_X(0));
cmd.cmd(VERTEX_TRANSLATE_Y(0));
#endif
}
// Strokes a polygon with the current COLOR_RGB
void stroke(poly_reader_t r) {
using namespace FTDI;
Polygon p(cmd);
p.begin_stroke();
p.begin_loop();
for(r.start();r.has_more(); r.next()) {
p(r.x * 16, r.y * 16);
if (r.end_of_loop()) {
p.end_loop();
p.begin_loop();
}
}
p.end_loop();
p.end_stroke();
}
// Compute the bounds of a polygon
void bounds(poly_reader_t r, int16_t &x, int16_t &y, int16_t &w, int16_t &h) {
int16_t x_min = INT16_MAX;
int16_t y_min = INT16_MAX;
int16_t x_max = INT16_MIN;
int16_t y_max = INT16_MIN;
for(r.start(); r.has_more(); r.next()) {
x_min = min(x_min, int16_t(r.x));
x_max = max(x_max, int16_t(r.x));
y_min = min(y_min, int16_t(r.y));
y_max = max(y_max, int16_t(r.y));
}
x = x_min;
y = y_min;
w = x_max - x_min;
h = y_max - y_min;
}
/**
* Draw shaped buttons. Buttons are drawn out of a polygon which is
* filled and stroked on top of a drop shadow. The button will
* become "pushed" when touched.
*/
void button_fill(const uint32_t color) {
btn_fill_color = color;
}
void button_stroke(const uint32_t color, const uint8_t width) {
btn_stroke_color = color;
btn_stroke_width = width;
}
void button_shadow(const uint32_t color, const uint8_t depth) {
btn_shadow_color = color;
btn_shadow_depth = depth;
}
void button(const uint8_t tag, poly_reader_t r) {
using namespace FTDI;
// Draw the shadow
#if FTDI_API_LEVEL >= 810
if (mode & BACKGROUND) {
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(TAG(tag));
cmd.cmd(VERTEX_TRANSLATE_X(btn_shadow_depth * 16));
cmd.cmd(VERTEX_TRANSLATE_Y(btn_shadow_depth * 16));
cmd.cmd(COLOR_RGB(btn_shadow_color));
fill(r, false);
cmd.cmd(RESTORE_CONTEXT());
}
#endif
if (mode & FOREGROUND) {
cmd.cmd(SAVE_CONTEXT());
#if FTDI_API_LEVEL >= 810
if (EventLoop::get_pressed_tag() == tag) {
// "Push" the button
cmd.cmd(VERTEX_TRANSLATE_X(btn_shadow_depth * 16));
cmd.cmd(VERTEX_TRANSLATE_Y(btn_shadow_depth * 16));
}
#endif
// Draw the fill and stroke
cmd.cmd(TAG(tag));
cmd.cmd(COLOR_RGB(btn_fill_color));
fill(r, false);
cmd.cmd(COLOR_RGB(btn_stroke_color));
cmd.cmd(LINE_WIDTH(btn_stroke_width));
stroke(r);
cmd.cmd(RESTORE_CONTEXT());
}
}
void color(const uint32_t color) {
cmd.cmd(FTDI::COLOR_RGB(color));
}
};
typedef GenericPolyUI<> PolyUI;

View File

@ -0,0 +1,280 @@
#!/usr/bin/python
# Written By Marcio Teixeira 2018 - Aleph Objects, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# To view a copy of the GNU General Public License, go to the following
# location: <http://www.gnu.org/licenses/>.
from __future__ import print_function
import argparse, re, sys
usage = '''
This program extracts line segments from a SVG file and writes
them as coordinates in a C array. The x and y values will be
scaled from 0x0000 to 0xFFFE. 0xFFFF is used as path separator.
This program can only interpret straight segments, not curves.
It also cannot handle SVG transform attributes. To convert an
SVG file into the proper format, use the following procedure:
- Load SVG file into Inkscape
- Convert all Objects to Paths (Path -> Object to Path)
- Convert all Strokes to Paths (Path -> Stroke to Path)
- Combine all paths into one (Path -> Combine) [1]
- Convert all curves into short line segments
(Extensions -> Modify Paths -> Flatten Beziers...)
- Save as new SVG
- Convert into a header file using this utility
- To give paths individual names, break apart paths and
use the XML Editor to set the "id" attributes.
[1] Combining paths is necessary to remove transforms. You
could also use inkscape-applytransforms Inkscape extension.
'''
header = '''
/****************************************************************************
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/**
* This file was auto-generated using "svg2cpp.py"
*
* The encoding consists of x,y pairs with the min and max scaled to
* 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the
* start of a new closed path.
*/
#pragma once
'''
class ComputeBoundingBox:
def reset(self):
self.x_min = float(" inf")
self.y_min = float(" inf")
self.x_max = float("-inf")
self.y_max = float("-inf")
self.n_points = 0
self.n_paths = 0
def command(self, type, x, y):
self.x_min = min(self.x_min, x)
self.x_max = max(self.x_max, x)
self.y_min = min(self.y_min, y)
self.y_max = max(self.y_max, y)
if type == "M":
self.n_paths += 1
self.n_points += 1
def scale(self, x, y):
x -= self.x_min
y -= self.y_min
x /= self.x_max - self.x_min
y /= self.y_max - self.y_min
#y = 1 - y # Flip upside down
return (x, y)
def path_finished(self, id):
pass
def write(self):
print("constexpr float x_min = %f;" % self.x_min)
print("constexpr float x_max = %f;" % self.x_max)
print("constexpr float y_min = %f;" % self.y_min)
print("constexpr float y_max = %f;" % self.y_max)
print()
def from_svg_view_box(self, svg):
s = re.search('<svg[^>]+>', svg);
if s:
m = re.search('viewBox="([0-9-.]+) ([0-9-.]+) ([0-9-.]+) ([0-9-.]+)"', svg)
if m:
self.x_min = float(m.group(1))
self.y_min = float(m.group(2))
self.x_max = float(m.group(3))
self.y_max = float(m.group(4))
return True
return False
# op
class WriteDataStructure:
def __init__(self, bounding_box):
self.bounds = bounding_box
def reset(self, ):
self.hex_words = []
def push(self, value):
self.hex_words.append("0x%04X" % (0xFFFF & int(value)))
def command(self, type, x, y):
if type == "M":
self.push(0xFFFF)
x, y = self.bounds.scale(x,y)
self.push(x * 0xFFFE)
self.push(y * 0xFFFE)
def path_finished(self, id):
if self.hex_words and self.hex_words[0] == "0xFFFF":
self.hex_words.pop(0)
print("const PROGMEM uint16_t", id + "[] = {" + ", ".join (self.hex_words) + "};")
self.hex_words = []
class Parser:
def __init__(self, op):
self.op = op
self.reset()
def reset(self):
self.last_x = 0
self.last_y = 0
self.initial_x = 0
self.initial_y = 0
def process_svg_path_L_or_M(self, cmd, x, y):
self.op.command(cmd, x, y)
self.last_x = x
self.last_y = y
if cmd == "M":
self.initial_x = x
self.initial_y = y
def process_svg_path_data_cmd(self, id, cmd, a, b):
"""Converts the various types of moves into L or M commands
and dispatches to process_svg_path_L_or_M for futher processing."""
if cmd == "Z" or cmd == "z":
self.process_svg_path_L_or_M("L", self.initial_x, self.initial_y)
elif cmd == "H":
self.process_svg_path_L_or_M("L", a, self.last_y)
elif cmd == "V":
self.process_svg_path_L_or_M("L", self.last_x, a)
elif cmd == "h":
self.process_svg_path_L_or_M("L", self.last_x + a, self.last_y)
elif cmd == "v":
self.process_svg_path_L_or_M("L", self.last_x, self.last_y + a)
elif cmd == "L":
self.process_svg_path_L_or_M("L", a, b)
elif cmd == "l":
self.process_svg_path_L_or_M("L", self.last_x + a, self.last_y + b)
elif cmd == "M":
self.process_svg_path_L_or_M("M", a, b)
elif cmd == "m":
self.process_svg_path_L_or_M("M", self.last_x + a, self.last_y + b)
else:
print("Unsupported path data command:", cmd, "in path", id, "\n", file=sys.stderr)
quit()
def eat_token(self, regex):
"""Looks for a token at the start of self.d.
If found, the token is removed."""
self.m = re.match(regex,self.d)
if self.m:
self.d = self.d[self.m.end():]
return self.m
def process_svg_path_data(self, id, d):
"""Breaks up the "d" attribute into individual commands
and calls "process_svg_path_data_cmd" for each"""
self.d = d
while (self.d):
if self.eat_token('\s+'):
pass # Just eat the spaces
elif self.eat_token('([LMHVZlmhvz])'):
cmd = self.m.group(1)
# The following commands take no arguments
if cmd == "Z" or cmd == "z":
self.process_svg_path_data_cmd(id, cmd, 0, 0)
elif self.eat_token('([CScsQqTtAa])'):
print("Unsupported path data command:", self.m.group(1), "in path", id, "\n", file=sys.stderr)
quit()
elif self.eat_token('([ ,]*[-0-9e.]+)+'):
# Process list of coordinates following command
coords = re.split('[ ,]+', self.m.group(0))
# The following commands take two arguments
if cmd == "L" or cmd == "l":
while coords:
self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0)))
elif cmd == "M":
while coords:
self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0)))
# If a MOVETO has multiple points, the subsequent ones are assumed to be LINETO
cmd = "L"
elif cmd == "m":
while coords:
self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), float(coords.pop(0)))
# If a MOVETO has multiple points, the subsequent ones are assumed to be LINETO
cmd = "l"
# Assume all other commands are single argument
else:
while coords:
self.process_svg_path_data_cmd(id, cmd, float(coords.pop(0)), 0)
else:
print("Syntax error:", d, "in path", id, "\n", file=sys.stderr)
quit()
def process_svg_paths(self, svg):
self.op.reset()
for path in re.findall('<path[^>]+>', svg):
id = "<none>"
m = re.search(' id="(.*)"', path)
if m:
id = m.group(1)
m = re.search(' transform="(.*)"', path)
if m:
print("Found transform in path", id, "! Cannot process file!", file=sys.stderr)
quit()
m = re.search(' d="(.*)"', path)
if m:
self.process_svg_path_data(id, m.group(1))
self.op.path_finished(id)
self.reset()
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("filename")
args = parser.parse_args()
f = open(args.filename, "r")
data = f.read()
print(header)
b = ComputeBoundingBox()
if not b.from_svg_view_box(data):
# Can't find the view box, so use the bounding box of the elements themselves.
p = Parser(b)
p.process_svg_paths(data)
b.write()
w = WriteDataStructure(b)
p = Parser(w)
p.process_svg_paths(data)

View File

@ -0,0 +1,27 @@
/******************
* ftdi_eve_lib.h *
******************/
/****************************************************************************
* Written By Mark Pelletier 2019 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "compat.h"
#include "basic/ftdi_basic.h"
#include "extended/ftdi_extended.h"

View File

@ -0,0 +1,27 @@
/****************
* language.cpp *
****************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../../../../../MarlinCore.h"
#include "language.h"
uint8_t lang = 0;

View File

@ -0,0 +1,23 @@
/**************
* language.h *
**************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "language_en.h"

View File

@ -0,0 +1,164 @@
/*****************
* language_en.h *
*****************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
#include "language.h"
#if ENABLED(TOUCH_UI_UTF8_COPYRIGHT)
#define COPYRIGHT_SIGN u8"©"
#else
#define COPYRIGHT_SIGN u8"(c)"
#endif
#if ENABLED(TOUCH_UI_UTF8_SUPERSCRIPTS)
#define SUPERSCRIPT_TWO u8"²"
#else
#define SUPERSCRIPT_TWO u8"^2"
#endif
#if ENABLED(TOUCH_UI_UTF8_WESTERN_CHARSET)
#define DEGREE_SIGN u8"°"
#else
#define DEGREE_SIGN u8" "
#endif
namespace Language_en {
PROGMEM Language_Str MSG_BUTTON_OKAY = u8"Okay";
PROGMEM Language_Str MSG_BUTTON_MENU = u8"Menu";
PROGMEM Language_Str MSG_BUTTON_MEDIA = u8"Media";
PROGMEM Language_Str MSG_BUTTON_OPEN = u8"Open";
PROGMEM Language_Str MSG_CLEAN_NOZZLE = u8"Clean Nozzle";
PROGMEM Language_Str MSG_VMAX_X = u8"Vmax X";
PROGMEM Language_Str MSG_VMAX_Y = u8"Vmax Y";
PROGMEM Language_Str MSG_VMAX_Z = u8"Vmax Z";
PROGMEM Language_Str MSG_ACCEL_PRINTING = u8"Printing";
PROGMEM Language_Str MSG_ACCEL_TRAVEL = u8"Travel";
PROGMEM Language_Str MSG_ACCEL_RETRACT = u8"Retraction";
PROGMEM Language_Str MSG_AMAX_X = u8"Amax X";
PROGMEM Language_Str MSG_AMAX_Y = u8"Amax Y";
PROGMEM Language_Str MSG_AMAX_Z = u8"Amax Z";
PROGMEM Language_Str MSG_AXIS_X = u8"X";
PROGMEM Language_Str MSG_AXIS_Y = u8"Y";
PROGMEM Language_Str MSG_AXIS_Z = u8"Z";
PROGMEM Language_Str MSG_AXIS_E = u8"E";
PROGMEM Language_Str MSG_AXIS_E1 = u8"E1";
PROGMEM Language_Str MSG_AXIS_E2 = u8"E2";
PROGMEM Language_Str MSG_AXIS_E3 = u8"E3";
PROGMEM Language_Str MSG_AXIS_E4 = u8"E4";
PROGMEM Language_Str MSG_AXIS_ALL = u8"All";
PROGMEM Language_Str MSG_HOME = u8"Home";
PROGMEM Language_Str MSG_PRINT_STARTING = u8"Print starting";
PROGMEM Language_Str MSG_PRINT_FINISHED = u8"Print finished";
PROGMEM Language_Str MSG_PRINT_ERROR = u8"Print error";
PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_1 = u8"Color Touch Panel";
PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_2 = u8"Portions " COPYRIGHT_SIGN " 2019 Aleph Objects, Inc.\n"
"Portions " COPYRIGHT_SIGN " 2019 Cocoa Press";
PROGMEM Language_Str MSG_FIRMWARE_FOR_TOOLHEAD = u8"Firmware for toolhead:\n%s\n\n";
PROGMEM Language_Str MSG_RUNOUT_1 = u8"Runout 1";
PROGMEM Language_Str MSG_RUNOUT_2 = u8"Runout 2";
PROGMEM Language_Str MSG_DISPLAY_MENU = u8"Display";
PROGMEM Language_Str MSG_INTERFACE_SETTINGS = u8"Interface Settings";
PROGMEM Language_Str MSG_MEASURE_AUTOMATICALLY = u8"Measure automatically";
PROGMEM Language_Str MSG_H_OFFSET = u8"H Offset";
PROGMEM Language_Str MSG_V_OFFSET = u8"V Offset";
PROGMEM Language_Str MSG_TOUCH_SCREEN = u8"Touch Screen";
PROGMEM Language_Str MSG_CALIBRATE = u8"Calibrate";
PROGMEM Language_Str MSG_UNITS_MILLIAMP = u8"mA";
PROGMEM Language_Str MSG_UNITS_MM = u8"mm";
PROGMEM Language_Str MSG_UNITS_MM_S = u8"mm/s";
PROGMEM Language_Str MSG_UNITS_MM_S2 = u8"mm/s" SUPERSCRIPT_TWO;
PROGMEM Language_Str MSG_UNITS_STEP_MM = u8"st/mm";
PROGMEM Language_Str MSG_UNITS_PERCENT = u8"%";
PROGMEM Language_Str MSG_UNITS_C = DEGREE_SIGN u8"C";
PROGMEM Language_Str MSG_MATERIAL_PLA = u8"PLA";
PROGMEM Language_Str MSG_MATERIAL_ABS = u8"ABS";
PROGMEM Language_Str MSG_MATERIAL_HIGH_TEMP = u8"High";
PROGMEM Language_Str MSG_IDLE = u8"idle";
PROGMEM Language_Str MSG_SET_MAXIMUM = u8"Set Maximum";
PROGMEM Language_Str MSG_PRINT_SPEED = u8"Print Speed";
PROGMEM Language_Str MSG_LINEAR_ADVANCE = u8"Linear Advance";
PROGMEM Language_Str MSG_LINEAR_ADVANCE_K = u8"K";
PROGMEM Language_Str MSG_LINEAR_ADVANCE_K1 = u8"K E1";
PROGMEM Language_Str MSG_LINEAR_ADVANCE_K2 = u8"K E2";
PROGMEM Language_Str MSG_LINEAR_ADVANCE_K3 = u8"K E3";
PROGMEM Language_Str MSG_LINEAR_ADVANCE_K4 = u8"K E4";
PROGMEM Language_Str MSG_NUDGE_NOZZLE = u8"Nudge Nozzle";
PROGMEM Language_Str MSG_ADJUST_BOTH_NOZZLES = u8"Adjust Both Nozzles";
PROGMEM Language_Str MSG_SHOW_OFFSETS = u8"Show Offsets";
PROGMEM Language_Str MSG_INCREMENT = u8"Increment";
PROGMEM Language_Str MSG_ERASE_FLASH_WARNING = u8"Are you sure? SPI flash will be erased.";
PROGMEM Language_Str MSG_ERASING = u8"Erasing...";
PROGMEM Language_Str MSG_ERASED = u8"SPI flash erased";
PROGMEM Language_Str MSG_CALIBRATION_WARNING = u8"For best results, unload the filament and clean the hotend prior to starting calibration. Continue?";
PROGMEM Language_Str MSG_START_PRINT_CONFIRMATION = u8"Start printing %s?";
PROGMEM Language_Str MSG_ABORT_WARNING = u8"Are you sure you want to cancel the print?";
PROGMEM Language_Str MSG_EXTRUDER_SELECTION = u8"Extruder Selection";
PROGMEM Language_Str MSG_CURRENT_TEMPERATURE = u8"Current Temp";
PROGMEM Language_Str MSG_REMOVAL_TEMPERATURE = u8"Removal Temp";
PROGMEM Language_Str MSG_CAUTION = u8"Caution:";
PROGMEM Language_Str MSG_HOT = u8"Hot!";
PROGMEM Language_Str MSG_UNLOAD_FILAMENT = u8"Unload/Retract";
PROGMEM Language_Str MSG_LOAD_FILAMENT = u8"Load/Extruder";
PROGMEM Language_Str MSG_MOMENTARY = u8"Momentary";
PROGMEM Language_Str MSG_CONTINUOUS = u8"Continuous";
PROGMEM Language_Str MSG_PLEASE_WAIT = u8"Please wait...";
PROGMEM Language_Str MSG_PRINT_MENU = u8"Print Menu";
PROGMEM Language_Str MSG_FINE_MOTION = u8"Fine motion";
PROGMEM Language_Str MSG_ENABLE_MEDIA = u8"Enable Media";
PROGMEM Language_Str MSG_INSERT_MEDIA = u8"Insert Media...";
PROGMEM Language_Str MSG_LCD_BRIGHTNESS = u8"LCD brightness";
PROGMEM Language_Str MSG_SOUND_VOLUME = u8"Sound volume";
PROGMEM Language_Str MSG_SCREEN_LOCK = u8"Screen lock";
PROGMEM Language_Str MSG_BOOT_SCREEN = u8"Boot screen";
PROGMEM Language_Str MSG_INTERFACE_SOUNDS = u8"Interface Sounds";
PROGMEM Language_Str MSG_CLICK_SOUNDS = u8"Click sounds";
PROGMEM Language_Str MSG_EEPROM_RESTORED = u8"Settings restored from backup";
PROGMEM Language_Str MSG_EEPROM_RESET = u8"Settings restored to default";
PROGMEM Language_Str MSG_EEPROM_SAVED = u8"Settings saved!";
PROGMEM Language_Str MSG_EEPROM_SAVE_PROMPT = u8"Do you wish to save these settings as defaults?";
PROGMEM Language_Str MSG_EEPROM_RESET_WARNING = u8"Are you sure? Customizations will be lost.";
PROGMEM Language_Str MSG_PASSCODE_REJECTED = u8"Wrong passcode!";
PROGMEM Language_Str MSG_PASSCODE_ACCEPTED = u8"Passcode accepted!";
PROGMEM Language_Str MSG_PASSCODE_SELECT = u8"Select Passcode:";
PROGMEM Language_Str MSG_PASSCODE_REQUEST = u8"Enter Passcode:";
PROGMEM Language_Str MSG_TOUCH_CALIBRATION_START = u8"Release to begin screen calibration";
PROGMEM Language_Str MSG_TOUCH_CALIBRATION_PROMPT = u8"Touch the dots to calibrate";
#ifdef TOUCH_UI_LULZBOT_BIO
PROGMEM Language_Str MSG_MOVE_TO_HOME = u8"Move to Home";
PROGMEM Language_Str MSG_RAISE_PLUNGER = u8"Raise Plunger";
PROGMEM Language_Str MSG_RELEASE_XY_AXIS = u8"Release X and Y Axis";
PROGMEM Language_Str MSG_AUTOLEVEL_X_AXIS = u8"Auto-level X Axis";
PROGMEM Language_Str MSG_BED_TEMPERATURE = u8"Bed Temperature";
PROGMEM Language_Str MSG_HOME_XYZ_WARNING = u8"About to move to home position. Ensure the top and the bed of the printer are clear.\n\nContinue?";
PROGMEM Language_Str MSG_HOME_E_WARNING = u8"About to re-home plunger and auto-level. Remove syringe prior to proceeding.\n\nContinue?";
#endif
#ifdef TOUCH_UI_COCOA_PRESS
PROGMEM Language_Str MSG_ZONE_1 = u8"Zone 1:";
PROGMEM Language_Str MSG_ZONE_2 = u8"Zone 2:";
PROGMEM Language_Str MSG_ZONE_3 = u8"Zone 3:";
PROGMEM Language_Str MSG_PREHEAT_FINISHED = u8"Preheat finished";
#endif
}; // namespace Language_en

View File

@ -0,0 +1,157 @@
/*********************
* marlin_events.cpp *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "compat.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens/screens.h"
namespace ExtUI {
using namespace Theme;
using namespace FTDI;
void onStartup() {
EventLoop::setup();
}
void onIdle() {
EventLoop::loop();
}
void onPrinterKilled(PGM_P const error, PGM_P const component) {
char str[strlen_P(error) + strlen_P(component) + 3];
sprintf_P(str, PSTR(S_FMT ": " S_FMT), error, component);
KillScreen::show(str);
}
void onMediaInserted() {
if (AT_SCREEN(StatusScreen))
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_INSERTED));
sound.play(media_inserted, PLAY_ASYNCHRONOUS);
}
void onMediaRemoved() {
if (AT_SCREEN(StatusScreen))
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_MEDIA_REMOVED));
sound.play(media_removed, PLAY_ASYNCHRONOUS);
if (AT_SCREEN(FilesScreen)) {
GOTO_SCREEN(StatusScreen)
}
}
void onMediaError() {
sound.play(sad_trombone, PLAY_ASYNCHRONOUS);
AlertDialogBox::showError(F("Unable to read media."));
}
void onStatusChanged(const char* lcd_msg) {
StatusScreen::setStatusMessage(lcd_msg);
}
void onStatusChanged(progmem_str lcd_msg) {
StatusScreen::setStatusMessage(lcd_msg);
}
void onPrintTimerStarted() {
InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_STARTED);
}
void onPrintTimerStopped() {
InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FINISHED);
}
void onPrintTimerPaused() {
}
void onFilamentRunout(const extruder_t extruder) {
char lcd_msg[30];
sprintf_P(lcd_msg, PSTR("Extruder %d Filament Error"), extruder + 1);
StatusScreen::setStatusMessage(lcd_msg);
InterfaceSoundsScreen::playEventSound(InterfaceSoundsScreen::PRINTING_FAILED);
}
void onFactoryReset() {
InterfaceSettingsScreen::defaultSettings();
}
void onStoreSettings(char *buff) {
InterfaceSettingsScreen::saveSettings(buff);
}
void onLoadSettings(const char *buff) {
InterfaceSettingsScreen::loadSettings(buff);
}
void onConfigurationStoreWritten(bool success) {
#ifdef ARCHIM2_SPI_FLASH_EEPROM_BACKUP_SIZE
if (success && InterfaceSettingsScreen::backupEEPROM()) {
SERIAL_ECHOLNPGM("Made backup of EEPROM to SPI Flash");
}
#else
UNUSED(success);
#endif
}
void onConfigurationStoreRead(bool) {
}
void onPlayTone(const uint16_t frequency, const uint16_t duration) {
sound.play_tone(frequency, duration);
}
void onUserConfirmRequired(const char * const msg) {
if (msg)
ConfirmUserRequestAlertBox::show(msg);
else
ConfirmUserRequestAlertBox::hide();
}
#if HAS_LEVELING && HAS_MESH
void onMeshUpdate(const int8_t, const int8_t, const float) {
}
#endif
#if HAS_PID_HEATING
void OnPidTuning(const result_t rst) {
// Called for temperature PID tuning result
SERIAL_ECHOLNPAIR("OnPidTuning:", rst);
switch (rst) {
case PID_BAD_EXTRUDER_NUM:
StatusScreen::setStatusMessage(STR_PID_BAD_EXTRUDER_NUM);
break;
case PID_TEMP_TOO_HIGH:
StatusScreen::setStatusMessage(STR_PID_TEMP_TOO_HIGH);
break;
case PID_TUNING_TIMEOUT:
StatusScreen::setStatusMessage(STR_PID_TIMEOUT);
break;
case PID_DONE:
StatusScreen::setStatusMessage(STR_PID_AUTOTUNE_FINISHED);
break;
}
GOTO_SCREEN(StatusScreen);
}
#endif // HAS_PID_HEATING
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,151 @@
/******************
* pin_mappings.h *
******************/
/****************************************************************************
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#pragma once
/* This file defines mappings from the ULTRA_LCD pins functions to new
* functions for the FTDI display. These mappings allows any board that
* support ULTRA_LCD via EXP1 and EXP2 connectors to use FTDI modules
* without adding new pin definitions to the board.
*/
#ifdef S6_TFT_PINMAP
#ifndef __MARLIN_FIRMWARE__
#error "This pin mapping requires Marlin."
#endif
#define CLCD_SPI_CS PC7
#define CLCD_MOD_RESET PC6
#endif
#ifdef CR10_TFT_PINMAP
#ifndef __MARLIN_FIRMWARE__
#error "This pin mapping requires Marlin."
#endif
#define CLCD_USE_SOFT_SPI
#define CLCD_SOFT_SPI_SCLK LCD_PINS_D4 // PORTA1 Pin 6
#define CLCD_SOFT_SPI_MOSI LCD_PINS_ENABLE // PORTC1 Pin 8
#define CLCD_SPI_CS LCD_PINS_RS // PORTA3 Pin 7
#define CLCD_SOFT_SPI_MISO 16 // PORTC0 BTN_ENC Pin 2
#define CLCD_MOD_RESET 11 // PORTD3 BTN_EN1 Pin 3
#define CLCD_AUX_0 10 // PORTD2 BTN_EN2 Pin 5
#define CLCD_AUX_1 BEEPER_PIN // PORTA4 Pin 1
#endif
/**
* The AlephObjects pinout for re-purposing the UltraLCD
* connector EXP1 for software SPI (rev B, obsolete)
*/
#ifdef AO_EXP1_DEPRECATED_PINMAP
#ifndef __MARLIN_FIRMWARE__
#error "This pin mapping requires Marlin."
#endif
#define CLCD_MOD_RESET LCD_PINS_D4
#define CLCD_SPI_CS LCD_PINS_D5
#define CLCD_AUX_0 LCD_PINS_ENABLE
#define CLCD_AUX_1 BTN_ENC
#define CLCD_AUX_2 BEEPER_PIN
#define CLCD_USE_SOFT_SPI
#define CLCD_SOFT_SPI_SCLK LCD_PINS_D7
#define CLCD_SOFT_SPI_MOSI LCD_PINS_D6
#define CLCD_SOFT_SPI_MISO LCD_PINS_RS
#endif
/**
* AO_EXP1_PINMAP
*
* The AlephObjects mapping for re-purposing the UltraLCD
* connector EXP1 for software SPI for display (rev C):
*
* EXP2: FTDI: SD -or- USB [1]: ULTRA_LCD:
* 1 MISO MISO MISO --> BEEPER
* 2 SCLK SCLK SCLK --> BTN_ENC
* 3 PD_N - - --> LCDE
* 4 - CS_N CS_N --> LCDRS
* 5 CS_N - - --> LCD4
* 6 MOSI MOSI MOSI --> LCD5
* 7 - SD_DET INT --> LCD6
* 8 RESET - RESET --> LCD4
* 9 GND GND GND --> GND
* 10 5V 5V 5V --> 5V
*
* [1] At the moment, Marlin does not support SD or USB
* functionality over software SPI.
*/
#ifdef AO_EXP1_PINMAP
#ifndef __MARLIN_FIRMWARE__
#error "This pin mapping requires Marlin."
#endif
#define CLCD_MOD_RESET LCD_PINS_ENABLE
#define CLCD_SPI_CS LCD_PINS_D4
#define CLCD_USE_SOFT_SPI
#define CLCD_SOFT_SPI_SCLK BTN_ENC
#define CLCD_SOFT_SPI_MOSI LCD_PINS_D5
#define CLCD_SOFT_SPI_MISO BEEPER_PIN
#endif
/**
* AO_EXP2_PINMAP
*
* The AlephObjects mapping for re-purposing the UltraLCD
* connector EXP2 for hardware SPI for display and SD card
* or USB (rev C):
*
* EXP2: FTDI: SD -or- USB: ULTRA_LCD:
* 1 MISO MISO MISO --> MISO
* 2 SCLK SCLK SCLK --> SCLK
* 3 PD_N - - --> BTN_EN2
* 4 - CS_N CS_N --> SD_CSEL
* 5 CS_N - - --> BTN_EN1
* 6 MOSI MOSI MOSI --> MOSI
* 7 - SD_DET INT --> SD_DET
* 8 RESET - RESET --> RESET
* 9 GND GND GND --> GND
* 10 5V 5V 5V --> KILL [3]
*
* [1] This configuration is not compatible with the
* EinsyRetro 1.1a because there is a level shifter
* on MISO enabled by SD/USB chip select.
*
* [2] This configuration allows daisy-chaining of the
* display and SD/USB on EXP2.
*
* [3] Archim Rambo provides 5V on this pin. On any other
* board, divert this wire from the ribbon cable and
* connect it to 5V at an endstop.
*/
#ifdef AO_EXP2_PINMAP
#ifndef __MARLIN_FIRMWARE__
#error "This pin mapping requires Marlin."
#endif
#define CLCD_SPI_CS BTN_EN1
#define CLCD_MOD_RESET BTN_EN2
#endif

View File

@ -0,0 +1,94 @@
/********************
* about_screen.cpp *
********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#define GRID_COLS 4
#define GRID_ROWS 9
using namespace FTDI;
using namespace Theme;
using namespace ExtUI;
void AboutScreen::onEntry() {
BaseScreen::onEntry();
sound.play(chimes, PLAY_ASYNCHRONOUS);
}
void AboutScreen::onRedraw(draw_mode_t) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0);
draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(4,1),
#ifdef CUSTOM_MACHINE_NAME
F(CUSTOM_MACHINE_NAME)
#else
GET_TEXT_F(MSG_ABOUT_TOUCH_PANEL_1)
#endif
, OPT_CENTER, font_xlarge
);
#ifdef TOOLHEAD_NAME
char about_str[
strlen_P(GET_TEXT(FIRMWARE_FOR_TOOLHEAD)) +
strlen_P(TOOLHEAD_NAME) +
strlen_P(GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2)) + 1
];
sprintf_P(about_str, GET_TEXT(MSG_FIRMWARE_FOR_TOOLHEAD), TOOLHEAD_NAME);
strcat_P (about_str, GET_TEXT(MSG_ABOUT_TOUCH_PANEL_2));
#endif
cmd.tag(2);
draw_text_box(cmd, BTN_POS(1,3), BTN_SIZE(4,3),
#ifdef TOOLHEAD_NAME
about_str
#else
GET_TEXT_F(MSG_ABOUT_TOUCH_PANEL_2)
#endif
, OPT_CENTER, font_medium
);
cmd.tag(0);
draw_text_box(cmd, BTN_POS(1,6), BTN_SIZE(4,2), progmem_str(getFirmwareName_str()), OPT_CENTER, font_medium);
cmd.font(font_medium).colors(action_btn).tag(1).button(BTN_POS(2,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BUTTON_OKAY));
}
bool AboutScreen::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); return true;
#if ENABLED(TOUCH_UI_DEVELOPER_MENU)
case 2: GOTO_SCREEN(DeveloperMenu); return true;
#endif
default: return false;
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,205 @@
/*****************************
* advance_settings_menu.cpp *
*****************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && !defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color))
.cmd(CLEAR(true,true,true));
}
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(Theme::font_medium)
#ifdef TOUCH_UI_PORTRAIT
#define GRID_ROWS 10
#define GRID_COLS 2
.enabled(
#if HAS_BED_PROBE
1
#endif
)
.tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET))
.enabled(
#if HAS_CASE_LIGHT
1
#endif
)
.tag(16).button( BTN_POS(1,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_CASE_LIGHT))
.tag(3) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(13).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(14).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_TMC_HOMING_THRS))
.enabled(
#if HOTENDS > 1
1
#endif
)
.tag(4) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_OFFSETS_MENU))
.enabled(
#if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR)
1
#endif
)
.tag(11).button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENT))
.tag(12).button( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS))
.tag(15).button( BTN_POS(2,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU))
.tag(9) .button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS))
.tag(10).button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS))
.tag(5) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY))
.tag(6) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION))
#if DISABLED(CLASSIC_JERK)
.tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION))
#else
.tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK))
#endif
.enabled(
#if ENABLED(BACKLASH_GCODE)
1
#endif
)
.tag(8).button( BTN_POS(2,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACKLASH))
.colors(action_btn)
.tag(1) .button( BTN_POS(1,10), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
#undef GRID_COLS
#undef GRID_ROWS
#else
#define GRID_ROWS 6
#define GRID_COLS 3
.enabled(
#if HAS_BED_PROBE
1
#endif
)
.tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_ZPROBE_ZOFFSET))
.enabled(
#if HAS_CASE_LIGHT
1
#endif
)
.tag(16).button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_CASE_LIGHT))
.enabled(1)
.tag(3) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(13).button( BTN_POS(3,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(14).button( BTN_POS(3,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_HOMING_THRS))
.enabled(
#if ENABLED(BACKLASH_GCODE)
1
#endif
)
.tag(8).button( BTN_POS(3,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACKLASH))
.enabled(
#if HOTENDS > 1
1
#endif
)
.tag(4) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_OFFSETS_MENU))
.tag(12).button( BTN_POS(3,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS))
.tag(5) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY))
.tag(6) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION))
#if DISABLED(CLASSIC_JERK)
.tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION))
#else
.tag(7) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK))
#endif
.tag(11).button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_FILAMENT))
.tag(15).button( BTN_POS(3,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU))
.tag(9) .button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS))
.tag(10).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS))
.colors(action_btn)
.tag(1) .button( BTN_POS(3,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACK));
#endif
}
}
bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
#if HAS_BED_PROBE
case 2: GOTO_SCREEN(ZOffsetScreen); break;
#endif
case 3: GOTO_SCREEN(StepsScreen); break;
#if HOTENDS > 1
case 4: GOTO_SCREEN(NozzleOffsetScreen); break;
#endif
case 5: GOTO_SCREEN(MaxVelocityScreen); break;
case 6: GOTO_SCREEN(DefaultAccelerationScreen); break;
case 7:
#if DISABLED(CLASSIC_JERK)
GOTO_SCREEN(JunctionDeviationScreen);
#else
GOTO_SCREEN(JerkScreen);
#endif
break;
#if ENABLED(BACKLASH_GCODE)
case 8: GOTO_SCREEN(BacklashCompensationScreen); break;
#endif
case 9: GOTO_SCREEN(InterfaceSettingsScreen); LockScreen::check_passcode(); break;
case 10: GOTO_SCREEN(RestoreFailsafeDialogBox); LockScreen::check_passcode(); break;
#if EITHER(LIN_ADVANCE, FILAMENT_RUNOUT_SENSOR)
case 11: GOTO_SCREEN(FilamentMenu); break;
#endif
case 12: GOTO_SCREEN(EndstopStatesScreen); break;
#if HAS_TRINAMIC_CONFIG
case 13: GOTO_SCREEN(StepperCurrentScreen); break;
case 14: GOTO_SCREEN(StepperBumpSensitivityScreen); break;
#endif
case 15: GOTO_SCREEN(DisplayTuningScreen); break;
#if HAS_CASE_LIGHT
case 16: GOTO_SCREEN(CaseLightScreen); break;
#endif
default: return false;
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,70 @@
/************************
* alert_dialog_box.cpp *
************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "screen_data.h"
using namespace FTDI;
using namespace Theme;
void AlertDialogBox::onEntry() {
BaseScreen::onEntry();
sound.play(screen_data.AlertDialogBox.isError ? sad_trombone : twinkle, PLAY_ASYNCHRONOUS);
}
void AlertDialogBox::onRedraw(draw_mode_t what) {
if (what & FOREGROUND) {
drawOkayButton();
}
}
template<typename T>
void AlertDialogBox::show(const T message) {
drawMessage(message);
storeBackground();
screen_data.AlertDialogBox.isError = false;
GOTO_SCREEN(AlertDialogBox);
}
template<typename T>
void AlertDialogBox::showError(const T message) {
drawMessage(message);
storeBackground();
screen_data.AlertDialogBox.isError = true;
GOTO_SCREEN(AlertDialogBox);
}
void AlertDialogBox::hide() {
if (AT_SCREEN(AlertDialogBox))
GOTO_PREVIOUS();
}
template void AlertDialogBox::show(const char *);
template void AlertDialogBox::show(const progmem_str);
template void AlertDialogBox::showError(const char *);
template void AlertDialogBox::showError(const progmem_str);
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,76 @@
/************************************
* backlash_compensation_screen.cpp *
************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if BOTH(TOUCH_UI_FTDI_EVE, BACKLASH_GCODE)
#include "screens.h"
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
void BacklashCompensationScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
w.precision(2).units( GET_TEXT_F(MSG_UNITS_MM));
w.heading( GET_TEXT_F(MSG_BACKLASH));
w.color(x_axis).adjuster(2, GET_TEXT_F(MSG_AXIS_X), getAxisBacklash_mm(X));
w.color(y_axis).adjuster(4, GET_TEXT_F(MSG_AXIS_Y), getAxisBacklash_mm(Y));
w.color(z_axis).adjuster(6, GET_TEXT_F(MSG_AXIS_Z), getAxisBacklash_mm(Z));
#if ENABLED(CALIBRATION_GCODE)
w.button(12, GET_TEXT_F(MSG_MEASURE_AUTOMATICALLY));
#endif
#ifdef BACKLASH_SMOOTHING_MM
w.color(other).adjuster(8, GET_TEXT_F(MSG_BACKLASH_SMOOTHING), getBacklashSmoothing_mm());
#endif
w.precision(0).units(GET_TEXT_F(MSG_UNITS_PERCENT))
.adjuster(10, GET_TEXT_F(MSG_BACKLASH_CORRECTION), getBacklashCorrection_percent());
w.precision(2).increments();
}
bool BacklashCompensationScreen::onTouchHeld(uint8_t tag) {
const float increment = getIncrement();
switch (tag) {
case 2: UI_DECREMENT(AxisBacklash_mm, X); break;
case 3: UI_INCREMENT(AxisBacklash_mm, X); break;
case 4: UI_DECREMENT(AxisBacklash_mm, Y); break;
case 5: UI_INCREMENT(AxisBacklash_mm, Y); break;
case 6: UI_DECREMENT(AxisBacklash_mm, Z); break;
case 7: UI_INCREMENT(AxisBacklash_mm, Z); break;
#ifdef BACKLASH_SMOOTHING_MM
case 8: UI_DECREMENT(BacklashSmoothing_mm); break;
case 9: UI_INCREMENT(BacklashSmoothing_mm); break;
#endif
case 10: UI_DECREMENT_BY(BacklashCorrection_percent, increment*100); break;
case 11: UI_INCREMENT_BY(BacklashCorrection_percent, increment*100); break;
#if ENABLED(CALIBRATION_GCODE)
case 12: GOTO_SCREEN(ConfirmAutoCalibrationDialogBox); return true;
#endif
default:
return false;
}
SaveSettingsDialogBox::settingsChanged();
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,384 @@
/**************************************
* base_numeric_adjustment_screen.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "screen_data.h"
using namespace FTDI;
using namespace Theme;
#ifdef TOUCH_UI_PORTRAIT
#define GRID_COLS 13
#define GRID_ROWS 10
#define LAYOUT_FONT font_small
#else
#define GRID_COLS 18
#define GRID_ROWS 7
#define LAYOUT_FONT font_medium
#endif
BaseNumericAdjustmentScreen::widgets_t::widgets_t(draw_mode_t what) : _what(what) {
CommandProcessor cmd;
if (what & BACKGROUND) {
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.colors(normal_btn)
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0);
}
cmd.font(font_medium);
_button(cmd, 1,
#ifdef TOUCH_UI_PORTRAIT
BTN_POS(1,10), BTN_SIZE(13,1),
#else
BTN_POS(15,7), BTN_SIZE(4,1),
#endif
GET_TEXT_F(MSG_BACK), true, true
);
_line = 1;
_units = F("");
}
/**
* Speed optimization for changing button style.
*/
void BaseNumericAdjustmentScreen::widgets_t::_button_style(CommandProcessor &cmd, BaseNumericAdjustmentScreen::widgets_t::style_t style) {
if (_style != style) {
const btn_colors *old_colors = &normal_btn;
const btn_colors *new_colors = &normal_btn;
switch(_style) {
case BTN_ACTION: old_colors = &action_btn; break;
case BTN_TOGGLE: old_colors = &ui_toggle; break;
case BTN_DISABLED: old_colors = &disabled_btn; break;
default: break;
}
switch(style) {
case BTN_ACTION: new_colors = &action_btn; break;
case BTN_TOGGLE: new_colors = &ui_toggle; break;
case BTN_DISABLED: new_colors = &disabled_btn; break;
default: break;
}
const bool rgb_changed = (old_colors->rgb != new_colors->rgb) ||
(_style == TEXT_LABEL && style != TEXT_LABEL) ||
(_style != TEXT_LABEL && style == TEXT_LABEL);
const bool grad_changed = old_colors->grad != new_colors->grad;
const bool fg_changed = (old_colors->fg != new_colors->fg) || (_style == TEXT_AREA);
const bool bg_changed = old_colors->bg != new_colors->bg;
if (rgb_changed) cmd.cmd(COLOR_RGB(style == TEXT_LABEL ? bg_text_enabled : new_colors->rgb));
if (grad_changed) cmd.gradcolor(new_colors->grad);
if (fg_changed) cmd.fgcolor(new_colors->fg);
if (bg_changed) cmd.bgcolor(new_colors->bg);
_style = style;
}
}
/**
* Speed optimization for drawing buttons. Draw all unpressed buttons in the
* background layer and draw only the pressed button in the foreground layer.
*/
void BaseNumericAdjustmentScreen::widgets_t::_button(CommandProcessor &cmd, uint8_t tag, int16_t x, int16_t y, int16_t w, int16_t h, progmem_str text, bool enabled, bool highlight) {
if (_what & BACKGROUND) enabled = true;
if ((_what & BACKGROUND) || buttonIsPressed(tag) || highlight || !enabled) {
_button_style(cmd, (!enabled) ? BTN_DISABLED : (highlight ? BTN_ACTION : BTN_NORMAL));
cmd.tag(enabled ? tag : 0).button(x, y, w, h, text);
}
}
BaseNumericAdjustmentScreen::widgets_t &BaseNumericAdjustmentScreen::widgets_t::precision(uint8_t decimals, precision_default_t initial) {
_decimals = decimals;
if (screen_data.BaseNumericAdjustmentScreen.increment == 0) {
screen_data.BaseNumericAdjustmentScreen.increment = 243 + (initial - DEFAULT_LOWEST) - _decimals;
}
return *this;
}
void BaseNumericAdjustmentScreen::widgets_t::heading(progmem_str label) {
if (_what & BACKGROUND) {
CommandProcessor cmd;
_button_style(cmd, TEXT_LABEL);
cmd.font(font_medium)
.tag(0)
.text(
#ifdef TOUCH_UI_PORTRAIT
BTN_POS(1, _line), BTN_SIZE(12,1),
#else
BTN_POS(5, _line), BTN_SIZE(8,1),
#endif
label
);
}
_line++;
}
#ifdef TOUCH_UI_PORTRAIT
#ifdef TOUCH_UI_800x480
#undef EDGE_R
#define EDGE_R 20
#else
#undef EDGE_R
#define EDGE_R 10
#endif
#endif
void BaseNumericAdjustmentScreen::widgets_t::_draw_increment_btn(CommandProcessor &cmd, uint8_t, const uint8_t tag) {
const char *label = PSTR("?");
uint8_t pos;
uint8_t & increment = screen_data.BaseNumericAdjustmentScreen.increment;
if (increment == 0) {
increment = tag; // Set the default value to be the first.
}
switch (tag) {
case 240: label = PSTR( ".001"); pos = _decimals - 3; break;
case 241: label = PSTR( ".01" ); pos = _decimals - 2; break;
case 242: label = PSTR( "0.1" ); pos = _decimals - 1; break;
case 243: label = PSTR( "1" ); pos = _decimals + 0; break;
case 244: label = PSTR( "10" ); pos = _decimals + 1; break;
default: label = PSTR("100" ); pos = _decimals + 2; break;
}
const bool highlight = (_what & FOREGROUND) && (increment == tag);
switch (pos) {
#ifdef TOUCH_UI_PORTRAIT
case 0: _button(cmd, tag, BTN_POS(5,_line), BTN_SIZE(2,1), progmem_str(label), true, highlight); break;
case 1: _button(cmd, tag, BTN_POS(7,_line), BTN_SIZE(2,1), progmem_str(label), true, highlight); break;
case 2: _button(cmd, tag, BTN_POS(9,_line), BTN_SIZE(2,1), progmem_str(label), true, highlight); break;
#else
case 0: _button(cmd, tag, BTN_POS(15,2), BTN_SIZE(4,1), progmem_str(label), true, highlight); break;
case 1: _button(cmd, tag, BTN_POS(15,3), BTN_SIZE(4,1), progmem_str(label), true, highlight); break;
case 2: _button(cmd, tag, BTN_POS(15,4), BTN_SIZE(4,1), progmem_str(label), true, highlight); break;
#endif
}
}
void BaseNumericAdjustmentScreen::widgets_t::increments() {
CommandProcessor cmd;
cmd.font(LAYOUT_FONT);
if (_what & BACKGROUND) {
_button_style(cmd, TEXT_LABEL);
cmd.tag(0).text(
#ifdef TOUCH_UI_PORTRAIT
BTN_POS(1, _line), BTN_SIZE(4,1),
#else
BTN_POS(15, 1), BTN_SIZE(4,1),
#endif
GET_TEXT_F(MSG_INCREMENT)
);
}
_draw_increment_btn(cmd, _line+1, 245 - _decimals);
_draw_increment_btn(cmd, _line+1, 244 - _decimals);
_draw_increment_btn(cmd, _line+1, 243 - _decimals);
#ifdef TOUCH_UI_PORTRAIT
_line++;
#endif
}
void BaseNumericAdjustmentScreen::widgets_t::adjuster_sram_val(uint8_t tag, progmem_str label, const char *value, bool is_enabled) {
CommandProcessor cmd;
if (_what & BACKGROUND) {
_button_style(cmd, TEXT_LABEL);
cmd.tag(0)
.font(font_small)
.text( BTN_POS(1,_line), BTN_SIZE(4,1), label);
_button_style(cmd, TEXT_AREA);
cmd.fgcolor(_color).button( BTN_POS(5,_line), BTN_SIZE(5,1), F(""), OPT_FLAT);
}
cmd.font(font_medium);
_button(cmd, tag, BTN_POS(10,_line), BTN_SIZE(2,1), F("-"), is_enabled);
_button(cmd, tag + 1, BTN_POS(12,_line), BTN_SIZE(2,1), F("+"), is_enabled);
if ((_what & FOREGROUND) && is_enabled) {
_button_style(cmd, BTN_NORMAL);
cmd.tag(0)
.font(font_small)
.text(BTN_POS(5,_line), BTN_SIZE(5,1), value);
}
_line++;
}
void BaseNumericAdjustmentScreen::widgets_t::adjuster(uint8_t tag, progmem_str label, const char *value, bool is_enabled) {
if (_what & BACKGROUND) {
adjuster_sram_val(tag, label, nullptr);
}
if (_what & FOREGROUND) {
char b[strlen_P(value)+1];
strcpy_P(b,value);
adjuster_sram_val(tag, label, b, is_enabled);
}
}
void BaseNumericAdjustmentScreen::widgets_t::adjuster(uint8_t tag, progmem_str label, float value, bool is_enabled) {
if (_what & BACKGROUND) {
adjuster_sram_val(tag, label, nullptr);
}
if (_what & FOREGROUND) {
char b[32];
dtostrf(value, 5, _decimals, b);
strcat_P(b, PSTR(" "));
strcat_P(b, (const char*) _units);
adjuster_sram_val(tag, label, b, is_enabled);
}
}
void BaseNumericAdjustmentScreen::widgets_t::button(uint8_t tag, progmem_str label, bool is_enabled) {
CommandProcessor cmd;
cmd.font(LAYOUT_FONT);
_button(cmd, tag, BTN_POS(5,_line), BTN_SIZE(9,1), label, is_enabled);
_line++;
}
void BaseNumericAdjustmentScreen::widgets_t::text_field(uint8_t tag, progmem_str label, const char *value, bool is_enabled) {
CommandProcessor cmd;
if (_what & BACKGROUND) {
_button_style(cmd, TEXT_LABEL);
cmd.enabled(1)
.tag(0)
.font(font_small)
.text( BTN_POS(1,_line), BTN_SIZE(4,1), label);
_button_style(cmd, TEXT_AREA);
cmd.fgcolor(_color)
.tag(tag)
.button( BTN_POS(5,_line), BTN_SIZE(9,1), F(""), OPT_FLAT);
}
if (_what & FOREGROUND) {
cmd.font(font_small).text( BTN_POS(5,_line), BTN_SIZE(9,1), is_enabled ? value : "-");
}
_line++;
}
void BaseNumericAdjustmentScreen::widgets_t::two_buttons(uint8_t tag1, progmem_str label1, uint8_t tag2, progmem_str label2, bool is_enabled) {
CommandProcessor cmd;
cmd.font(LAYOUT_FONT);
_button(cmd, tag1, BTN_POS(5,_line), BTN_SIZE(4.5,1), label1, is_enabled);
_button(cmd, tag2, BTN_POS(9.5,_line), BTN_SIZE(4.5,1), label2, is_enabled);
_line++;
}
void BaseNumericAdjustmentScreen::widgets_t::toggle(uint8_t tag, progmem_str label, bool value, bool is_enabled) {
CommandProcessor cmd;
if (_what & BACKGROUND) {
_button_style(cmd, TEXT_LABEL);
cmd.font(font_small)
.text(
#ifdef TOUCH_UI_PORTRAIT
BTN_POS(1, _line), BTN_SIZE( 8,1),
#else
BTN_POS(1, _line), BTN_SIZE(10,1),
#endif
label
);
}
if (_what & FOREGROUND) {
_button_style(cmd, BTN_TOGGLE);
cmd.tag(is_enabled ? tag : 0)
.enabled(is_enabled)
.font(font_small)
.toggle2(
#ifdef TOUCH_UI_PORTRAIT
BTN_POS( 9,_line), BTN_SIZE(5,1),
#else
BTN_POS(10,_line), BTN_SIZE(4,1),
#endif
GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), value
);
}
_line++;
}
void BaseNumericAdjustmentScreen::widgets_t::home_buttons(uint8_t tag) {
CommandProcessor cmd;
if (_what & BACKGROUND) {
_button_style(cmd, TEXT_LABEL);
cmd.font(font_small)
.text(BTN_POS(1, _line), BTN_SIZE(4,1), GET_TEXT_F(MSG_HOME));
}
cmd.font(LAYOUT_FONT);
_button(cmd, tag+0, BTN_POS(5,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_X));
_button(cmd, tag+1, BTN_POS(7,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Y));
_button(cmd, tag+2, BTN_POS(9,_line), BTN_SIZE(2,1), GET_TEXT_F(MSG_AXIS_Z));
_button(cmd, tag+3, BTN_POS(11,_line), BTN_SIZE(3,1), GET_TEXT_F(MSG_AXIS_ALL));
_line++;
}
void BaseNumericAdjustmentScreen::onEntry() {
screen_data.BaseNumericAdjustmentScreen.increment = 0; // This will force the increment to be picked while drawing.
BaseScreen::onEntry();
CommandProcessor cmd;
cmd.set_button_style_callback(nullptr);
}
bool BaseNumericAdjustmentScreen::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); return true;
case 240 ... 245: screen_data.BaseNumericAdjustmentScreen.increment = tag; break;
default: return current_screen.onTouchHeld(tag);
}
return true;
}
float BaseNumericAdjustmentScreen::getIncrement() {
switch (screen_data.BaseNumericAdjustmentScreen.increment) {
case 240: return 0.001;
case 241: return 0.01;
case 242: return 0.1;
case 243: return 1.0;
case 244: return 10.0;
case 245: return 100.0;
default: return 0.0;
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,90 @@
/*******************
* base_screen.cpp *
*******************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
using namespace FTDI;
using namespace Theme;
void BaseScreen::onEntry() {
CommandProcessor cmd;
cmd.set_button_style_callback(buttonStyleCallback);
reset_menu_timeout();
UIScreen::onEntry();
}
bool BaseScreen::buttonIsPressed(uint8_t tag) {
return tag != 0 && EventLoop::get_pressed_tag() == tag;
}
bool BaseScreen::buttonStyleCallback(CommandProcessor &cmd, uint8_t tag, uint8_t &style, uint16_t &options, bool post) {
if (post) {
cmd.colors(normal_btn);
return false;
}
#ifdef LCD_TIMEOUT_TO_STATUS
if (EventLoop::get_pressed_tag() != 0) {
reset_menu_timeout();
}
#endif
if (buttonIsPressed(tag)) {
options = OPT_FLAT;
}
if (style & cmd.STYLE_DISABLED) {
cmd.tag(0);
style &= ~cmd.STYLE_DISABLED;
cmd.colors(disabled_btn);
return true; // Call me again to reset the colors
}
return false;
}
void BaseScreen::onIdle() {
#ifdef LCD_TIMEOUT_TO_STATUS
if ((millis() - last_interaction) > LCD_TIMEOUT_TO_STATUS) {
reset_menu_timeout();
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_MSG("Returning to status due to menu timeout");
#endif
GOTO_SCREEN(StatusScreen);
}
#endif
}
void BaseScreen::reset_menu_timeout() {
#ifdef LCD_TIMEOUT_TO_STATUS
last_interaction = millis();
#endif
}
#ifdef LCD_TIMEOUT_TO_STATUS
uint32_t BaseScreen::last_interaction;
#endif
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,137 @@
/*****************************
* bio_advanced_settings.cpp *
*****************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
using namespace Theme;
void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color))
.cmd(CLEAR(true,true,true));
}
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(Theme::font_medium)
#define GRID_ROWS 9
#define GRID_COLS 2
.tag(2) .button( BTN_POS(1,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_DISPLAY_MENU))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(3) .button( BTN_POS(1,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_CURRENT))
.enabled(
#if HAS_TRINAMIC_CONFIG
1
#endif
)
.tag(4) .button( BTN_POS(1,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_TMC_HOMING_THRS))
.tag(5) .button( BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_LCD_ENDSTOPS))
.enabled(
#if HOTENDS > 1
1
#endif
)
.tag(6) .button( BTN_POS(1,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_OFFSETS_MENU))
.tag(7) .button( BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM))
.tag(8) .button( BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY))
.tag(9) .button( BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION))
#if DISABLED(CLASSIC_JERK)
.tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JUNCTION_DEVIATION))
#else
.tag(10) .button( BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_JERK))
#endif
.enabled(
#if ENABLED(BACKLASH_GCODE)
1
#endif
)
.tag(11) .button( BTN_POS(2,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_BACKLASH))
.enabled(
#if ENABLED(LIN_ADVANCE)
1
#endif
)
.tag(12) .button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_LINEAR_ADVANCE))
.tag(13) .button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS))
.tag(14) .button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_RESTORE_DEFAULTS))
.colors(action_btn)
.tag(1). button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
#undef GRID_COLS
#undef GRID_ROWS
}
}
bool AdvancedSettingsMenu::onTouchEnd(uint8_t tag) {
using namespace ExtUI;
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
case 2: GOTO_SCREEN(DisplayTuningScreen); break;
#if HAS_TRINAMIC_CONFIG
case 3: GOTO_SCREEN(StepperCurrentScreen); break;
case 4: GOTO_SCREEN(StepperBumpSensitivityScreen); break;
#endif
case 5: GOTO_SCREEN(EndstopStatesScreen); break;
#if HOTENDS > 1
case 6: GOTO_SCREEN(NozzleOffsetScreen); break;
#endif
case 7: GOTO_SCREEN(StepsScreen); break;
case 8: GOTO_SCREEN(MaxVelocityScreen); break;
case 9: GOTO_SCREEN(DefaultAccelerationScreen); break;
case 10:
#if DISABLED(CLASSIC_JERK)
GOTO_SCREEN(JunctionDeviationScreen);
#else
GOTO_SCREEN(JerkScreen);
#endif
break;
#if ENABLED(BACKLASH_GCODE)
case 11: GOTO_SCREEN(BacklashCompensationScreen); break;
#endif
#if ENABLED(LIN_ADVANCE)
case 12: GOTO_SCREEN(LinearAdvanceScreen); break;
#endif
case 13: GOTO_SCREEN(InterfaceSettingsScreen); break;
case 14: GOTO_SCREEN(RestoreFailsafeDialogBox); break;
default:
return false;
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,54 @@
/****************************
* bio_confirm_home_xyz.cpp *
****************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
void BioConfirmHomeE::onRedraw(draw_mode_t) {
drawMessage(GET_TEXT_F(MSG_HOME_E_WARNING));
drawYesNoButtons(1);
}
bool BioConfirmHomeE::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
SpinnerDialogBox::enqueueAndWait_P(F(
"G28 E\n"
AXIS_LEVELING_COMMANDS "\n"
PARK_AND_RELEASE_COMMANDS
));
current_screen.forget();
break;
case 2:
GOTO_SCREEN(StatusScreen);
break;
default:
return DialogBoxBaseClass::onTouchEnd(tag);
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,53 @@
/****************************
* bio_confirm_home_xyz.cpp *
****************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
void BioConfirmHomeXYZ::onRedraw(draw_mode_t) {
drawMessage(GET_TEXT_F(MSG_HOME_XYZ_WARNING));
drawYesNoButtons(1);
}
bool BioConfirmHomeXYZ::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
SpinnerDialogBox::enqueueAndWait_P(F(
"G28\n"
PARK_AND_RELEASE_COMMANDS
));
current_screen.forget();
break;
case 2:
GOTO_SCREEN(StatusScreen);
break;
default:
return DialogBoxBaseClass::onTouchEnd(tag);
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,86 @@
/*********************
* bio_main_menu.cpp *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
using namespace Theme;
void MainMenu::onRedraw(draw_mode_t what) {
#define GRID_ROWS 10
#define GRID_COLS 2
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(Theme::bg_color))
.cmd(CLEAR(true,true,true))
.tag(0);
}
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.cmd(COLOR_RGB(bg_text_enabled))
.font(font_large).text( BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_MAIN))
.colors(normal_btn)
.font(font_medium)
.tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_MOVE_TO_HOME))
.tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_RAISE_PLUNGER))
.tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_RELEASE_XY_AXIS))
.tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_AUTOLEVEL_X_AXIS))
.tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_BED_TEMPERATURE))
.tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_INTERFACE_SETTINGS))
.tag(8).button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_ADVANCED_SETTINGS))
.tag(9).button( BTN_POS(1,9), BTN_SIZE(2,1), GET_TEXT_F(MSG_INFO_MENU))
.colors(action_btn)
.tag(1).button( BTN_POS(1,10), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
}
#undef GRID_COLS
#undef GRID_ROWS
}
bool MainMenu::onTouchEnd(uint8_t tag) {
using namespace ExtUI;
const bool e_homed = isAxisPositionKnown(E0);
switch (tag) {
case 1: SaveSettingsDialogBox::promptToSaveSettings(); break;
case 2: GOTO_SCREEN(BioConfirmHomeXYZ); break;
case 3: SpinnerDialogBox::enqueueAndWait_P(e_homed ? F("G0 E0 F120") : F("G112")); break;
case 4: StatusScreen::unlockMotors(); break;
case 5: SpinnerDialogBox::enqueueAndWait_P(F(AXIS_LEVELING_COMMANDS)); break;
case 6: GOTO_SCREEN(TemperatureScreen); break;
case 7: GOTO_SCREEN(InterfaceSettingsScreen); break;
case 8: GOTO_SCREEN(AdvancedSettingsMenu); break;
case 9: GOTO_SCREEN(AboutScreen); break;
default:
return false;
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,59 @@
/****************************************************************************
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/**
* This file was auto-generated using "svg2cpp.py"
*
* The encoding consists of x,y pairs with the min and max scaled to
* 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the
* start of a new closed path.
*/
#pragma once
constexpr float x_min = 0.000000;
constexpr float x_max = 480.000000;
constexpr float y_min = 0.000000;
constexpr float y_max = 272.000000;
const PROGMEM uint16_t z_neg[] = {0x7950, 0x51EA, 0x824E, 0x51EA, 0x824E, 0x71E2, 0x86CD, 0x71E2, 0x7DCF, 0x81DF, 0x74D1, 0x71E2, 0x7950, 0x71E2, 0x7950, 0x51EA};
const PROGMEM uint16_t z_pos[] = {0x7950, 0x41EE, 0x824E, 0x41EE, 0x824E, 0x21F5, 0x86CD, 0x21F5, 0x7DCF, 0x11F9, 0x74D0, 0x21F5, 0x7950, 0x21F5, 0x7950, 0x41EE};
const PROGMEM uint16_t y_neg[] = {0x3479, 0x56CF, 0x3EC6, 0x56CF, 0x3747, 0x7281, 0x3C6D, 0x7281, 0x2E61, 0x8059, 0x27D4, 0x7281, 0x2CFA, 0x7281, 0x3479, 0x56CF};
const PROGMEM uint16_t y_pos[] = {0x3BF9, 0x3B1D, 0x4645, 0x3B1D, 0x4DC4, 0x1F6B, 0x52EB, 0x1F6B, 0x4C5E, 0x1192, 0x3E52, 0x1F6B, 0x4378, 0x1F6B, 0x3BF9, 0x3B1D};
const PROGMEM uint16_t x_neg[] = {0x350E, 0x4209, 0x314E, 0x4FE2, 0x1CB5, 0x4FE2, 0x1AD6, 0x56CF, 0x1449, 0x48F6, 0x2255, 0x3B1D, 0x2075, 0x4209, 0x350E, 0x4209};
const PROGMEM uint16_t x_pos[] = {0x498C, 0x4209, 0x45CC, 0x4FE2, 0x5A65, 0x4FE2, 0x5885, 0x56CF, 0x6691, 0x48F6, 0x6004, 0x3B1D, 0x5E25, 0x4209, 0x498C, 0x4209};
const PROGMEM uint16_t syringe_fluid[] = {0xB4E9, 0x78BE, 0xBB12, 0x7C44, 0xBDE3, 0x7C44, 0xC426, 0x78BE, 0xC426, 0x250D, 0xB4E9, 0x250D, 0xB4E9, 0x78BE};
const PROGMEM uint16_t syringe[] = {0xB8AD, 0x6BB1, 0xB8AD, 0x6E0C, 0xBE02, 0x6E0C, 0xBE02, 0x6BB1, 0xFFFF, 0xB8AD, 0x6248, 0xB8AD, 0x64A2, 0xBE02, 0x64A2, 0xBE02, 0x6248, 0xFFFF, 0xB8AD, 0x58DF, 0xB8AD, 0x5B39, 0xBE02, 0x5B39, 0xBE02, 0x58DF, 0xFFFF, 0xB8AD, 0x4F75, 0xB8AD, 0x51D0, 0xBE02, 0x51D0, 0xBE02, 0x4F75, 0xFFFF, 0xB8AD, 0x460C, 0xB8AD, 0x4866, 0xBE02, 0x4866, 0xBE02, 0x460C, 0xFFFF, 0xB8AD, 0x3CA3, 0xB8AD, 0x3EFD, 0xBE02, 0x3EFD, 0xBE02, 0x3CA3, 0xFFFF, 0xB8AD, 0x3339, 0xB8AD, 0x3594, 0xBE02, 0x3594, 0xBE02, 0x3339, 0xFFFF, 0xB396, 0x110A, 0xB396, 0x1818, 0xB995, 0x1818, 0xB995, 0x22AD, 0xB396, 0x22AD, 0xB396, 0x7ADA, 0xB995, 0x7E61, 0xB995, 0x88F5, 0xBB95, 0x88F5, 0xBB95, 0xA8B4, 0xBD94, 0xAC3B, 0xBD94, 0x88F5, 0xBF94, 0x88F5, 0xBF94, 0x7E61, 0xC593, 0x7ADA, 0xC593, 0x22AD, 0xBF94, 0x22AD, 0xBF94, 0x1818, 0xC593, 0x1818, 0xC593, 0x110A, 0xFFFF, 0xBB95, 0x1818, 0xBD94, 0x1818, 0xBD94, 0x22AD, 0xBB95, 0x22AD, 0xBB95, 0x1818, 0xFFFF, 0xB596, 0x2634, 0xC393, 0x2634, 0xC393, 0x7753, 0xBD94, 0x7ADA, 0xBB95, 0x7ADA, 0xB596, 0x7753, 0xB596, 0x2634};
const PROGMEM uint16_t syringe_outline[] = {0xB396, 0x110A, 0xB396, 0x1818, 0xB995, 0x1818, 0xB995, 0x22AD, 0xB396, 0x22AD, 0xB396, 0x7ADA, 0xB995, 0x7E61, 0xB995, 0x88F5, 0xBB95, 0x88F5, 0xBB95, 0xA8B4, 0xBD94, 0xAC3B, 0xBD94, 0x88F5, 0xBF94, 0x88F5, 0xBF94, 0x7E61, 0xC593, 0x7ADA, 0xC593, 0x22AD, 0xBF94, 0x22AD, 0xBF94, 0x1818, 0xC593, 0x1818, 0xC593, 0x110A, 0xB396, 0x110A};
const PROGMEM uint16_t padlock[] = {0x3FE3, 0x2A04, 0x3D34, 0x2AF9, 0x3AFF, 0x2D93, 0x397D, 0x316D, 0x38E8, 0x3626, 0x38E8, 0x3A14, 0x39B3, 0x3C8F, 0x3B50, 0x3C8F, 0x3C1C, 0x3A14, 0x3C1C, 0x363C, 0x3C6B, 0x33A9, 0x3D3A, 0x3193, 0x3E6C, 0x302D, 0x3FE3, 0x2FAA, 0x415A, 0x302D, 0x428C, 0x3192, 0x435B, 0x33A8, 0x43AB, 0x363C, 0x43AB, 0x4492, 0x38C3, 0x4492, 0x3741, 0x45AC, 0x36A1, 0x4856, 0x36A1, 0x5C41, 0x3741, 0x5EEC, 0x38C3, 0x6005, 0x4703, 0x6005, 0x4886, 0x5EEC, 0x4925, 0x5C41, 0x4925, 0x4856, 0x4886, 0x45AC, 0x4703, 0x4492, 0x46DE, 0x362B, 0x4649, 0x316D, 0x44C7, 0x2D92, 0x4292, 0x2AF9};
const PROGMEM uint16_t home_z[] = {0x80BB, 0x2B43, 0x712C, 0x46B9, 0x750F, 0x46B9, 0x750F, 0x622F, 0x7CD7, 0x622F, 0x7CD7, 0x5474, 0x849F, 0x5474, 0x849F, 0x622F, 0x8C67, 0x622F, 0x8C67, 0x46B9, 0x904B, 0x46B9, 0x8A48, 0x3C1D, 0x8A48, 0x2ECD, 0x8664, 0x2ECD, 0x8664, 0x3540};
const PROGMEM uint16_t usb_btn[] = {0x0558, 0xC0D6, 0x3BDB, 0xC0D6, 0x3BDB, 0xF431, 0x0558, 0xF431, 0x0558, 0xC0D6};
const PROGMEM uint16_t menu_btn[] = {0x416B, 0xC0D6, 0x77EE, 0xC0D6, 0x77EE, 0xF431, 0x416B, 0xF431, 0x416B, 0xC0D6};
const PROGMEM uint16_t e_pos[] = {0xE04E, 0x5E7B, 0xE94C, 0x5E7B, 0xE94C, 0x7E74, 0xEDCB, 0x7E74, 0xE4CD, 0x8E70, 0xDBCF, 0x7E74, 0xE04E, 0x7E74, 0xE04E, 0x5E7B};
const PROGMEM uint16_t e_neg[] = {0xE04E, 0x4E7F, 0xE94C, 0x4E7F, 0xE94C, 0x2E87, 0xEDCB, 0x2E87, 0xE4CD, 0x1E8A, 0xDBCF, 0x2E87, 0xE04E, 0x2E87, 0xE04E, 0x4E7F};
const PROGMEM uint16_t home_e[] = {0xD705, 0x3885, 0xC775, 0x53FB, 0xCB59, 0x53FB, 0xCB59, 0x6F71, 0xD321, 0x6F71, 0xD321, 0x61B6, 0xDAE9, 0x61B6, 0xDAE9, 0x6F71, 0xE2B1, 0x6F71, 0xE2B1, 0x53FB, 0xE695, 0x53FB, 0xE092, 0x495F, 0xE092, 0x3C0E, 0xDCAE, 0x3C0E, 0xDCAE, 0x4281};
const PROGMEM uint16_t fine_label[] = {0x0D92, 0x9444, 0x5211, 0x9444, 0x5211, 0xA9EA, 0x0D92, 0xA9EA};
const PROGMEM uint16_t fine_toggle[] = {0x56E7, 0x9444, 0x8007, 0x9444, 0x8007, 0xA9EA, 0x56E7, 0xA9EA};
const PROGMEM uint16_t h1_temp[] = {0x9C2B, 0xDD3B, 0xBBDE, 0xDD3B, 0xBBDE, 0xFA57, 0x9C2B, 0xFA57};
const PROGMEM uint16_t h1_label[] = {0x9C2B, 0xBE8F, 0xBBDC, 0xBE8F, 0xBBDC, 0xDBAA, 0x9C2B, 0xDBAA};
const PROGMEM uint16_t h0_temp[] = {0x7BD0, 0xDD3B, 0x9B83, 0xDD3B, 0x9B83, 0xFA57, 0x7BD0, 0xFA57};
const PROGMEM uint16_t h0_label[] = {0x7BD0, 0xBE8F, 0x9B83, 0xBE8F, 0x9B83, 0xDBAA, 0x7BD0, 0xDBAA};
const PROGMEM uint16_t h2_temp[] = {0xBC86, 0xDD3B, 0xDC39, 0xDD3B, 0xDC39, 0xFA57, 0xBC86, 0xFA57};
const PROGMEM uint16_t h2_label[] = {0xBC86, 0xBE8F, 0xDC37, 0xBE8F, 0xDC37, 0xDBAA, 0xBC86, 0xDBAA};
const PROGMEM uint16_t h3_temp[] = {0xDCE2, 0xDD0D, 0xFC95, 0xDD0D, 0xFC95, 0xFA28, 0xDCE2, 0xFA28};
const PROGMEM uint16_t h3_label[] = {0xDCE2, 0xBE60, 0xFC92, 0xBE60, 0xFC92, 0xDB7C, 0xDCE2, 0xDB7C};
const PROGMEM uint16_t actual_temp[] = {0xCDF6, 0xD037, 0xF7CA, 0xD037, 0xF7CA, 0xF424, 0xCDF6, 0xF424};
const PROGMEM uint16_t bed_icon[] = {0xCDF6, 0xA5CC, 0xF7CA, 0xA5CC, 0xF7CA, 0xC9B9, 0xCDF6, 0xC9B9};

View File

@ -0,0 +1,52 @@
/****************************************************************************
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
/**
* This file was auto-generated using "svg2cpp.py"
*
* The encoding consists of x,y pairs with the min and max scaled to
* 0x0000 and 0xFFFE. A single 0xFFFF in the data stream indicates the
* start of a new closed path.
*/
#pragma once
constexpr float x_min = 0.000000;
constexpr float x_max = 272.000000;
constexpr float y_min = 0.000000;
constexpr float y_max = 480.000000;
const PROGMEM uint16_t z_neg[] = {0xC9B1, 0x96B3, 0xD990, 0x96B3, 0xD990, 0xA8D0, 0xE17F, 0xA8D0, 0xD1A0, 0xB1DF, 0xC1C2, 0xA8D0, 0xC9B1, 0xA8D0, 0xC9B1, 0x96B3};
const PROGMEM uint16_t z_pos[] = {0xC9B1, 0x8DA4, 0xD990, 0x8DA4, 0xD990, 0x7B86, 0xE17F, 0x7B86, 0xD1A0, 0x7277, 0xC1C2, 0x7B86, 0xC9B1, 0x7B86, 0xC9B1, 0x8DA4};
const PROGMEM uint16_t y_neg[] = {0x5037, 0x9979, 0x6264, 0x9979, 0x5529, 0xA92A, 0x5E3F, 0xA92A, 0x4575, 0xB103, 0x39E6, 0xA92A, 0x42FC, 0xA92A, 0x5037, 0x9979};
const PROGMEM uint16_t y_pos[] = {0x5D72, 0x89C7, 0x6F9F, 0x89C7, 0x7CDA, 0x7A15, 0x85F0, 0x7A15, 0x7A61, 0x723D, 0x6197, 0x7A15, 0x6AAD, 0x7A15, 0x5D72, 0x89C7};
const PROGMEM uint16_t x_neg[] = {0x513D, 0x8DB3, 0x4AA0, 0x958C, 0x2647, 0x958C, 0x22F8, 0x9979, 0x1769, 0x91A0, 0x3033, 0x89C7, 0x2CE4, 0x8DB3, 0x513D, 0x8DB3};
const PROGMEM uint16_t x_pos[] = {0x7566, 0x8DB3, 0x6EC9, 0x958C, 0x9322, 0x958C, 0x8FD4, 0x9979, 0xA89E, 0x91A0, 0x9D0E, 0x89C7, 0x99C0, 0x8DB3, 0x7566, 0x8DB3};
const PROGMEM uint16_t syringe_fluid[] = {0x7D1D, 0x4A0F, 0x87FC, 0x4C0E, 0x8CF4, 0x4C0E, 0x9801, 0x4A0F, 0x9801, 0x1AA2, 0x7D1D, 0x1AA2, 0x7D1D, 0x4A0F};
const PROGMEM uint16_t syringe[] = {0x83C2, 0x42AA, 0x83C2, 0x43FF, 0x8D2C, 0x43FF, 0x8D2C, 0x42AA, 0xFFFF, 0x83C2, 0x3D54, 0x83C2, 0x3EAA, 0x8D2C, 0x3EAA, 0x8D2C, 0x3D54, 0xFFFF, 0x83C2, 0x37FF, 0x83C2, 0x3954, 0x8D2C, 0x3954, 0x8D2C, 0x37FF, 0xFFFF, 0x83C2, 0x32AA, 0x83C2, 0x33FF, 0x8D2C, 0x33FF, 0x8D2C, 0x32AA, 0xFFFF, 0x83C2, 0x2D54, 0x83C2, 0x2EAA, 0x8D2C, 0x2EAA, 0x8D2C, 0x2D54, 0xFFFF, 0x83C2, 0x27FF, 0x83C2, 0x2955, 0x8D2C, 0x2955, 0x8D2C, 0x27FF, 0xFFFF, 0x83C2, 0x22AA, 0x83C2, 0x23FF, 0x8D2C, 0x23FF, 0x8D2C, 0x22AA, 0xFFFF, 0x7AC7, 0x0F4B, 0x7AC7, 0x134A, 0x855B, 0x134A, 0x855B, 0x1949, 0x7AC7, 0x1949, 0x7AC7, 0x4B40, 0x855B, 0x4D40, 0x855B, 0x533F, 0x88E2, 0x533F, 0x88E2, 0x653C, 0x8C69, 0x673C, 0x8C69, 0x533F, 0x8FF0, 0x533F, 0x8FF0, 0x4D40, 0x9A85, 0x4B40, 0x9A85, 0x1949, 0x8FF0, 0x1949, 0x8FF0, 0x134A, 0x9A85, 0x134A, 0x9A85, 0x0F4B, 0xFFFF, 0x88E2, 0x134A, 0x8C69, 0x134A, 0x8C69, 0x1949, 0x88E2, 0x1949, 0x88E2, 0x134A, 0xFFFF, 0x7E4D, 0x1B49, 0x96FE, 0x1B49, 0x96FE, 0x4941, 0x8C69, 0x4B40, 0x88E2, 0x4B40, 0x7E4D, 0x4941, 0x7E4D, 0x1B49};
const PROGMEM uint16_t syringe_outline[] = {0x7AC7, 0x0F4B, 0x7AC7, 0x134A, 0x855B, 0x134A, 0x855B, 0x1949, 0x7AC7, 0x1949, 0x7AC7, 0x4B40, 0x855B, 0x4D40, 0x855B, 0x533F, 0x88E2, 0x533F, 0x88E2, 0x653C, 0x8C69, 0x673C, 0x8C69, 0x533F, 0x8FF0, 0x533F, 0x8FF0, 0x4D40, 0x9A85, 0x4B40, 0x9A85, 0x1949, 0x8FF0, 0x1949, 0x8FF0, 0x134A, 0x9A85, 0x134A, 0x9A85, 0x0F4B, 0x7AC7, 0x0F4B};
const PROGMEM uint16_t padlock[] = {0x645A, 0x8017, 0x5F9E, 0x80A1, 0x5BBA, 0x821B, 0x5911, 0x844A, 0x580A, 0x86F7, 0x580A, 0x8931, 0x5970, 0x8A98, 0x5C49, 0x8A98, 0x5DB0, 0x8931, 0x5DB0, 0x8703, 0x5E3C, 0x858E, 0x5FAA, 0x845F, 0x61C5, 0x8394, 0x645A, 0x834A, 0x66F0, 0x8394, 0x690C, 0x845F, 0x6A7A, 0x858D, 0x6B07, 0x8703, 0x6B07, 0x8F23, 0x57C8, 0x8F23, 0x551E, 0x8FC3, 0x5404, 0x9145, 0x5404, 0x9C8F, 0x551E, 0x9E11, 0x57C8, 0x9EB1, 0x70EE, 0x9EB1, 0x7398, 0x9E11, 0x74B2, 0x9C8F, 0x74B2, 0x9145, 0x7398, 0x8FC3, 0x70EE, 0x8F23, 0x70AC, 0x86FA, 0x6FA5, 0x844A, 0x6CFD, 0x821B, 0x6917, 0x80A1};
const PROGMEM uint16_t home_z[] = {0xD6C9, 0x80CC, 0xBB53, 0x905B, 0xC231, 0x905B, 0xC231, 0x9FEB, 0xCFEC, 0x9FEB, 0xCFEC, 0x9823, 0xDDA7, 0x9823, 0xDDA7, 0x9FEB, 0xEB62, 0x9FEB, 0xEB62, 0x905B, 0xF240, 0x905B, 0xE7A3, 0x8A58, 0xE7A3, 0x82CD, 0xE0C6, 0x82CD, 0xE0C6, 0x8674};
const PROGMEM uint16_t home_e[] = {0xB94F, 0x25AA, 0x9DD8, 0x353A, 0xA4B6, 0x353A, 0xA4B6, 0x44C9, 0xB271, 0x44C9, 0xB271, 0x3D02, 0xC02C, 0x3D02, 0xC02C, 0x44C9, 0xCDE7, 0x44C9, 0xCDE7, 0x353A, 0xD4C5, 0x353A, 0xCA28, 0x2F36, 0xCA28, 0x27AB, 0xC34B, 0x27AB, 0xC34B, 0x2B53};
const PROGMEM uint16_t bed_icon[] = {0x1764, 0x2C4C, 0x6135, 0x2C4C, 0x6135, 0x40A8, 0x1764, 0x40A8};
const PROGMEM uint16_t actual_temp[] = {0x1764, 0x466F, 0x6135, 0x466F, 0x6135, 0x5ACB, 0x1764, 0x5ACB};
const PROGMEM uint16_t target_temp[] = {0x1764, 0x1228, 0x6135, 0x1228, 0x6135, 0x2684, 0x1764, 0x2684};
const PROGMEM uint16_t fine_label[] = {0x1AA7, 0xC6D2, 0x9387, 0xC6D2, 0x9387, 0xD316, 0x1AA7, 0xD316};
const PROGMEM uint16_t fine_toggle[] = {0x9C10, 0xC6D2, 0xE4A3, 0xC6D2, 0xE4A3, 0xD316, 0x9C10, 0xD316};
const PROGMEM uint16_t usb_btn[] = {0x0B68, 0xE880, 0x7B1A, 0xE880, 0x7B1A, 0xF94B, 0x0B68, 0xF94B, 0x0B68, 0xE880};
const PROGMEM uint16_t menu_btn[] = {0x84E3, 0xE880, 0xF495, 0xE880, 0xF495, 0xF94B, 0x84E3, 0xF94B, 0x84E3, 0xE880};
const PROGMEM uint16_t e_pos[] = {0xC9B1, 0x3B2D, 0xD990, 0x3B2D, 0xD990, 0x4D4B, 0xE17F, 0x4D4B, 0xD1A0, 0x565A, 0xC1C2, 0x4D4B, 0xC9B1, 0x4D4B, 0xC9B1, 0x3B2D};
const PROGMEM uint16_t e_neg[] = {0xC9B1, 0x321E, 0xD990, 0x321E, 0xD990, 0x2000, 0xE17F, 0x2000, 0xD1A0, 0x16F1, 0xC1C2, 0x2000, 0xC9B1, 0x2000, 0xC9B1, 0x321E};

View File

@ -0,0 +1,157 @@
/*******************************
* bio_printing_dialog_box.cpp *
*******************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
#include "../ftdi_eve_lib/extras/circular_progress.h"
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
#define GRID_COLS 2
#define GRID_ROWS 9
void BioPrintingDialogBox::draw_status_message(draw_mode_t what, const char* message) {
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(COLOR_RGB(bg_text_enabled))
.tag(0);
draw_text_box(cmd, BTN_POS(1,2), BTN_SIZE(2,2), message, OPT_CENTER, font_large);
}
}
void BioPrintingDialogBox::draw_progress(draw_mode_t what) {
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.font(font_large)
.text(BTN_POS(1,1), BTN_SIZE(2,2), isPrinting() ? F("Printing...") : F("Finished."))
.tag(1)
.font(font_xlarge);
draw_circular_progress(cmd, BTN_POS(1,4), BTN_SIZE(2,3), getProgress_percent(), theme_dark, theme_darkest);
}
}
void BioPrintingDialogBox::draw_time_remaining(draw_mode_t what) {
if (what & FOREGROUND) {
const uint32_t elapsed = getProgress_seconds_elapsed();
const uint8_t hrs = elapsed/3600;
const uint8_t min = (elapsed/60)%60;
char time_str[10];
sprintf_P(time_str, PSTR("%02dh %02dm"), hrs, min);
CommandProcessor cmd;
cmd.font(font_large)
.text(BTN_POS(1,7), BTN_SIZE(2,2), time_str);
}
}
void BioPrintingDialogBox::draw_interaction_buttons(draw_mode_t what) {
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(font_medium)
.colors(isPrinting() ? action_btn : normal_btn)
.tag(2).button(BTN_POS(1,9), BTN_SIZE(1,1), F("Menu"))
#if ENABLED(SDSUPPORT)
.enabled(isPrinting() ? isPrintingFromMedia() : 1)
#else
.enabled(isPrinting() ? 0 : 1)
#endif
.tag(3)
.colors(isPrinting() ? normal_btn : action_btn)
.button( BTN_POS(2,9), BTN_SIZE(1,1), isPrinting() ? F("Cancel") : F("Back"));
}
}
void BioPrintingDialogBox::onRedraw(draw_mode_t what) {
if (what & FOREGROUND) {
draw_progress(FOREGROUND);
draw_time_remaining(FOREGROUND);
draw_interaction_buttons(FOREGROUND);
}
}
bool BioPrintingDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_SCREEN(FeedratePercentScreen); break;
case 2: GOTO_SCREEN(TuneMenu); break;
case 3:
if (isPrinting()) {
GOTO_SCREEN(ConfirmAbortPrintDialogBox);
} else {
GOTO_SCREEN(StatusScreen);
}
break;
default: return false;
}
return true;
}
void BioPrintingDialogBox::setStatusMessage(progmem_str message) {
char buff[strlen_P((const char*)message)+1];
strcpy_P(buff, (const char*) message);
setStatusMessage(buff);
}
void BioPrintingDialogBox::setStatusMessage(const char* message) {
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART)
.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true));
draw_status_message(BACKGROUND, message);
draw_progress(BACKGROUND);
draw_time_remaining(BACKGROUND);
draw_interaction_buttons(BACKGROUND);
storeBackground();
#if ENABLED(TOUCH_UI_DEBUG)
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("New status message: ", message);
#endif
if (AT_SCREEN(BioPrintingDialogBox)) {
current_screen.onRefresh();
}
}
void BioPrintingDialogBox::onIdle() {
reset_menu_timeout();
if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
onRefresh();
refresh_timer.start();
}
BaseScreen::onIdle();
}
void BioPrintingDialogBox::show() {
GOTO_SCREEN(BioPrintingDialogBox);
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,467 @@
/*************************
* bio_status_screen.cpp *
*************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Cocoa Press *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && ANY(TOUCH_UI_LULZBOT_BIO, TOUCH_UI_COCOA_PRESS)
#include "screens.h"
#include "../ftdi_eve_lib/extras/poly_ui.h"
#ifdef TOUCH_UI_PORTRAIT
#include "bio_printer_ui_portrait.h"
#else
#include "bio_printer_ui_landscape.h"
#endif
#define GRID_COLS 2
#define GRID_ROWS 9
#define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0]))
const uint8_t shadow_depth = 5;
const float max_speed = 1.00;
const float min_speed = 0.02;
const float emax_speed = 2.00;
const float emin_speed = 0.70;
using namespace FTDI;
using namespace Theme;
using namespace ExtUI;
float StatusScreen::increment;
bool StatusScreen::jog_xy;
bool StatusScreen::fine_motion;
void StatusScreen::unlockMotors() {
injectCommands_P(PSTR("M84 XY"));
jog_xy = false;
}
void StatusScreen::draw_temperature(draw_mode_t what) {
CommandProcessor cmd;
PolyUI ui(cmd, what);
int16_t x, y, h, v;
cmd.tag(15);
if (what & BACKGROUND) {
cmd.cmd(COLOR_RGB(bg_color));
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
// The LulzBot Bio shows the temperature for
// the bed.
#ifdef TOUCH_UI_PORTRAIT
// Draw touch surfaces
ui.bounds(POLY(target_temp), x, y, h, v);
cmd.rectangle(x, y, h, v);
ui.bounds(POLY(actual_temp), x, y, h, v);
cmd.rectangle(x, y, h, v);
#else
ui.bounds(POLY(bed_temp), x, y, h, v);
cmd.rectangle(x, y, h, v);
#endif
ui.bounds(POLY(bed_icon), x, y, h, v);
cmd.rectangle(x, y, h, v);
// Draw bed icon
cmd.cmd(BITMAP_SOURCE(Bed_Heat_Icon_Info))
.cmd(BITMAP_LAYOUT(Bed_Heat_Icon_Info))
.cmd(BITMAP_SIZE (Bed_Heat_Icon_Info))
.cmd(COLOR_RGB(shadow_rgb))
.icon (x + 2, y + 2, h, v, Bed_Heat_Icon_Info, icon_scale * 2)
.cmd(COLOR_RGB(bg_text_enabled))
.icon (x, y, h, v, Bed_Heat_Icon_Info, icon_scale * 2);
#elif ENABLED(TOUCH_UI_COCOA_PRESS) && DISABLED(TOUCH_UI_PORTRAIT)
// The CocoaPress shows the temperature for two
// heating zones, but has no bed temperature
cmd.cmd(COLOR_RGB(bg_text_enabled));
cmd.font(font_medium);
ui.bounds(POLY(h0_label), x, y, h, v);
cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_1));
ui.bounds(POLY(h1_label), x, y, h, v);
cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_2));
ui.bounds(POLY(h2_label), x, y, h, v);
cmd.text(x, y, h, v, GET_TEXT_F(MSG_ZONE_3));
ui.bounds(POLY(h3_label), x, y, h, v);
cmd.text(x, y, h, v, GET_TEXT_F(MSG_CHAMBER));
#else
UNUSED(x);
UNUSED(y);
UNUSED(h);
UNUSED(v);
#endif
#ifdef TOUCH_UI_USE_UTF8
load_utf8_bitmaps(cmd); // Restore font bitmap handles
#endif
}
if (what & FOREGROUND) {
char str[15];
cmd.cmd(COLOR_RGB(bg_text_enabled));
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
cmd.font(font_medium);
#ifdef TOUCH_UI_PORTRAIT
if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0)
format_temp(str, getTargetTemp_celsius(BED));
else
strcpy_P(str, GET_TEXT(MSG_BED));
ui.bounds(POLY(target_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
format_temp(str, getActualTemp_celsius(BED));
ui.bounds(POLY(actual_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
#else
if (!isHeaterIdle(BED) && getTargetTemp_celsius(BED) > 0)
format_temp_and_temp(str, getActualTemp_celsius(BED), getTargetTemp_celsius(BED));
else
format_temp_and_idle(str, getActualTemp_celsius(BED));
ui.bounds(POLY(bed_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
#endif
#elif ENABLED(TOUCH_UI_COCOA_PRESS) && DISABLED(TOUCH_UI_PORTRAIT)
// The CocoaPress shows the temperature for two
// heating zones, but has no bed temperature
cmd.font(font_large);
if (!isHeaterIdle(E0) && getTargetTemp_celsius(E0) > 0)
format_temp_and_temp(str, getActualTemp_celsius(E0), getTargetTemp_celsius(E0));
else
format_temp_and_idle(str, getActualTemp_celsius(E0));
ui.bounds(POLY(h0_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
if (!isHeaterIdle(E1) && getTargetTemp_celsius(E1) > 0)
format_temp_and_temp(str, getActualTemp_celsius(E1), getTargetTemp_celsius(E1));
else
format_temp_and_idle(str, getActualTemp_celsius(E1));
ui.bounds(POLY(h1_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
if (!isHeaterIdle(E2) && getTargetTemp_celsius(E2) > 0)
format_temp_and_temp(str, getActualTemp_celsius(E2), getTargetTemp_celsius(E2));
else
format_temp_and_idle(str, getActualTemp_celsius(E2));
ui.bounds(POLY(h2_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
if (!isHeaterIdle(CHAMBER) && getTargetTemp_celsius(CHAMBER) > 0)
format_temp_and_temp(str, getActualTemp_celsius(CHAMBER), getTargetTemp_celsius(CHAMBER));
else
format_temp_and_idle(str, getActualTemp_celsius(CHAMBER));
ui.bounds(POLY(h3_temp), x, y, h, v);
cmd.text(x, y, h, v, str);
#else
UNUSED(str);
#endif
}
}
void StatusScreen::draw_syringe(draw_mode_t what) {
int16_t x, y, h, v;
#ifdef E_MAX_POS
const float fill_level = 1.0 - min(1.0, max(0.0, getAxisPosition_mm(E0) / E_MAX_POS));
#else
const float fill_level = 0.75;
#endif
const bool e_homed = (true
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
&& isAxisPositionKnown(E0)
#endif
);
CommandProcessor cmd;
PolyUI ui(cmd, what);
if (what & BACKGROUND) {
// Paint the shadow for the syringe
ui.color(shadow_rgb);
ui.shadow(POLY(syringe_outline), shadow_depth);
}
if (what & FOREGROUND && e_homed) {
// Paint the syringe icon
ui.color(syringe_rgb);
ui.fill(POLY(syringe_outline));
ui.color(fill_rgb);
ui.bounds(POLY(syringe_fluid), x, y, h, v);
cmd.cmd(SAVE_CONTEXT());
cmd.cmd(SCISSOR_XY(x,y + v * (1.0 - fill_level)));
cmd.cmd(SCISSOR_SIZE(h, v * fill_level));
ui.fill(POLY(syringe_fluid), false);
cmd.cmd(RESTORE_CONTEXT());
ui.color(stroke_rgb);
ui.fill(POLY(syringe));
}
}
void StatusScreen::draw_arrows(draw_mode_t what) {
const bool e_homed = (true
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
&& isAxisPositionKnown(E0)
#endif
);
const bool z_homed = isAxisPositionKnown(Z);
CommandProcessor cmd;
PolyUI ui(cmd, what);
ui.button_fill (fill_rgb);
ui.button_stroke(stroke_rgb, 28);
ui.button_shadow(shadow_rgb, shadow_depth);
if ((what & BACKGROUND) || jog_xy) {
ui.button(1, POLY(x_neg));
ui.button(2, POLY(x_pos));
ui.button(3, POLY(y_neg));
ui.button(4, POLY(y_pos));
}
if ((what & BACKGROUND) || z_homed) {
ui.button(5, POLY(z_neg));
ui.button(6, POLY(z_pos));
}
if ((what & BACKGROUND) || e_homed) {
#if DISABLED(TOUCH_UI_COCOA_PRESS)
ui.button(7, POLY(e_neg));
#endif
ui.button(8, POLY(e_pos));
}
}
void StatusScreen::draw_fine_motion(draw_mode_t what) {
int16_t x, y, h, v;
CommandProcessor cmd;
PolyUI ui(cmd, what);
cmd.font(
#ifdef TOUCH_UI_PORTRAIT
font_medium
#else
font_small
#endif
)
.tag(16);
if (what & BACKGROUND) {
ui.bounds(POLY(fine_label), x, y, h, v);
cmd.cmd(COLOR_RGB(bg_text_enabled))
.text(x, y, h, v, GET_TEXT_F(MSG_FINE_MOTION));
}
if (what & FOREGROUND) {
ui.bounds(POLY(fine_toggle), x, y, h, v);
cmd.colors(ui_toggle)
.toggle2(x, y, h, v, GET_TEXT_F(MSG_NO), GET_TEXT_F(MSG_YES), fine_motion);
}
}
void StatusScreen::draw_overlay_icons(draw_mode_t what) {
const bool e_homed = (true
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
&& isAxisPositionKnown(E0)
#endif
);
const bool z_homed = isAxisPositionKnown(Z);
CommandProcessor cmd;
PolyUI ui(cmd, what);
if (what & FOREGROUND) {
ui.button_fill (fill_rgb);
ui.button_stroke(stroke_rgb, 28);
ui.button_shadow(shadow_rgb, shadow_depth);
if (!jog_xy) ui.button(12, POLY(padlock));
if (!e_homed) ui.button(13, POLY(home_e));
if (!z_homed) ui.button(14, POLY(home_z));
}
}
void StatusScreen::draw_buttons(draw_mode_t what) {
int16_t x, y, h, v;
const bool has_media = isMediaInserted() && !isPrintingFromMedia();
CommandProcessor cmd;
PolyUI ui(cmd, what);
ui.bounds(POLY(usb_btn), x, y, h, v);
cmd.font(font_medium)
.colors(normal_btn)
.enabled(has_media)
.colors(has_media ? action_btn : normal_btn)
.tag(9).button(x, y, h, v,
isPrintingFromMedia() ?
GET_TEXT_F(MSG_PRINTING) :
GET_TEXT_F(MSG_BUTTON_MEDIA)
);
ui.bounds(POLY(menu_btn), x, y, h, v);
cmd.colors(!has_media ? action_btn : normal_btn).tag(10).button(x, y, h, v, GET_TEXT_F(MSG_BUTTON_MENU));
}
void StatusScreen::loadBitmaps() {
// Load the bitmaps for the status screen
constexpr uint32_t base = ftdi_memory_map::RAM_G;
CLCD::mem_write_pgm(base + Bed_Heat_Icon_Info.RAMG_offset, Bed_Heat_Icon, sizeof(Bed_Heat_Icon));
// Load fonts for internationalization
#ifdef TOUCH_UI_USE_UTF8
load_utf8_data(base + UTF8_FONT_OFFSET);
#endif
}
void StatusScreen::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.tag(0);
}
draw_syringe(what);
draw_temperature(what);
draw_arrows(what);
draw_overlay_icons(what);
draw_buttons(what);
draw_fine_motion(what);
}
bool StatusScreen::onTouchStart(uint8_t) {
increment = 0;
return true;
}
bool StatusScreen::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
case 2:
case 3:
case 4:
case 12:
if (!jog_xy) {
jog_xy = true;
injectCommands_P(PSTR("M17"));
}
jog({ 0, 0, 0 });
break;
case 5:
case 6:
jog({ 0, 0, 0 });
break;
case 9: GOTO_SCREEN(FilesScreen); break;
case 10: GOTO_SCREEN(MainMenu); break;
#if ENABLED(TOUCH_UI_LULZBOT_BIO)
case 13: GOTO_SCREEN(BioConfirmHomeE); break;
#endif
case 14: SpinnerDialogBox::enqueueAndWait_P(F("G28 Z")); break;
case 15: GOTO_SCREEN(TemperatureScreen); break;
case 16: fine_motion = !fine_motion; break;
default: return false;
}
// If a passcode is enabled, the LockScreen will prevent the
// user from proceeding.
LockScreen::check_passcode();
return true;
}
bool StatusScreen::onTouchHeld(uint8_t tag) {
if (tag >= 1 && tag <= 4 && !jog_xy) return false;
const float s = min_speed + (fine_motion ? 0 : (max_speed - min_speed) * sq(increment));
switch (tag) {
case 1: jog({-s, 0, 0}); break;
case 2: jog({ s, 0, 0}); break;
case 4: jog({ 0, -s, 0}); break; // NOTE: Y directions inverted because bed rather than needle moves
case 3: jog({ 0, s, 0}); break;
case 5: jog({ 0, 0, -s}); break;
case 6: jog({ 0, 0, s}); break;
case 7: case 8:
{
if (ExtUI::isMoving()) return false;
const feedRate_t feedrate = emin_speed + (fine_motion ? 0 : (emax_speed - emin_speed) * sq(increment));
const float increment = 0.25 * feedrate * (tag == 7 ? -1 : 1);
MoveAxisScreen::setManualFeedrate(E0, feedrate);
UI_INCREMENT(AxisPosition_mm, E0);
current_screen.onRefresh();
break;
}
default:
return false;
}
increment = min(1.0f, increment + 0.1f);
return false;
}
void StatusScreen::setStatusMessage(progmem_str pstr) {
#ifdef TOUCH_UI_LULZBOT_BIO
BioPrintingDialogBox::setStatusMessage(pstr);
#else
UNUSED(pstr);
#endif
}
void StatusScreen::setStatusMessage(const char * const str) {
#ifdef TOUCH_UI_LULZBOT_BIO
BioPrintingDialogBox::setStatusMessage(str);
#else
UNUSED(str);
#endif
}
void StatusScreen::onIdle() {
reset_menu_timeout();
if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
if (!EventLoop::is_touch_held())
onRefresh();
#ifdef TOUCH_UI_LULZBOT_BIO
if (isPrintingFromMedia())
BioPrintingDialogBox::show();
#endif
refresh_timer.start();
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,83 @@
/*********************
* bio_tune_menu.cpp *
*********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE) && defined(TOUCH_UI_LULZBOT_BIO)
#include "screens.h"
using namespace FTDI;
using namespace Theme;
using namespace ExtUI;
void TuneMenu::onRedraw(draw_mode_t what) {
#define GRID_ROWS 8
#define GRID_COLS 2
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.cmd(COLOR_RGB(bg_text_enabled))
.tag(0)
.font(font_large)
.text( BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_PRINT_MENU));
}
if (what & FOREGROUND) {
CommandProcessor cmd;
cmd.colors(normal_btn)
.font(font_medium)
.enabled( isPrinting()).tag(2).button( BTN_POS(1,2), BTN_SIZE(2,1), GET_TEXT_F(MSG_PRINT_SPEED))
.tag(3).button( BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_BED_TEMPERATURE))
.enabled(
#if ENABLED(BABYSTEPPING)
true
#endif
)
.tag(4).button( BTN_POS(1,4), BTN_SIZE(2,1), GET_TEXT_F(MSG_NUDGE_NOZZLE))
.enabled(!isPrinting()).tag(5).button( BTN_POS(1,5), BTN_SIZE(2,1), GET_TEXT_F(MSG_MOVE_TO_HOME))
.enabled(!isPrinting()).tag(6).button( BTN_POS(1,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_RAISE_PLUNGER))
.enabled(!isPrinting()).tag(7).button( BTN_POS(1,7), BTN_SIZE(2,1), GET_TEXT_F(MSG_RELEASE_XY_AXIS))
.colors(action_btn) .tag(1).button( BTN_POS(1,8), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
}
#undef GRID_COLS
#undef GRID_ROWS
}
bool TuneMenu::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1: GOTO_PREVIOUS(); break;
case 2: GOTO_SCREEN(FeedratePercentScreen); break;
case 3: GOTO_SCREEN(TemperatureScreen); break;
case 4: GOTO_SCREEN(NudgeNozzleScreen); break;
case 5: GOTO_SCREEN(BioConfirmHomeXYZ); break;
case 6: SpinnerDialogBox::enqueueAndWait_P(F("G0 E0 F120")); break;
case 7: StatusScreen::unlockMotors(); break;
default:
return false;
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,127 @@
/*******************
* boot_screen.cpp *
*******************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2019 - Cocoa Press *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "../ftdi_eve_lib/extras/poly_ui.h"
#include "../archim2-flash/flash_storage.h"
#ifdef SHOW_CUSTOM_BOOTSCREEN
#ifdef TOUCH_UI_PORTRAIT
#include "../theme/_bootscreen_portrait.h"
#else
#include "../theme/_bootscreen_landscape.h"
#endif
#else
#ifdef TOUCH_UI_PORTRAIT
#include "../theme/marlin_bootscreen_portrait.h"
#else
#include "../theme/marlin_bootscreen_landscape.h"
#endif
#endif
using namespace FTDI;
using namespace Theme;
void BootScreen::onRedraw(draw_mode_t) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(0x000000));
cmd.cmd(CLEAR(true,true,true));
CLCD::turn_on_backlight();
SoundPlayer::set_volume(255);
}
void BootScreen::onIdle() {
if (CLCD::is_touching()) {
// If the user is touching the screen at startup, then
// assume the user wants to re-calibrate the screen.
// This gives the user the ability to recover a
// miscalibration that has been stored to EEPROM.
// Also reset display parameters to defaults, just
// in case the display is borked.
InterfaceSettingsScreen::failSafeSettings();
StatusScreen::loadBitmaps();
GOTO_SCREEN(TouchCalibrationScreen);
current_screen.forget();
PUSH_SCREEN(StatusScreen);
StatusScreen::setStatusMessage(GET_TEXT_F(WELCOME_MSG));
} else {
if (!UIFlashStorage::is_valid()) {
StatusScreen::loadBitmaps();
SpinnerDialogBox::show(GET_TEXT_F(MSG_PLEASE_WAIT));
UIFlashStorage::format_flash();
SpinnerDialogBox::hide();
}
if (UIData::animations_enabled()) {
// If there is a startup video in the flash SPI, play
// that, otherwise show a static splash screen.
if (!MediaPlayerScreen::playBootMedia())
showSplashScreen();
}
StatusScreen::loadBitmaps();
#ifdef TOUCH_UI_LULZBOT_BIO
GOTO_SCREEN(BioConfirmHomeXYZ);
current_screen.forget();
PUSH_SCREEN(StatusScreen);
PUSH_SCREEN(BioConfirmHomeE);
#elif NUM_LANGUAGES > 1
StatusScreen::setStatusMessage(GET_TEXT_F(WELCOME_MSG));
GOTO_SCREEN(LanguageMenu);
#else
StatusScreen::setStatusMessage(GET_TEXT_F(WELCOME_MSG));
GOTO_SCREEN(StatusScreen);
#endif
}
}
void BootScreen::showSplashScreen() {
CommandProcessor cmd;
cmd.cmd(CMD_DLSTART);
cmd.cmd(CLEAR_COLOR_RGB(LOGO_BACKGROUND));
cmd.cmd(CLEAR(true,true,true));
#define POLY(A) PolyUI::poly_reader_t(A, sizeof(A)/sizeof(A[0]))
#define LOGO_PAINT_PATH(rgb, path) cmd.cmd(COLOR_RGB(rgb)); ui.fill(POLY(path));
PolyUI ui(cmd);
LOGO_PAINT_PATHS
cmd.cmd(DL::DL_DISPLAY);
cmd.cmd(CMD_SWAP);
cmd.execute();
ExtUI::delay_ms(2500);
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,62 @@
/*************************
* case_light_screen.cpp *
*************************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Cocoa Press *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if BOTH(TOUCH_UI_FTDI_EVE, CASE_LIGHT_ENABLE)
#include "screens.h"
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
void CaseLightScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
w.heading( GET_TEXT_F(MSG_CASE_LIGHT));
w.toggle( 2, GET_TEXT_F(MSG_LEDS), getCaseLightState());
#if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
w.precision(0).units(GET_TEXT_F(MSG_UNITS_PERCENT))
.adjuster(10, GET_TEXT_F(MSG_CASE_LIGHT_BRIGHTNESS), getCaseLightBrightness_percent());
w.precision(0).increments();
#endif
}
bool CaseLightScreen::onTouchHeld(uint8_t tag) {
using namespace ExtUI;
#if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
const float increment = getIncrement();
#endif
switch (tag) {
case 2: setCaseLightState(!getCaseLightState()); break;
#if DISABLED(CASE_LIGHT_NO_BRIGHTNESS)
case 10: UI_DECREMENT(CaseLightBrightness_percent); break;
case 11: UI_INCREMENT(CaseLightBrightness_percent); break;
#endif
default:
return false;
}
SaveSettingsDialogBox::settingsChanged();
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,353 @@
/******************************
* change_filament_screen.cpp *
******************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "screen_data.h"
using namespace ExtUI;
using namespace FTDI;
using namespace Theme;
#define COOL_TEMP 40
#define LOW_TEMP 180
#define MED_TEMP 200
#define HIGH_TEMP 220
/****************** COLOR SCALE ***********************/
uint32_t getWarmColor(uint16_t temp, uint16_t cool, uint16_t low, uint16_t med, uint16_t high) {
rgb_t R0, R1, mix;
float t;
if (temp < cool) {
R0 = cool_rgb;
R1 = low_rgb;
t = 0;
}
else if (temp < low) {
R0 = cool_rgb;
R1 = low_rgb;
t = (float(temp)-cool)/(low-cool);
}
else if (temp < med) {
R0 = low_rgb;
R1 = med_rgb;
t = (float(temp)-low)/(med-low);
}
else if (temp < high) {
R0 = med_rgb;
R1 = high_rgb;
t = (float(temp)-med)/(high-med);
}
else if (temp >= high) {
R0 = med_rgb;
R1 = high_rgb;
t = 1;
}
rgb_t::lerp(t, R0, R1, mix);
return mix;
}
void ChangeFilamentScreen::drawTempGradient(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
CommandProcessor cmd;
cmd.cmd(SCISSOR_XY (x, y))
.cmd(SCISSOR_SIZE (w, h/2))
.gradient (x, y, high_rgb, x, y+h/2, med_rgb)
.cmd(SCISSOR_XY (x, y+h/2))
.cmd(SCISSOR_SIZE (w, h/2))
.gradient (x, y+h/2, med_rgb, x, y+h, low_rgb)
.cmd(SCISSOR_XY ())
.cmd(SCISSOR_SIZE ());
}
void ChangeFilamentScreen::onEntry() {
screen_data.ChangeFilamentScreen.e_tag = ExtUI::getActiveTool() + 10;
screen_data.ChangeFilamentScreen.t_tag = 0;
screen_data.ChangeFilamentScreen.repeat_tag = 0;
screen_data.ChangeFilamentScreen.saved_extruder = getActiveTool();
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
screen_data.ChangeFilamentScreen.need_purge = true;
#endif
}
void ChangeFilamentScreen::onExit() {
setActiveTool(screen_data.ChangeFilamentScreen.saved_extruder, true);
}
void ChangeFilamentScreen::onRedraw(draw_mode_t what) {
CommandProcessor cmd;
#ifdef TOUCH_UI_PORTRAIT
#define GRID_COLS 2
#define GRID_ROWS 11
#else
#define GRID_COLS 4
#define GRID_ROWS 6
#endif
if (what & BACKGROUND) {
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.tag(0)
#ifdef TOUCH_UI_PORTRAIT
.font(font_large)
#else
.font(font_medium)
#endif
.text(BTN_POS(1,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_EXTRUDER_SELECTION))
#ifdef TOUCH_UI_PORTRAIT
.text(BTN_POS(1,7), BTN_SIZE(1,1), F(""))
#else
.text(BTN_POS(3,1), BTN_SIZE(2,1), GET_TEXT_F(MSG_CURRENT_TEMPERATURE))
.font(font_small)
#endif
.text(BTN_POS(1,3), BTN_SIZE(2,1), GET_TEXT_F(MSG_REMOVAL_TEMPERATURE));
drawTempGradient(BTN_POS(1,4), BTN_SIZE(1,3));
}
if (what & FOREGROUND) {
const extruder_t e = getExtruder();
char e_str[15];
if (isHeaterIdle(e))
format_temp_and_idle(e_str, getActualTemp_celsius(e));
else
format_temp_and_temp(e_str, getActualTemp_celsius(e), getTargetTemp_celsius(e));
const rgb_t tcol = getWarmColor(getActualTemp_celsius(e), COOL_TEMP, LOW_TEMP, MED_TEMP, HIGH_TEMP);
cmd.cmd(COLOR_RGB(tcol))
.tag(15)
#ifdef TOUCH_UI_PORTRAIT
.rectangle(BTN_POS(2,7), BTN_SIZE(1,1))
#else
.rectangle(BTN_POS(3,2), BTN_SIZE(2,1))
#endif
.cmd(COLOR_RGB(tcol.luminance() > 128 ? 0x000000 : 0xFFFFFF))
.font(font_medium)
#ifdef TOUCH_UI_PORTRAIT
.text(BTN_POS(2,7), BTN_SIZE(1,1), e_str)
#else
.text(BTN_POS(3,2), BTN_SIZE(2,1), e_str)
#endif
.colors(normal_btn);
const bool t_ok = getActualTemp_celsius(e) > getSoftenTemp() - 10;
if (screen_data.ChangeFilamentScreen.t_tag && !t_ok) {
cmd.text(BTN_POS(1,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_HEATING));
} else if (getActualTemp_celsius(e) > 100) {
cmd.cmd(COLOR_RGB(0xFF0000))
.text(BTN_POS(1,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_CAUTION))
.colors(normal_btn)
.text(BTN_POS(1,6), BTN_SIZE(1,1), GET_TEXT_F(MSG_HOT));
}
#define TOG_STYLE(A) colors(A ? action_btn : normal_btn)
const bool tog2 = screen_data.ChangeFilamentScreen.t_tag == 2;
const bool tog3 = screen_data.ChangeFilamentScreen.t_tag == 3;
const bool tog4 = screen_data.ChangeFilamentScreen.t_tag == 4;
const bool tog10 = screen_data.ChangeFilamentScreen.e_tag == 10;
#if HOTENDS > 1
const bool tog11 = screen_data.ChangeFilamentScreen.e_tag == 11;
#endif
#ifdef TOUCH_UI_PORTRAIT
cmd.font(font_large)
#else
cmd.font(font_medium)
#endif
.TOG_STYLE(tog10)
.tag(10) .button (BTN_POS(1,2), BTN_SIZE(1,1), F("1"))
#if HOTENDS < 2
.enabled(false)
#else
.TOG_STYLE(tog11)
#endif
.tag(11) .button (BTN_POS(2,2), BTN_SIZE(1,1), F("2"));
if (!t_ok) reset_menu_timeout();
const bool tog7 = screen_data.ChangeFilamentScreen.repeat_tag == 7;
const bool tog8 = screen_data.ChangeFilamentScreen.repeat_tag == 8;
cmd.font(
#ifdef TOUCH_UI_PORTRAIT
font_large
#else
font_small
#endif
);
{
char str[30];
format_temp_and_material(str, LOW_TEMP, GET_TEXT(MSG_MATERIAL_PLA));
cmd.tag(2) .TOG_STYLE(tog2) .button (BTN_POS(2,6), BTN_SIZE(1,1), str);
format_temp_and_material(str, MED_TEMP, GET_TEXT(MSG_MATERIAL_ABS));
cmd.tag(3) .TOG_STYLE(tog3) .button (BTN_POS(2,5), BTN_SIZE(1,1), str);
format_temp_and_material(str, HIGH_TEMP, GET_TEXT(MSG_MATERIAL_HIGH_TEMP));
cmd.tag(4) .TOG_STYLE(tog4) .button (BTN_POS(2,4), BTN_SIZE(1,1), str);
}
cmd.colors(normal_btn)
// Add tags to color gradient
.cmd(COLOR_MASK(0,0,0,0))
.tag(2) .rectangle(BTN_POS(1,6), BTN_SIZE(1,1))
.tag(3) .rectangle(BTN_POS(1,5), BTN_SIZE(1,1))
.tag(4) .rectangle(BTN_POS(1,4), BTN_SIZE(1,1))
.cmd(COLOR_MASK(1,1,1,1))
.cmd(COLOR_RGB(t_ok ? bg_text_enabled : bg_text_disabled))
#ifdef TOUCH_UI_PORTRAIT
.font(font_large)
.tag(0) .text (BTN_POS(1,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_UNLOAD_FILAMENT))
.text (BTN_POS(2,8), BTN_SIZE(1,1), GET_TEXT_F(MSG_LOAD_FILAMENT))
.tag(5) .enabled(t_ok).button (BTN_POS(1,9), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOMENTARY))
.tag(6) .enabled(t_ok).button (BTN_POS(2,9), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOMENTARY))
.tag(7).TOG_STYLE(tog7).enabled(t_ok).button (BTN_POS(1,10), BTN_SIZE(1,1), GET_TEXT_F(MSG_CONTINUOUS))
.tag(8).TOG_STYLE(tog8).enabled(t_ok).button (BTN_POS(2,10), BTN_SIZE(1,1), GET_TEXT_F(MSG_CONTINUOUS))
.tag(1).colors(action_btn) .button (BTN_POS(1,11), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
#else
.font(font_small)
.tag(0) .text (BTN_POS(3,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_UNLOAD_FILAMENT))
.text (BTN_POS(4,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_LOAD_FILAMENT))
.tag(5) .enabled(t_ok).button (BTN_POS(3,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOMENTARY))
.tag(6) .enabled(t_ok).button (BTN_POS(4,4), BTN_SIZE(1,1), GET_TEXT_F(MSG_MOMENTARY))
.tag(7).TOG_STYLE(tog7).enabled(t_ok).button (BTN_POS(3,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_CONTINUOUS))
.tag(8).TOG_STYLE(tog8).enabled(t_ok).button (BTN_POS(4,5), BTN_SIZE(1,1), GET_TEXT_F(MSG_CONTINUOUS))
.font(font_medium)
.tag(1).colors(action_btn) .button (BTN_POS(3,6), BTN_SIZE(2,1), GET_TEXT_F(MSG_BACK));
#endif
}
#undef GRID_COLS
#undef GRID_ROWS
}
uint8_t ChangeFilamentScreen::getSoftenTemp() {
switch (screen_data.ChangeFilamentScreen.t_tag) {
case 2: return LOW_TEMP;
case 3: return MED_TEMP;
case 4: return HIGH_TEMP;
default: return EXTRUDE_MINTEMP;
}
}
ExtUI::extruder_t ChangeFilamentScreen::getExtruder() {
switch (screen_data.ChangeFilamentScreen.e_tag) {
case 13: return ExtUI::E3;
case 12: return ExtUI::E2;
case 11: return ExtUI::E1;
default: return ExtUI::E0;
}
}
void ChangeFilamentScreen::doPurge() {
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
constexpr float purge_distance_mm = FILAMENT_UNLOAD_PURGE_LENGTH;
if (screen_data.ChangeFilamentScreen.need_purge) {
screen_data.ChangeFilamentScreen.need_purge = false;
MoveAxisScreen::setManualFeedrate(getExtruder(), purge_distance_mm);
ExtUI::setAxisPosition_mm(ExtUI::getAxisPosition_mm(getExtruder()) + purge_distance_mm, getExtruder());
}
#endif
}
bool ChangeFilamentScreen::onTouchStart(uint8_t tag) {
// Make the Momentary and Continuous buttons slightly more responsive
switch (tag) {
case 5: case 6: case 7: case 8:
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
if (tag == 5 || tag == 7) doPurge();
#endif
return ChangeFilamentScreen::onTouchHeld(tag);
default:
return false;
}
}
bool ChangeFilamentScreen::onTouchEnd(uint8_t tag) {
using namespace ExtUI;
switch (tag) {
case 1: GOTO_PREVIOUS(); break;
case 2:
case 3:
case 4:
// Change temperature
screen_data.ChangeFilamentScreen.t_tag = tag;
setTargetTemp_celsius(getSoftenTemp(), getExtruder());
break;
case 7:
screen_data.ChangeFilamentScreen.repeat_tag = (screen_data.ChangeFilamentScreen.repeat_tag == 7) ? 0 : 7;
break;
case 8:
screen_data.ChangeFilamentScreen.repeat_tag = (screen_data.ChangeFilamentScreen.repeat_tag == 8) ? 0 : 8;
break;
case 10:
case 11:
// Change extruder
screen_data.ChangeFilamentScreen.e_tag = tag;
screen_data.ChangeFilamentScreen.t_tag = 0;
screen_data.ChangeFilamentScreen.repeat_tag = 0;
#if FILAMENT_UNLOAD_PURGE_LENGTH > 0
screen_data.ChangeFilamentScreen.need_purge = true;
#endif
setActiveTool(getExtruder(), true);
break;
case 15: GOTO_SCREEN(TemperatureScreen); break;
}
return true;
}
bool ChangeFilamentScreen::onTouchHeld(uint8_t tag) {
if (ExtUI::isMoving()) return false; // Don't allow moves to accumulate
constexpr float increment = 1;
#define UI_INCREMENT_AXIS(axis) UI_INCREMENT(AxisPosition_mm, axis);
#define UI_DECREMENT_AXIS(axis) UI_DECREMENT(AxisPosition_mm, axis);
switch (tag) {
case 5: case 7: UI_DECREMENT_AXIS(getExtruder()); break;
case 6: case 8: UI_INCREMENT_AXIS(getExtruder()); break;
default: return false;
}
#undef UI_DECREMENT_AXIS
#undef UI_INCREMENT_AXIS
return false;
}
void ChangeFilamentScreen::onIdle() {
reset_menu_timeout();
if (screen_data.ChangeFilamentScreen.repeat_tag) onTouchHeld(screen_data.ChangeFilamentScreen.repeat_tag);
if (refresh_timer.elapsed(STATUS_UPDATE_INTERVAL)) {
onRefresh();
refresh_timer.start();
}
BaseScreen::onIdle();
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,47 @@
/**************************************
* confirm_abort_print_dialog_box.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
using namespace ExtUI;
void ConfirmAbortPrintDialogBox::onRedraw(draw_mode_t) {
drawMessage(GET_TEXT_F(MSG_ABORT_WARNING));
drawYesNoButtons();
}
bool ConfirmAbortPrintDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
GOTO_PREVIOUS();
stopPrint();
return true;
default:
return DialogBoxBaseClass::onTouchEnd(tag);
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,48 @@
/*******************************************
* confirm_auto_calibration_dialog_box.cpp *
*******************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if BOTH(TOUCH_UI_FTDI_EVE, CALIBRATION_GCODE)
#include "screens.h"
using namespace ExtUI;
using namespace Theme;
void ConfirmAutoCalibrationDialogBox::onRedraw(draw_mode_t) {
drawMessage(GET_TEXT_F(MSG_CALIBRATION_WARNING));
drawYesNoButtons();
}
bool ConfirmAutoCalibrationDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
GOTO_SCREEN(StatusScreen);
injectCommands_P(PSTR(CALIBRATION_COMMANDS));
return true;
default:
return DialogBoxBaseClass::onTouchEnd(tag);
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,54 @@
/**************************************
* confirm_erase_flash_dialog_box.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if BOTH(TOUCH_UI_FTDI_EVE, TOUCH_UI_DEVELOPER_MENU)
#include "screens.h"
#include "../archim2-flash/flash_storage.h"
using namespace FTDI;
void ConfirmEraseFlashDialogBox::onRedraw(draw_mode_t) {
drawMessage(GET_TEXT_F(MSG_ERASE_FLASH_WARNING));
drawYesNoButtons();
}
bool ConfirmEraseFlashDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
SpinnerDialogBox::show(GET_TEXT_F(MSG_ERASING));
UIFlashStorage::format_flash();
SpinnerDialogBox::hide();
AlertDialogBox::show(GET_TEXT_F(MSG_ERASED));
// Remove ConfirmEraseFlashDialogBox from the stack
// so the alert box doesn't return to me.
current_screen.forget();
return true;
default:
return DialogBoxBaseClass::onTouchEnd(tag);
}
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,70 @@
/**************************************
* confirm_start_print_dialog_box.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "screen_data.h"
using namespace FTDI;
using namespace Theme;
using namespace ExtUI;
void ConfirmStartPrintDialogBox::onEntry() {
BaseScreen::onEntry();
sound.play(twinkle, PLAY_ASYNCHRONOUS);
}
void ConfirmStartPrintDialogBox::onRedraw(draw_mode_t) {
const char *filename = getLongFilename();
char buffer[strlen_P(GET_TEXT(MSG_START_PRINT_CONFIRMATION)) + strlen(filename) + 1];
sprintf_P(buffer, GET_TEXT(MSG_START_PRINT_CONFIRMATION), filename);
drawMessage((const char *)buffer);
drawYesNoButtons(1);
}
bool ConfirmStartPrintDialogBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
printFile(getShortFilename());
StatusScreen::setStatusMessage(GET_TEXT_F(MSG_PRINT_STARTING));
GOTO_SCREEN(StatusScreen);
return true;
case 2: GOTO_PREVIOUS(); return true;
default: return false;
}
}
const char *ConfirmStartPrintDialogBox::getFilename(bool longName) {
FileList files;
files.seek(screen_data.ConfirmStartPrintDialogBox.file_index, true);
return longName ? files.longFilename() : files.shortFilename();
}
void ConfirmStartPrintDialogBox::show(uint8_t file_index) {
screen_data.ConfirmStartPrintDialogBox.file_index = file_index;
GOTO_SCREEN(ConfirmStartPrintDialogBox);
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,58 @@
/**************************************
* confirm_user_request_alert_box.cpp *
**************************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
#include "screen_data.h"
using namespace FTDI;
void ConfirmUserRequestAlertBox::onRedraw(draw_mode_t mode) {
AlertDialogBox::onRedraw(mode); // Required for the GOTO_SCREEN function to work
}
bool ConfirmUserRequestAlertBox::onTouchEnd(uint8_t tag) {
switch (tag) {
case 1:
ExtUI::setUserConfirmed();
GOTO_PREVIOUS();
return true;
case 2: GOTO_PREVIOUS(); return true;
default: return false;
}
}
void ConfirmUserRequestAlertBox::show(const char* msg) {
drawMessage(msg);
storeBackground();
screen_data.AlertDialogBox.isError = false;
GOTO_SCREEN(ConfirmUserRequestAlertBox);
}
void ConfirmUserRequestAlertBox::hide() {
if (AT_SCREEN(ConfirmUserRequestAlertBox))
GOTO_PREVIOUS();
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,63 @@
/***********************************
* default_acceleration_screen.cpp *
***********************************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if ENABLED(TOUCH_UI_FTDI_EVE)
#include "screens.h"
using namespace FTDI;
using namespace ExtUI;
using namespace Theme;
void DefaultAccelerationScreen::onRedraw(draw_mode_t what) {
widgets_t w(what);
w.precision(0);
w.units(GET_TEXT_F(MSG_UNITS_MM_S2));
w.heading( GET_TEXT_F(MSG_ACCELERATION));
w.color(other);
w.adjuster( 2, GET_TEXT_F(MSG_ACCEL_PRINTING), getPrintingAcceleration_mm_s2() );
w.adjuster( 4, GET_TEXT_F(MSG_ACCEL_TRAVEL), getTravelAcceleration_mm_s2() );
w.adjuster( 6, GET_TEXT_F(MSG_ACCEL_RETRACT), getRetractAcceleration_mm_s2() );
w.increments();
w.button( 8, GET_TEXT_F(MSG_SET_MAXIMUM));
}
bool DefaultAccelerationScreen::onTouchHeld(uint8_t tag) {
const float increment = getIncrement();
switch (tag) {
case 2: UI_DECREMENT(PrintingAcceleration_mm_s2); break;
case 3: UI_INCREMENT(PrintingAcceleration_mm_s2); break;
case 4: UI_DECREMENT(TravelAcceleration_mm_s2); break;
case 5: UI_INCREMENT(TravelAcceleration_mm_s2); break;
case 6: UI_DECREMENT(RetractAcceleration_mm_s2); break;
case 7: UI_INCREMENT(RetractAcceleration_mm_s2); break;
case 8: GOTO_SCREEN(MaxAccelerationScreen); break;
default:
return false;
}
SaveSettingsDialogBox::settingsChanged();
return true;
}
#endif // TOUCH_UI_FTDI_EVE

View File

@ -0,0 +1,150 @@
/**********************
* developer_menu.cpp *
**********************/
/****************************************************************************
* Written By Mark Pelletier 2017 - Aleph Objects, Inc. *
* Written By Marcio Teixeira 2018 - Aleph Objects, Inc. *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* To view a copy of the GNU General Public License, go to the following *
* location: <http://www.gnu.org/licenses/>. *
****************************************************************************/
#include "../config.h"
#if BOTH(TOUCH_UI_FTDI_EVE, TOUCH_UI_DEVELOPER_MENU)
#include "screens.h"
#include "../archim2-flash/flash_storage.h"
using namespace FTDI;
using namespace Theme;
void DeveloperMenu::onRedraw(draw_mode_t what) {
if (what & BACKGROUND) {
CommandProcessor cmd;
cmd.cmd(CLEAR_COLOR_RGB(bg_color))
.cmd(CLEAR(true,true,true))
.font(font_medium)
.tag(0);
#ifdef SPI_FLASH_SS
constexpr bool has_flash = true;
#else
constexpr bool has_flash = false;
#endif
#if ENABLED(SDSUPPORT)
constexpr bool has_media = true;
#else
constexpr bool has_media = false;
#endif
cmd.cmd(COLOR_RGB(bg_text_enabled));
#ifdef TOUCH_UI_PORTRAIT
#define GRID_ROWS 10
#define GRID_COLS 1
cmd.font(font_large) .text ( BTN_POS(1,1), BTN_SIZE(1,1), F("Developer Menu"))
.colors(normal_btn)
.tag(2).font(font_medium) .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Show All Widgets"))
.tag(3) .button( BTN_POS(1,3), BTN_SIZE(1,1), F("Stress Test"))
.tag(4) .button( BTN_POS(1,4), BTN_SIZE(1,1), F("Show Touch Registers"))
.tag(5) .button( BTN_POS(1,5), BTN_SIZE(1,1), F("Play Song"))
.tag(6).enabled(has_media).button( BTN_POS(1,6), BTN_SIZE(1,1), F("Play Video from Media"))
.tag(7).enabled(has_flash).button( BTN_POS(1,7), BTN_SIZE(1,1), F("Play Video from SPI Flash"))
.tag(8).enabled(has_flash).button( BTN_POS(1,8), BTN_SIZE(1,1), F("Load Video to SPI Flash"))
.tag(9).enabled(has_flash).button( BTN_POS(1,9), BTN_SIZE(1,1), F("Erase SPI Flash"))
.tag(1).colors(action_btn)
.button( BTN_POS(1,10), BTN_SIZE(1,1), F("Back"));
#else
#define GRID_ROWS 6
#define GRID_COLS 2
cmd.font(font_medium) .text ( BTN_POS(1,1), BTN_SIZE(2,1), F("Developer Menu"))
.colors(normal_btn)
.tag(2).font(font_small) .button( BTN_POS(1,2), BTN_SIZE(1,1), F("Show All Widgets"))
.tag(3) .button( BTN_POS(1,3), BTN_SIZE(1,1), F("Show Touch Registers"))
.tag(9) .button( BTN_POS(1,4), BTN_SIZE(1,1), F("Show Pin States"))
.tag(4) .button( BTN_POS(1,5), BTN_SIZE(1,1), F("Play Song"))
.tag(5).enabled(has_media).button( BTN_POS(2,2), BTN_SIZE(1,1), F("Play Video from Media"))
.tag(6).enabled(has_flash).button( BTN_POS(2,3), BTN_SIZE(1,1), F("Play Video from SPI Flash"))
.tag(7).enabled(has_flash).button( BTN_POS(2,4), BTN_SIZE(1,1), F("Load Video to SPI Flash"))
.tag(8).enabled(has_flash).button( BTN_POS(2,5), BTN_SIZE(1,1), F("Erase SPI Flash"))
.tag(1).colors(action_btn)
.button( BTN_POS(1,6), BTN_SIZE(2,1), F("Back"));
#endif
}
}
bool DeveloperMenu::onTouchEnd(uint8_t tag) {
using namespace Theme;
switch (tag) {
case 1: GOTO_PREVIOUS(); break;
case 2: GOTO_SCREEN(WidgetsScreen); break;
case 3:
PUSH_SCREEN(StressTestScreen);
AlertDialogBox::show(F("Please do not run this test unattended as it may cause your printer to malfunction."));
current_screen.forget();
break;
case 4: GOTO_SCREEN(TouchRegistersScreen); break;
case 5: sound.play(js_bach_joy, PLAY_ASYNCHRONOUS); break;
#if ENABLED(SDSUPPORT)
case 6:
if (!MediaPlayerScreen::playCardMedia())
AlertDialogBox::showError(F("Cannot open STARTUP.AVI"));
break;
#endif
#ifdef SPI_FLASH_SS
case 7:
if (!MediaPlayerScreen::playBootMedia())
AlertDialogBox::showError(F("No boot media available"));
break;
case 8:
{
SpinnerDialogBox::show(F("Saving..."));
UIFlashStorage::error_t res = UIFlashStorage::write_media_file(F("STARTUP.AVI"));
SpinnerDialogBox::hide();
reset_menu_timeout();
switch (res) {
case UIFlashStorage::SUCCESS:
AlertDialogBox::show(F("File copied!"));
break;
case UIFlashStorage::READ_ERROR:
AlertDialogBox::showError(F("Failed to read file"));
break;
case UIFlashStorage::VERIFY_ERROR:
AlertDialogBox::showError(F("Failed to verify file"));
break;
case UIFlashStorage::FILE_NOT_FOUND:
AlertDialogBox::showError(F("Cannot open STARTUP.AVI"));
break;
case UIFlashStorage::WOULD_OVERWRITE:
AlertDialogBox::showError(F("Cannot overwrite existing media."));
break;
}
break;
}
case 9: GOTO_SCREEN(ConfirmEraseFlashDialogBox); break;
#endif
case 10: GOTO_SCREEN(EndstopStatesScreen); break;
default: return false;
}
return true;
}
#endif // TOUCH_UI_FTDI_EVE

Some files were not shown because too many files have changed in this diff Show More