Creality Ender 3 v2 (#17719)

This commit is contained in:
Scott Lahteine 2020-06-16 01:45:27 -05:00 committed by GitHub
parent 642112d3eb
commit f4c258dc23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 5379 additions and 82 deletions

View file

@ -67,6 +67,7 @@ jobs:
- rumba32_f446ve
- rumba32_mks
- mks_robin_pro
- STM32F103RET6_creality
# Put lengthy tests last

View file

@ -904,6 +904,11 @@
*/
//#define BLTOUCH
/**
* Pressure sensor with a BLTouch-like interface
*/
//#define CREALITY_TOUCH
/**
* Touch-MI Probe by hotends.fr
*
@ -2130,6 +2135,11 @@
//
//#define SPI_GRAPHICAL_TFT
//
// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder.
//
//#define DWIN_CREALITY_LCD
//
// ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8
//

View file

@ -44,8 +44,12 @@ typedef uint16_t hal_timer_t;
#define HAL_TIMER_RATE uint32_t(F_CPU) // frequency of timers peripherals
#define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#ifndef STEP_TIMER_CHAN
#define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#endif
#ifndef TEMP_TIMER_CHAN
#define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#endif
/**
* Note: Timers may be used by platforms and libraries

View file

@ -65,6 +65,16 @@
#include "lcd/extui/lib/mks_ui/inc/draw_ui.h"
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#include "lcd/dwin/dwin.h"
#include "lcd/dwin/dwin_lcd.h"
#include "lcd/dwin/rotary_encoder.h"
#endif
#if ENABLED(IIC_BL24CXX_EEPROM)
#include "lcd/dwin/eeprom_BL24CXX.h"
#endif
#if ENABLED(DIRECT_STEPPING)
#include "feature/direct_stepping.h"
#endif
@ -689,6 +699,9 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
// Handle SD Card insert / remove
TERN_(SDSUPPORT, card.manage_media());
// Handle UI input / draw events
TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
// Handle USB Flash Drive insert / remove
TERN_(USB_FLASH_DRIVE_SUPPORT, Sd2Card::idle());
@ -962,8 +975,19 @@ void setup() {
// UI must be initialized before EEPROM
// (because EEPROM code calls the UI).
SETUP_RUN(ui.init());
SETUP_RUN(ui.reset_status()); // Load welcome message early. (Retained if no errors exist.)
#if ENABLED(DWIN_CREALITY_LCD)
delay(800); // Required delay (since boot?)
SERIAL_ECHOPGM("\nDWIN handshake ");
if (DWIN_Handshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error.");
DWIN_Frame_SetDir(1); // Orientation 90°
DWIN_UpdateLCD(); // Show bootscreen (first image)
#else
SETUP_RUN(ui.init());
#if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN)
SETUP_RUN(ui.show_bootscreen());
#endif
SETUP_RUN(ui.reset_status()); // Load welcome message early. (Retained if no errors exist.)
#endif
#if BOTH(HAS_SPI_LCD, SHOW_BOOTSCREEN)
SETUP_RUN(ui.show_bootscreen());
@ -1143,6 +1167,22 @@ void setup() {
SETUP_RUN(mmu2.init());
#endif
#if ENABLED(IIC_BL24CXX_EEPROM)
BL24CXX::init();
const uint8_t err = BL24CXX::check();
SERIAL_ECHO_TERNARY(err, "I2C_EEPROM Check ", "failed", "succeeded", "!\n");
#endif
#if ENABLED(DWIN_CREALITY_LCD)
Encoder_Configuration();
HMI_Init();
HMI_StartFrame(true);
#endif
#if HAS_SERVICE_INTERVALS && DISABLED(DWIN_CREALITY_LCD)
ui.reset_status(true); // Show service messages or keep current status
#endif
#if ENABLED(MAX7219_DEBUG)
SETUP_RUN(max7219.init());
#endif

View file

@ -310,6 +310,7 @@
#define BOARD_CCROBOT_MEEB_3DP 4029 // ccrobot-online.com MEEB_3DP (STM32F103RC)
#define BOARD_CHITU3D_V5 4030 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CHITU3D_V6 4031 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CREALITY_V4 4032 // Creality v4.x (STM32F103RE)
//
// ARM Cortex-M4F

View file

@ -51,10 +51,16 @@ extern uint8_t marlin_debug_flags;
extern int8_t serial_port_index;
#define _PORT_REDIRECT(n,p) REMEMBER(n,serial_port_index,p)
#define _PORT_RESTORE(n) RESTORE(n)
#define SERIAL_OUT(WHAT, V...) do{ \
if (!serial_port_index || serial_port_index == SERIAL_BOTH) (void)MYSERIAL0.WHAT(V); \
if ( serial_port_index) (void)MYSERIAL1.WHAT(V); \
}while(0)
#ifdef SERIAL_CATCHALL
#define SERIAL_OUT(WHAT, V...) (void)CAT(MYSERIAL,SERIAL_CATCHALL).WHAT(V)
#else
#define SERIAL_OUT(WHAT, V...) do{ \
if (!serial_port_index || serial_port_index == SERIAL_BOTH) (void)MYSERIAL0.WHAT(V); \
if ( serial_port_index) (void)MYSERIAL1.WHAT(V); \
}while(0)
#endif
#define SERIAL_ASSERT(P) if(serial_port_index!=(P)){ debugger(); }
#else
#define _PORT_REDIRECT(n,p) NOOP

View file

@ -26,9 +26,17 @@
// BLTouch commands are sent as servo angles
typedef unsigned char BLTCommand;
#define BLTOUCH_DEPLOY 10
#if ENABLED(CREALITY_TOUCH)
#define STOW_ALARM false
#define BLTOUCH_DEPLOY 170
#define BLTOUCH_STOW 20
#else
#define STOW_ALARM true
#define BLTOUCH_DEPLOY 10
#define BLTOUCH_STOW 90
#endif
#define BLTOUCH_SW_MODE 60
#define BLTOUCH_STOW 90
#define BLTOUCH_SELFTEST 120
#define BLTOUCH_MODE_STORE 130
#define BLTOUCH_5V_MODE 140
@ -95,7 +103,7 @@ public:
private:
FORCE_INLINE static bool _deploy_query_alarm() { return command(BLTOUCH_DEPLOY, BLTOUCH_DEPLOY_DELAY); }
FORCE_INLINE static bool _stow_query_alarm() { return command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY); }
FORCE_INLINE static bool _stow_query_alarm() { return command(BLTOUCH_STOW, BLTOUCH_STOW_DELAY) == STOW_ALARM; }
static void clear();
static bool command(const BLTCommand cmd, const millis_t &ms);

View file

@ -40,6 +40,10 @@ uint8_t PrintJobRecovery::queue_index_r;
uint32_t PrintJobRecovery::cmd_sdpos, // = 0
PrintJobRecovery::sdpos[BUFSIZE];
#if ENABLED(DWIN_CREALITY_LCD)
bool PrintJobRecovery::dwin_flag; // = false
#endif
#include "../sd/cardreader.h"
#include "../lcd/ultralcd.h"
#include "../gcode/queue.h"
@ -105,6 +109,7 @@ void PrintJobRecovery::check() {
load();
if (!valid()) return cancel();
queue.inject_P(PSTR("M1000 S"));
TERN_(DWIN_CREALITY_LCD, dwin_flag = true);
}
}

View file

@ -121,6 +121,10 @@ class PrintJobRecovery {
static uint32_t cmd_sdpos, //!< SD position of the next command
sdpos[BUFSIZE]; //!< SD positions of queued commands
#if ENABLED(DWIN_CREALITY_LCD)
static bool dwin_flag;
#endif
static void init();
static void prepare();

View file

@ -60,6 +60,10 @@
#include "../../../lcd/extui/ui_api.h"
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#include "../../../lcd/dwin/dwin.h"
#endif
#if HAS_MULTI_HOTEND
#include "../../../module/tool_change.h"
#endif
@ -888,6 +892,10 @@ G29_TYPE GcodeSuite::G29() {
process_subcommands_now_P(PSTR(Z_PROBE_END_SCRIPT));
#endif
#if ENABLED(DWIN_CREALITY_LCD)
DWIN_CompletedLeveling();
#endif
report_current_position();
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("<<< G29");

View file

@ -46,6 +46,9 @@
#endif
#include "../../lcd/ultralcd.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../../lcd/dwin/dwin.h"
#endif
#if HAS_L64XX // set L6470 absolute position registers to counts
#include "../../libs/L64XX/L64XX_Marlin.h"
@ -209,6 +212,8 @@ void GcodeSuite::G28() {
log_machine_info();
}
TERN_(DWIN_CREALITY_LCD, HMI_flag.home_flag = true);
#if ENABLED(DUAL_X_CARRIAGE)
bool IDEX_saved_duplication_state = extruder_duplication_enabled;
DualXMode IDEX_saved_mode = dual_x_carriage_mode;
@ -475,6 +480,8 @@ void GcodeSuite::G28() {
ui.refresh();
TERN_(DWIN_CREALITY_LCD, DWIN_CompletedHoming());
report_current_position();
if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS)))

View file

@ -31,7 +31,6 @@
#if ENABLED(PARK_HEAD_ON_PAUSE)
#include "../../feature/pause.h"
#include "../queue.h"
#endif
#if ENABLED(HOST_ACTION_COMMANDS)
@ -98,7 +97,8 @@ void GcodeSuite::M25() {
#endif
print_job_timer.pause();
ui.reset_status();
TERN(DWIN_CREALITY_LCD,,ui.reset_status());
#if ENABLED(HOST_ACTION_COMMANDS)
TERN_(HOST_PROMPT_SUPPORT, host_prompt_open(PROMPT_PAUSE_RESUME, PSTR("Pause SD"), PSTR("Resume")));

View file

@ -529,6 +529,15 @@
#define UNUSED_E(E) UNUSED(E)
#endif
#if ENABLED(DWIN_CREALITY_LCD)
#define SERIAL_CATCHALL 0
#endif
// Pressure sensor with a BLTouch-like interface
#if ENABLED(CREALITY_TOUCH)
#define BLTOUCH
#endif
/**
* The BLTouch Probe emulates a servo probe
* and uses "special" angles for its state.

View file

@ -2465,7 +2465,11 @@
#endif
// Number of VFAT entries used. Each entry has 13 UTF-16 characters
#define MAX_VFAT_ENTRIES TERN(SCROLL_LONG_FILENAMES, 5, 2)
#if EITHER(SCROLL_LONG_FILENAMES, DWIN_CREALITY_LCD)
#define MAX_VFAT_ENTRIES (5)
#else
#define MAX_VFAT_ENTRIES (2)
#endif
// Nozzle park for Delta
#if BOTH(NOZZLE_PARK_FEATURE, DELTA)

View file

@ -1165,7 +1165,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
+ ENABLED(FIX_MOUNTED_PROBE) \
+ ENABLED(NOZZLE_AS_PROBE) \
+ (HAS_Z_SERVO_PROBE && DISABLED(BLTOUCH)) \
+ ENABLED(BLTOUCH) \
+ ENABLED(BLTOUCH) && DISABLED(CREALITY_TOUCH) \
+ ENABLED(CREALITY_TOUCH) \
+ ENABLED(TOUCH_MI_PROBE) \
+ ENABLED(SOLENOID_PROBE) \
+ ENABLED(Z_PROBE_ALLEN_KEY) \
@ -2150,6 +2151,7 @@ static_assert(hbm[Z_AXIS] >= 0, "HOMING_BUMP_MM.Z must be greater than or equal
+ ENABLED(FYSETC_MINI_12864_2_1) \
+ ENABLED(FYSETC_GENERIC_12864_1_1) \
+ ENABLED(CR10_STOCKDISPLAY) \
+ ENABLED(DWIN_CREALITY_LCD) \
+ ENABLED(ANET_FULL_GRAPHICS_LCD) \
+ ENABLED(AZSMZ_12864) \
+ ENABLED(SILVER_GATE_GLCD_CONTROLLER) \

View file

@ -0,0 +1,7 @@
# DWIN for Creality Ender 3 v2
Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.0.x/config/examples/Creality/Ender-3%20V2).
## Easy Install
Copy the `DWIN_SET` folder onto a Micro-SD card and insert the card into the slot on the DWIN screen. Cycle the machine and wait for the screen to go from blue to orange. Turn the machine off and remove the SD card. When you turn on the machine the screen will display a "Creality" loading screen.

3390
Marlin/src/lcd/dwin/dwin.cpp Normal file

File diff suppressed because it is too large Load diff

379
Marlin/src/lcd/dwin/dwin.h Normal file
View file

@ -0,0 +1,379 @@
/**
* 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
/**
* DWIN by Creality3D
*/
#include "dwin_lcd.h"
#include "rotary_encoder.h"
#include "eeprom_BL24CXX.h"
#include <stdint.h>
#define MACHINE_SIZE "220x220x250"
#define CORP_WEBSITE_C "www.cxsw3d.com"
#define CORP_WEBSITE_E "www.creality.com"
/*********************************/
#define MENU_CHAR_LIMIT 24
/*fan speed limit*/
#define FanOn 255
#define FanOff 0
/*print speed limit*/
#define max_print_speed 999
#define min_print_speed 10
/*Temp limit*/
#define max_E_Temp (HEATER_0_MAXTEMP - 15)
#define min_E_Temp HEATER_0_MINTEMP
#define max_Bed_Temp (BED_MAXTEMP - 10)
#define min_Bed_Temp BED_MINTEMP
/*Feedspeed limit*/ // max feedspeed = DEFAULT_MAX_FEEDRATE * 2
#define min_MaxFeedspeed 1
#define min_MaxAcceleration 1
#define min_MaxCorner 0.1
#define min_Step 1
#define FEEDRATE_E (60)
// mininum unit (0.1) : multiple (10)
#define MinUnitMult 10
#define Encoder_wait 20
#define DWIN_SCROLL_UPDATE_INTERVAL 2000
#define DWIN_REMAIN_TIME_UPDATE_INTERVAL 20000
enum processID {
/*Process ID*/
MainMenu,
SelectFile,
Prepare,
Control,
Leveling,
PrintProcess,
AxisMove,
TemperatureID,
Motion,
Info,
Tune,
PLAPreheat,
ABSPreheat,
MaxSpeed,
MaxSpeed_value,
MaxAcceleration,
MaxAcceleration_value,
MaxCorner,
MaxCorner_value,
Step,
Step_value,
/*Last Process ID*/
Last_Prepare,
/*Back Process ID*/
Back_Main,
Back_Print,
/*Date variable ID*/
Move_X,
Move_Y,
Move_Z,
Extruder,
Homeoffset,
ETemp,
BedTemp,
FanSpeed,
PrintSpeed,
/*Window ID*/
Print_window,
Popup_Window
};
/*Picture ID*/
#define Start_Process 0
#define Language_English 1
#define Language_Chinese 2
/*ICON ID*/
#define ICON 0x09
#define ICON_LOGO 0
#define ICON_Print_0 1
#define ICON_Print_1 2
#define ICON_Prepare_0 3
#define ICON_Prepare_1 4
#define ICON_Control_0 5
#define ICON_Control_1 6
#define ICON_Leveling_0 7
#define ICON_Leveling_1 8
#define ICON_HotendTemp 9
#define ICON_BedTemp 10
#define ICON_Speed 11
#define ICON_Zoffset 12
#define ICON_Back 13
#define ICON_File 14
#define ICON_PrintTime 15
#define ICON_RemainTime 16
#define ICON_Setup_0 17
#define ICON_Setup_1 18
#define ICON_Pause_0 19
#define ICON_Pause_1 20
#define ICON_Continue_0 21
#define ICON_Continue_1 22
#define ICON_Stop_0 23
#define ICON_Stop_1 24
#define ICON_Bar 25
#define ICON_More 26
#define ICON_Axis 27
#define ICON_CloseMotor 28
#define ICON_Homing 29
#define ICON_SetHome 30
#define ICON_PLAPreheat 31
#define ICON_ABSPreheat 32
#define ICON_Cool 33
#define ICON_Language 34
#define ICON_MoveX 35
#define ICON_MoveY 36
#define ICON_MoveZ 37
#define ICON_Extruder 38
#define ICON_Temperature 40
#define ICON_Motion 41
#define ICON_WriteEEPROM 42
#define ICON_ReadEEPROM 43
#define ICON_ResumeEEPROM 44
#define ICON_Info 45
#define ICON_SetEndTemp 46
#define ICON_SetBedTemp 47
#define ICON_FanSpeed 48
#define ICON_SetPLAPreheat 49
#define ICON_SetABSPreheat 50
#define ICON_MaxSpeed 51
#define ICON_MaxAccelerated 52
#define ICON_MaxCorner 53
#define ICON_Step 54
#define ICON_PrintSize 55
#define ICON_Version 56
#define ICON_Contact 57
#define ICON_StockConfiguraton 58
#define ICON_MaxSpeedX 59
#define ICON_MaxSpeedY 60
#define ICON_MaxSpeedZ 61
#define ICON_MaxSpeedE 62
#define ICON_MaxAccX 63
#define ICON_MaxAccY 64
#define ICON_MaxAccZ 65
#define ICON_MaxAccE 66
#define ICON_MaxSpeedCornerX 67
#define ICON_MaxSpeedCornerY 68
#define ICON_MaxSpeedCornerZ 69
#define ICON_MaxSpeedCornerE 70
#define ICON_StepX 71
#define ICON_StepY 72
#define ICON_StepZ 73
#define ICON_StepE 74
#define ICON_Setspeed 75
#define ICON_SetZOffset 76
#define ICON_Rectangle 77
#define ICON_BLTouch 78
#define ICON_TempTooLow 79
#define ICON_AutoLeveling 80
#define ICON_TempTooHigh 81
#define ICON_NoTips_C 82
#define ICON_NoTips_E 83
#define ICON_Continue_C 84
#define ICON_Continue_E 85
#define ICON_Cancel_C 86
#define ICON_Cancel_E 87
#define ICON_Confirm_C 88
#define ICON_Confirm_E 89
#define ICON_Info_0 90
#define ICON_Info_1 91
/*
* 3-.00x00-0x09
* 0x00=6*12 0x01=8*16 0x02=10*20 0x03=12*24 0x04=14*28
* 0x05=16*32 0x06=20*40 0x07=24*48 0x08=28*56 0x09=32*64
*/
#define font6x12 0x00
#define font8x16 0x01
#define font10x20 0x02
#define font12x24 0x03
#define font14x28 0x04
#define font16x32 0x05
#define font20x40 0x06
#define font24x48 0x07
#define font28x56 0x08
#define font32x64 0x09
/* Colour */
#define White 0xFFFF
#define Background_window 0x31E8 // 弹窗背景色
#define Background_blue 0x1125 // 暗蓝背景色
#define Background_black 0x0841 // 黑色背景色
#define Font_window 0xD6BA // 弹窗字体背景色
#define Line_Color 0x3A6A // 分割线颜色
#define Rectangle_Color 0xEE2F // 蓝色方块光标颜色
#define Percent_Color 0xFE29 // 百分比颜色
#define BarFill_Color 0x10E4 // 进度条填充色
#define Select_Color 0x33BB // 选中色
extern int checkkey, last_checkkey;
extern float zprobe_zoffset;
extern char print_filename[16];
extern millis_t heat_time;
typedef struct {
int16_t E_Temp = 0;
int16_t Bed_Temp = 0;
int16_t Fan_speed = 0;
int16_t print_speed = 100;
float Max_Feedspeed = 0;
float Max_Acceleration = 0;
float Max_Corner = 0;
float Max_Step = 0;
float Move_X_scale = 0;
float Move_Y_scale = 0;
float Move_Z_scale = 0;
float Move_E_scale = 0;
float offset_value = 0;
char show_mode = 0; // -1: Temperature control 0: Printing temperature
int16_t preheat_hotend_temp[2];
int16_t preheat_bed_temp[2];
uint8_t preheat_fan_speed[2];
} HMI_value_t;
typedef struct {
bool language_flag; // 0: EN, 1: CN
bool pause_flag:1;
bool print_finish:1;
bool confirm_flag:1;
bool select_flag:1;
bool home_flag:1;
bool heat_flag:1; // 0: heating done 1: during heating
bool ETempTooLow_flag:1;
bool leveling_offset_flag:1;
char feedspeed_flag;
char acc_flag;
char corner_flag;
char step_flag;
} HMI_Flag;
extern HMI_value_t HMI_ValueStruct;
extern HMI_Flag HMI_flag;
/* Language */
void lcd_select_language(void);
void set_english_to_eeprom(void);
void set_chinese_to_eeprom(void);
/* Show ICON*/
void ICON_Print(bool show);
void ICON_Prepare(bool show);
void ICON_Control(bool show);
void ICON_Leveling(bool show);
void ICON_StartInfo(bool show);
void ICON_Setting(bool show);
void ICON_Pause(bool show);
void ICON_Continue(bool show);
void ICON_Stop(bool show);
/* Popup window tips */
void Popup_Window_Temperature(const bool toohigh);
void Popup_Window_ETempTooLow(void);
void Popup_Window_Resume(void);
void Popup_Window_Home(void);
void Popup_Window_Leveling(void);
void Goto_PrintProcess(void);
void Goto_MainMenu(void);
/* Variable control */
void HMI_Move_X(void);
void HMI_Move_Y(void);
void HMI_Move_Z(void);
void HMI_Move_E(void);
void HMI_Zoffset(void);
void HMI_ETemp(void);
void HMI_BedTemp(void);
void HMI_FanSpeed(void);
void HMI_PrintSpeed(void);
void HMI_MaxFeedspeedXYZE(void);
void HMI_MaxAccelerationXYZE(void);
void HMI_MaxCornerXYZE(void);
void HMI_StepXYZE(void);
void update_variable(void);
void show_plus_or_minus(uint8_t size, uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value);
/* SD Card */
void HMI_SDCardInit(void);
void HMI_SDCardUpdate(void);
/* Main Process */
void Icon_print(bool value);
void Icon_control(bool value);
void Icon_temperature(bool value);
void Icon_leveling(bool value);
/* Other */
bool Pause_HeatStatus();
void HMI_StartFrame(const bool with_update); // 开机画面
void HMI_MainMenu(void); // 主进程画面
void HMI_SelectFile(void); // 文件页
void HMI_Printing(void); // 打印页
void HMI_Prepare(void); // 准备页
void HMI_Control(void); // 控制页
void HMI_Leveling(void); // 调平页
void HMI_AxisMove(void); // 轴移动菜单
void HMI_Temperature(void); // 温度菜单
void HMI_Motion(void); // 运动菜单
void HMI_Info(void); // 信息菜单
void HMI_Tune(void); // 调整菜单
void HMI_PLAPreheatSetting(void); // PLA预热设置
void HMI_ABSPreheatSetting(void); // ABS预热设置
void HMI_MaxSpeed(void); // 最大速度子菜单
void HMI_MaxAcceleration(void); // 最大加速度子菜单
void HMI_MaxCorner(void); // 最大拐角速度子菜单
void HMI_Step(void); // 传动比
void HMI_Init(void);
void DWIN_Update(void);
void EachMomentUpdate(void);
void DWIN_HandleScreen(void);
void DWIN_CompletedHoming(void);
void DWIN_CompletedLeveling(void);

View file

@ -0,0 +1,302 @@
/**
* 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/>.
*
*/
/********************************************************************************
* @file dwin_lcd.c
* @author LEO / Creality3D
* @date 2019/07/18
* @version 2.0.1
* @brief
********************************************************************************/
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../../inc/MarlinConfig.h"
#include "dwin_lcd.h"
#include <string.h> // for memset
// Make sure DWIN_SendBuf is large enough to hold the largest
// printed string plus the draw command and tail.
uint8_t DWIN_SendBuf[11 + 24] = { 0xAA };
uint8_t DWIN_BufTail[4] = { 0xCC, 0x33, 0xC3, 0x3C };
uint8_t databuf[26] = { 0 };
uint8_t receivedType;
int recnum = 0;
inline void DWIN_Byte(size_t &i, const uint16_t bval) {
DWIN_SendBuf[++i] = bval;
}
inline void DWIN_Word(size_t &i, const uint16_t wval) {
DWIN_SendBuf[++i] = wval >> 8;
DWIN_SendBuf[++i] = wval & 0xFF;
}
inline void DWIN_Long(size_t &i, const uint32_t lval) {
DWIN_SendBuf[++i] = (lval >> 24) & 0xFF;
DWIN_SendBuf[++i] = (lval >> 16) & 0xFF;
DWIN_SendBuf[++i] = (lval >> 8) & 0xFF;
DWIN_SendBuf[++i] = lval & 0xFF;
}
inline void DWIN_String(size_t &i, char * const string) {
const size_t len = strlen(string);
memcpy(&DWIN_SendBuf[i+1], string, len);
i += len;
}
/*发送当前BUF中的数据以及包尾数据 len:整包数据长度*/
inline void DWIN_Send(size_t &i) {
++i;
LOOP_L_N(n, i) { MYSERIAL1.write(DWIN_SendBuf[n]);
delayMicroseconds(1); }
LOOP_L_N(n, 4) { MYSERIAL1.write(DWIN_BufTail[n]);
delayMicroseconds(1); }
}
/*----------------------------------------------系统变量函数----------------------------------------------*/
/*握手 1: 握手成功 2: 握手失败*/
bool DWIN_Handshake(void) {
size_t i = 0;
DWIN_Byte(i, 0x00);
DWIN_Send(i);
while (MYSERIAL1.available() > 0 && recnum < (signed)sizeof(databuf)) {
databuf[recnum] = MYSERIAL1.read();
// ignore the invalid data
if (databuf[0] != FHONE) { // prevent the program from running.
if (recnum > 0) {
recnum = 0;
ZERO(databuf);
}
continue;
}
delay(10);
recnum++;
}
return ( recnum >= 3
&& databuf[0] == FHONE
&& databuf[1] == '\0'
&& databuf[2] == 'O'
&& databuf[3] == 'K' );
}
/*设定背光亮度 luminance:亮度(0x00~0xFF)*/
void DWIN_Backlight_SetLuminance(const uint8_t luminance) {
size_t i = 0;
DWIN_Byte(i, 0x30);
DWIN_Byte(i, _MAX(luminance, 0x1F));
DWIN_Send(i);
}
/*设定画面显示方向 dir:0,0°; 1,90°; 2,180°; 3,270°*/
void DWIN_Frame_SetDir(uint8_t dir) {
size_t i = 0;
DWIN_Byte(i, 0x34);
DWIN_Byte(i, 0x5A);
DWIN_Byte(i, 0xA5);
DWIN_Byte(i, dir);
DWIN_Send(i);
}
/*更新显示*/
void DWIN_UpdateLCD(void) {
size_t i = 0;
DWIN_Byte(i, 0x3D);
DWIN_Send(i);
}
/*----------------------------------------------绘图相关函数----------------------------------------------*/
/*画面清屏 color:清屏颜色*/
void DWIN_Frame_Clear(const uint16_t color) {
size_t i = 0;
DWIN_Byte(i, 0x01);
DWIN_Word(i, color);
DWIN_Send(i);
}
/*画面画线 color:线段颜色 xStart:X起始坐标 yStart:Y起始坐标 xEnd:X终止坐标 yEnd:Y终止坐标*/
void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x03);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
/*画面画矩形 mode:0,外框;1,填充;2,异或填充 color:颜色 xStart/yStart:矩形左上坐标 xEnd/yEnd:矩形右下坐标*/
void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color,
uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x05);
DWIN_Byte(i, mode);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
/*画面区域移动 mode:0,环移;1,平移 dir:0,向左移动;1,向右移动;2,向上移动;3,向下移动 dis:移动距离
color: xStart/yStart: xEnd/yEnd:*/
void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis,
uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd) {
size_t i = 0;
DWIN_Byte(i, 0x09);
DWIN_Byte(i, (mode << 7) | dir);
DWIN_Word(i, dis);
DWIN_Word(i, color);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Send(i);
}
/*----------------------------------------------文本相关函数----------------------------------------------*/
/*画面显示字符串 widthAdjust:true,自调整字符宽度;false,不调整字符宽度 bShow:true,显示背景色;false,不显示背景色 size:字号大小
color: bColor: x/y: *string:*/
void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size,
uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string) {
size_t i = 0;
DWIN_Byte(i, 0x11);
DWIN_Byte(i, (widthAdjust? 0x80:0x00) | (bShow? 0x40:0x00) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_String(i, string);
DWIN_Send(i);
}
/*画面显示正整数 bShow:true,显示背景色;false,不显示背景色 zeroFill:true,补零;false,不补零 zeroMode:1,无效0显示为0; 0,无效0显示为空格 size:字号大小
color: bColor: iNum: x/y: value:*/
void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value) {
size_t i = 0;
DWIN_Byte(i, 0x14);
DWIN_Byte(i, (bShow? 0x80:0x00) | (zeroFill? 0x20:0x00) | (zeroMode? 0x10:0x00) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Byte(i, iNum);
DWIN_Byte(i, 0); // fNum
DWIN_Word(i, x);
DWIN_Word(i, y);
#if 0
for (char count = 0; count < 8; count++) {
DWIN_Byte(i, value);
value >>= 8;
if ((value&0xFF) == 0x00) break;
}
#else
// Write a big-endian 64 bit integer
const size_t p = i + 1;
for (char count = 8; count--;) { // 7..0
++i;
DWIN_SendBuf[p + count] = value;
value >>= 8;
}
#endif
DWIN_Send(i);
}
/*画面显示浮点数 bShow:true,显示背景色;false,不显示背景色 zeroFill:true,补零;false,不补零 zeroMode:1,无效0显示为0; 0,无效0显示为空格 size:字号大小
color: bColor: iNum: fNum: x/y: value:*/
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value) {
//uint8_t *fvalue = (uint8_t*)&value;
size_t i = 0;
DWIN_Byte(i, 0x14);
DWIN_Byte(i, (bShow? 0x80:0x00) | (zeroFill? 0x20:0x00) | (zeroMode? 0x10:0x00) | size);
DWIN_Word(i, color);
DWIN_Word(i, bColor);
DWIN_Byte(i, iNum);
DWIN_Byte(i, fNum);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Long(i, value);
/*
DWIN_Byte(i, fvalue[3]);
DWIN_Byte(i, fvalue[2]);
DWIN_Byte(i, fvalue[1]);
DWIN_Byte(i, fvalue[0]);
*/
DWIN_Send(i);
}
/*----------------------------------------------图片相关函数----------------------------------------------*/
/*jpg图片显示并缓存在#0虚拟显示区 id:图片ID*/
void DWIN_JPG_ShowAndCache(const uint8_t id) {
size_t i = 0;
DWIN_Word(i, 0x2200);
DWIN_Byte(i, id);
DWIN_Send(i); //AA 23 00 00 00 00 08 00 01 02 03 CC 33 C3 3C
}
/*图标显示 libID:图标库ID picID:图标ID x/y:图标左上坐标*/
void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y) {
NOMORE(x, DWIN_WIDTH - 1);
NOMORE(y, DWIN_HEIGHT - 1); // -- ozy -- srl
size_t i = 0;
DWIN_Byte(i, 0x23);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Byte(i, 0x80 | libID);
DWIN_Byte(i, picID);
DWIN_Send(i);
}
/*jpg图片解压到#1虚拟显示区 id:图片ID*/
void DWIN_JPG_CacheToN(uint8_t n, uint8_t id) {
size_t i = 0;
DWIN_Byte(i, 0x25);
DWIN_Byte(i, n);
DWIN_Byte(i, id);
DWIN_Send(i);
}
/*从虚拟显示区复制区域至当前画面 cacheID:虚拟区号 xStart/yStart:虚拟区左上坐标 xEnd/yEnd:虚拟区右下坐标 x/y:当前画面粘贴坐标*/
void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y) {
size_t i = 0;
DWIN_Byte(i, 0x27);
DWIN_Byte(i, 0x80 | cacheID);
DWIN_Word(i, xStart);
DWIN_Word(i, yStart);
DWIN_Word(i, xEnd);
DWIN_Word(i, yEnd);
DWIN_Word(i, x);
DWIN_Word(i, y);
DWIN_Send(i);
}
#endif // DWIN_CREALITY_LCD

View file

@ -0,0 +1,111 @@
/**
* 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
/********************************************************************************
* @file dwin_lcd.h
* @author LEO / Creality3D
* @date 2019/07/18
* @version 2.0.1
* @brief
********************************************************************************/
#include <stdint.h>
#define RECEIVED_NO_DATA 0x00
#define RECEIVED_SHAKE_HAND_ACK 0x01
#define FHONE 0xAA
#define DWIN_SCROLL_UP 2
#define DWIN_SCROLL_DOWN 3
#define DWIN_WIDTH 272
#define DWIN_HEIGHT 480
/*接收数据解析 返回值:true,接收到数据;false,未接收到数据*/
bool DWIN_ReceiveAnalyze(void);
/*发送当前BUF中的数据以及包尾数据 len:整包数据长度*/
void DWIN_Send_BufTail(const uint8_t len);
/*----------------------------------------------系统变量函数----------------------------------------------*/
/*握手 1: 握手成功 2: 握手失败*/
bool DWIN_Handshake(void);
/*设定背光亮度 luminance:亮度(0x00~0xFF)*/
void DWIN_Backlight_SetLuminance(const uint8_t luminance);
/*设定画面显示方向 dir:0,0°; 1,90°; 2,180°; 3,270°*/
void DWIN_Frame_SetDir(uint8_t dir);
/*更新显示*/
void DWIN_UpdateLCD(void);
/*----------------------------------------------绘图相关函数----------------------------------------------*/
/*画面清屏 color:清屏颜色*/
void DWIN_Frame_Clear(const uint16_t color);
/*画面画线 color:线段颜色 xStart:X起始坐标 yStart:Y起始坐标 xEnd:X终止坐标 yEnd:Y终止坐标*/
void DWIN_Draw_Line(uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
/*画面画矩形 mode:0,外框;1,填充;2,异或填充 color:颜色 xStart/yStart:矩形左上坐标 xEnd/yEnd:矩形右下坐标*/
void DWIN_Draw_Rectangle(uint8_t mode, uint16_t color,
uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
/*画面区域移动 mode:0,环移;1,平移 dir:0,向左移动;1,向右移动;2,向上移动;3,向下移动 dis:移动距离
color: xStart/yStart: xEnd/yEnd:*/
void DWIN_Frame_AreaMove(uint8_t mode, uint8_t dir, uint16_t dis,
uint16_t color, uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd);
/*----------------------------------------------文本相关函数----------------------------------------------*/
/*画面显示字符串 widthAdjust:true,自调整字符宽度;false,不调整字符宽度 bShow:true,显示背景色;false,不显示背景色 size:字号大小
color: bColor: x/y: *string:*/
void DWIN_Draw_String(bool widthAdjust, bool bShow, uint8_t size,
uint16_t color, uint16_t bColor, uint16_t x, uint16_t y, char *string);
/*画面显示正整数 bShow:true,显示背景色;false,不显示背景色 zeroFill:true,补零;false,不补零 zeroMode:1,无效0显示为0; 0,无效0显示为空格 size:字号大小
color: bColor: iNum: x/y: value:*/
void DWIN_Draw_IntValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint16_t x, uint16_t y, uint16_t value);
/*画面显示浮点数 bShow:true,显示背景色;false,不显示背景色 zeroFill:true,补零;false,不补零 zeroMode:1,无效0显示为0; 0,无效0显示为空格 size:字号大小
color: bColor: iNum: fNum: x/y: value:*/
void DWIN_Draw_FloatValue(uint8_t bShow, bool zeroFill, uint8_t zeroMode, uint8_t size, uint16_t color,
uint16_t bColor, uint8_t iNum, uint8_t fNum, uint16_t x, uint16_t y, long value);
/*----------------------------------------------图片相关函数----------------------------------------------*/
/*jpg图片显示并缓存在#0虚拟显示区 id:图片ID*/
void DWIN_JPG_ShowAndCache(const uint8_t id);
/*图标显示 libID:图标库ID picID:图标ID x/y:图标左上坐标*/
void DWIN_ICON_Show(uint8_t libID, uint8_t picID, uint16_t x, uint16_t y);
/*jpg图片解压到#1虚拟显示区 id:图片ID*/
void DWIN_JPG_CacheToN(uint8_t n, uint8_t id);
/*jpg图片解压到#1虚拟显示区 id:图片ID*/
inline void DWIN_JPG_CacheTo1(uint8_t id) { DWIN_JPG_CacheToN(1, id); }
/*从虚拟显示区复制区域至当前画面 cacheID:虚拟区号 xStart/yStart:虚拟区左上坐标 xEnd/yEnd:虚拟区右下坐标 x/y:当前画面粘贴坐标*/
void DWIN_Frame_AreaCopy(uint8_t cacheID, uint16_t xStart, uint16_t yStart,
uint16_t xEnd, uint16_t yEnd, uint16_t x, uint16_t y);

View file

@ -0,0 +1,263 @@
/**
* 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/>.
*
*/
/********************************************************************************
* @file eeprom_BL24CXX.cpp
* @brief i2c EEPROM for Ender 3 v2 board (4.2.2)
********************************************************************************/
#include "../../inc/MarlinConfig.h"
#if ENABLED(IIC_BL24CXX_EEPROM)
#include "eeprom_BL24CXX.h"
#include "../../MarlinCore.h"
#include <stdlib.h>
/******************** IIC ********************/
// 初始化IIC
void IIC::init() {
SET_OUTPUT(IIC_EEPROM_SDA);
SET_OUTPUT(IIC_EEPROM_SCL);
IIC_SCL_1();
IIC_SDA_1();
}
// 产生IIC起始信号
void IIC::start() {
SDA_OUT(); // sda线输出
IIC_SDA_1();
IIC_SCL_1();
delay_us(4);
IIC_SDA_0(); // START:when CLK is high, DATA change form high to low
delay_us(4);
IIC_SCL_0(); // 钳住I2C总线准备发送或接收数据
}
// 产生IIC停止信号
void IIC::stop() {
SDA_OUT(); // sda线输出
IIC_SCL_0();
IIC_SDA_0(); // STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL_1();
IIC_SDA_1(); // 发送I2C总线结束信号
delay_us(4);
}
// 等待应答信号到来
// 返回值1接收应答失败
// 0接收应答成功
uint8_t IIC::wait_ack() {
uint8_t ucErrTime=0;
SDA_IN(); // SDA设置为输入
IIC_SDA_1();delay_us(1);
IIC_SCL_1();delay_us(1);
while (READ_SDA()) {
ucErrTime++;
if (ucErrTime>250) {
stop();
return 1;
}
}
IIC_SCL_0(); // 时钟输出0
return 0;
}
// 产生ACK应答
void IIC::ack() {
IIC_SCL_0();
SDA_OUT();
IIC_SDA_0();
delay_us(2);
IIC_SCL_1();
delay_us(2);
IIC_SCL_0();
}
// 不产生ACK应答
void IIC::nAck() {
IIC_SCL_0();
SDA_OUT();
IIC_SDA_1();
delay_us(2);
IIC_SCL_1();
delay_us(2);
IIC_SCL_0();
}
// IIC发送一个字节
// 返回从机有无应答
// 1有应答
// 0无应答
void IIC::send_byte(uint8_t txd) {
SDA_OUT();
IIC_SCL_0(); // 拉低时钟开始数据传输
LOOP_L_N(t, 8) {
// IIC_SDA = (txd & 0x80) >> 7;
if (txd & 0x80) IIC_SDA_1(); else IIC_SDA_0();
txd <<= 1;
delay_us(2); // 对TEA5767这三个延时都是必须的
IIC_SCL_1();
delay_us(2);
IIC_SCL_0();
delay_us(2);
}
}
// 读1个字节ack=1时发送ACKack=0发送nACK
uint8_t IIC::read_byte(unsigned char ack_chr) {
unsigned char receive = 0;
SDA_IN(); // SDA设置为输入
LOOP_L_N(i, 8) {
IIC_SCL_0();
delay_us(2);
IIC_SCL_1();
receive <<= 1;
if (READ_SDA()) receive++;
delay_us(1);
}
ack_chr ? ack() : nAck(); // 发送ACK / 发送nACK
return receive;
}
/******************** EEPROM ********************/
// 初始化IIC接口
void BL24CXX::init() { IIC::init(); }
// 在BL24CXX指定地址读出一个数据
// ReadAddr:开始读数的地址
// 返回值 :读到的数据
uint8_t BL24CXX::readOneByte(uint16_t ReadAddr) {
uint8_t temp = 0;
IIC::start();
if (EE_TYPE > BL24C16) {
IIC::send_byte(0xA0); // 发送写命令
IIC::wait_ack();
IIC::send_byte(ReadAddr >> 8); // 发送高地址
IIC::wait_ack();
}
else
IIC::send_byte(0xA0 + ((ReadAddr >> 8) << 1)); // 发送器件地址0xA0,写数据
IIC::wait_ack();
IIC::send_byte(ReadAddr & 0xFF); // 发送低地址
IIC::wait_ack();
IIC::start();
IIC::send_byte(0xA1); // 进入接收模式
IIC::wait_ack();
temp = IIC::read_byte(0);
IIC::stop(); // 产生一个停止条件
return temp;
}
// 在BL24CXX指定地址写入一个数据
// WriteAddr :写入数据的目的地址
// DataToWrite:要写入的数据
void BL24CXX::writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite) {
IIC::start();
if (EE_TYPE > BL24C16) {
IIC::send_byte(0xA0); // 发送写命令
IIC::wait_ack();
IIC::send_byte(WriteAddr >> 8); // 发送高地址
}
else {
IIC::send_byte(0xA0 + ((WriteAddr >> 8) << 1)); // 发送器件地址0xA0,写数据
}
IIC::wait_ack();
IIC::send_byte(WriteAddr & 0xFF); // 发送低地址
IIC::wait_ack();
IIC::send_byte(DataToWrite); // 发送字节
IIC::wait_ack();
IIC::stop(); // 产生一个停止条件
delay(10);
}
// 在BL24CXX里面的指定地址开始写入长度为Len的数据
// 该函数用于写入16bit或者32bit的数据.
// WriteAddr :开始写入的地址
// DataToWrite:数据数组首地址
// Len :要写入数据的长度2,4
void BL24CXX::writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len) {
LOOP_L_N(t, Len)
writeOneByte(WriteAddr + t, (DataToWrite >> (8 * t)) & 0xFF);
}
// 在BL24CXX里面的指定地址开始读出长度为Len的数据
// 该函数用于读出16bit或者32bit的数据.
// ReadAddr :开始读出的地址
// 返回值 :数据
// Len :要读出数据的长度2,4
uint32_t BL24CXX::readLenByte(uint16_t ReadAddr, uint8_t Len) {
uint32_t temp = 0;
LOOP_L_N(t, Len) {
temp <<= 8;
temp += readOneByte(ReadAddr + Len - t - 1);
}
return temp;
}
// 检查BL24CXX是否正常
// 这里用了24XX的最后一个地址(255)来存储标志字.
// 如果用其他24C系列,这个地址要修改
// 返回1:检测失败
// 返回0:检测成功
uint8_t BL24CXX::check() {
uint8_t temp;
temp = readOneByte(255); // 避免每次开机都写BL24CXX
if (temp == 'U') return 0;
else { // 排除第一次初始化的情况
writeOneByte(255, 'U');
temp = readOneByte(255);
if (temp == 'U') return 0;
}
return 1;
}
// 在BL24CXX里面的指定地址开始读出指定个数的数据
// ReadAddr :开始读出的地址 对24c02为0~255
// pBuffer :数据数组首地址
// NumToRead:要读出数据的个数
void BL24CXX::read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead) {
while (NumToRead) {
*pBuffer++ = readOneByte(ReadAddr++);
NumToRead--;
}
}
// 在BL24CXX里面的指定地址开始写入指定个数的数据
// WriteAddr :开始写入的地址 对24c02为0~255
// pBuffer :数据数组首地址
// NumToWrite:要写入数据的个数
void BL24CXX::write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite) {
while (NumToWrite--) {
writeOneByte(WriteAddr, *pBuffer);
WriteAddr++;
pBuffer++;
}
}
#endif // IIC_BL24CXX_EEPROM

View file

@ -0,0 +1,86 @@
/**
* 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
/********************************************************************************
* @file eeprom_BL24CXX.h
* @brief i2c EEPROM for Ender 3 v2 board (4.2.2)
********************************************************************************/
#include <libmaple/gpio.h>
/******************** IIC ********************/
//IO方向设置
#define SDA_IN() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 8 << 12; }while(0)
#define SDA_OUT() do{ PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH &= 0XFFFF0FFF; PIN_MAP[IIC_EEPROM_SDA].gpio_device->regs->CRH |= 3 << 12; }while(0)
//IO操作函数
#define IIC_SCL_0() WRITE(IIC_EEPROM_SCL, LOW)
#define IIC_SCL_1() WRITE(IIC_EEPROM_SCL, HIGH)
#define IIC_SDA_0() WRITE(IIC_EEPROM_SDA, LOW)
#define IIC_SDA_1() WRITE(IIC_EEPROM_SDA, HIGH)
#define READ_SDA() READ(IIC_EEPROM_SDA)
class BL24CXX;
// IIC所有操作函数
class IIC {
friend class BL24CXX;
protected:
static void init(); // 初始化IIC的IO口
static void start(); // 发送IIC开始信号
static void stop(); // 发送IIC停止信号
static void send_byte(uint8_t txd); // IIC发送一个字节
static uint8_t read_byte(unsigned char ack); // IIC读取一个字节
static uint8_t wait_ack(); // IIC等待ACK信号
static void ack(); // IIC发送ACK信号
static void nAck(); // IIC不发送ACK信号
static void write_one_byte(uint8_t daddr, uint8_t addr, uint8_t data);
static uint8_t read_one_byte(uint8_t daddr, uint8_t addr);
};
/******************** EEPROM ********************/
#define BL24C01 127
#define BL24C02 255
#define BL24C04 511
#define BL24C08 1023
#define BL24C16 2047
#define BL24C32 4095
#define BL24C64 8191
#define BL24C128 16383
#define BL24C256 32767
#define EE_TYPE BL24C16
class BL24CXX {
public:
static void init(); //初始化IIC
static uint8_t check(); //检查器件
static uint8_t readOneByte(uint16_t ReadAddr); //指定地址读取一个字节
static void writeOneByte(uint16_t WriteAddr, uint8_t DataToWrite); //指定地址写入一个字节
static void writeLenByte(uint16_t WriteAddr, uint32_t DataToWrite, uint8_t Len);//指定地址开始写入指定长度的数据
static uint32_t readLenByte(uint16_t ReadAddr, uint8_t Len); //指定地址开始读取指定长度数据
static void write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite); //从指定地址开始写入指定长度的数据
static void read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead); //从指定地址开始读出指定长度的数据
};

View file

@ -0,0 +1,249 @@
/**
* 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/>.
*
*/
/**
******************************************************************************
* @file rotary_encoder.cpp
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief
******************************************************************************
**/
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "rotary_encoder.h"
#include "../../MarlinCore.h"
#include "../../HAL/shared/Delay.h"
#if HAS_BUZZER
#include "../../libs/buzzer.h"
#endif
#include <stdlib.h>
ENCODER_Rate EncoderRate;
/*蜂鸣器响*/
void Encoder_tick(void) {
WRITE(BEEPER_PIN,1);
delay(10);
WRITE(BEEPER_PIN,0);
}
/*编码器初始化 PB12:Encoder_A PB13:Encoder_B PB14:Encoder_C*/
void Encoder_Configuration(void) {
#if BUTTON_EXISTS(EN1)
SET_INPUT_PULLUP(BTN_EN1);
#endif
#if BUTTON_EXISTS(EN2)
SET_INPUT_PULLUP(BTN_EN2);
#endif
#if BUTTON_EXISTS(ENC)
SET_INPUT_PULLUP(BTN_ENC);
#endif
#ifdef BEEPER_PIN
SET_OUTPUT(BEEPER_PIN);
#endif
}
millis_t next_click_update_ms;
/*接收数据解析 返回值:ENCODER_DIFF_NO,无状态; ENCODER_DIFF_CW,顺时针旋转; ENCODER_DIFF_CCW,逆时针旋转; ENCODER_DIFF_ENTER,按下*/
ENCODER_DiffState Encoder_ReceiveAnalyze(void) {
const millis_t now = millis();
static unsigned char lastEncoderBits;
unsigned char newbutton = 0;
static signed char temp_diff = 0;
ENCODER_DiffState temp_diffState = ENCODER_DIFF_NO;
if (BUTTON_PRESSED(EN1)) newbutton |= 0x01;
if (BUTTON_PRESSED(EN2)) newbutton |= 0x02;
if (BUTTON_PRESSED(ENC)) {
if (ELAPSED(now, next_click_update_ms)) {
next_click_update_ms = millis() + 300;
Encoder_tick();
#if PIN_EXISTS(LCD_LED)
//LED_Action();
#endif
return ENCODER_DIFF_ENTER;
}
else return ENCODER_DIFF_NO;
}
if (newbutton != lastEncoderBits) {
switch (newbutton) {
case ENCODER_PHASE_0: {
if (lastEncoderBits == ENCODER_PHASE_3) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_1) temp_diff--;
}break;
case ENCODER_PHASE_1: {
if (lastEncoderBits == ENCODER_PHASE_0) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_2) temp_diff--;
}break;
case ENCODER_PHASE_2: {
if (lastEncoderBits == ENCODER_PHASE_1) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_3) temp_diff--;
}break;
case ENCODER_PHASE_3: {
if (lastEncoderBits == ENCODER_PHASE_2) temp_diff++;
else if (lastEncoderBits == ENCODER_PHASE_0) temp_diff--;
}break;
}
lastEncoderBits = newbutton;
}
if (abs(temp_diff) >= ENCODER_PULSES_PER_STEP) {
if (temp_diff > 0) temp_diffState = ENCODER_DIFF_CW;
else temp_diffState = ENCODER_DIFF_CCW;
#if ENABLED(ENCODER_RATE_MULTIPLIER)
millis_t ms = millis();
int32_t encoderMultiplier = 1;
// if must encoder rati multiplier
if (EncoderRate.encoderRateEnabled) {
const float abs_diff = ABS(temp_diff);
const float encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP);
if (EncoderRate.lastEncoderTime) {
// Note that the rate is always calculated between two passes through the
// loop and that the abs of the temp_diff value is tracked.
const float encoderStepRate = encoderMovementSteps / float(ms - EncoderRate.lastEncoderTime) * 1000;
if (encoderStepRate >= ENCODER_100X_STEPS_PER_SEC) encoderMultiplier = 100;
else if (encoderStepRate >= ENCODER_10X_STEPS_PER_SEC) encoderMultiplier = 10;
else if (encoderStepRate >= ENCODER_5X_STEPS_PER_SEC) encoderMultiplier = 5;
}
EncoderRate.lastEncoderTime = ms;
}
#else
constexpr int32_t encoderMultiplier = 1;
#endif // ENCODER_RATE_MULTIPLIER
// EncoderRate.encoderMoveValue += (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP);
EncoderRate.encoderMoveValue = (temp_diff * encoderMultiplier) / (ENCODER_PULSES_PER_STEP);
if (EncoderRate.encoderMoveValue < 0) EncoderRate.encoderMoveValue = -EncoderRate.encoderMoveValue;
temp_diff = 0;
}
return temp_diffState;
}
#if PIN_EXISTS(LCD_LED)
/*取低24位有效 24Bit: G7 G6 G5 G4 G3 G2 G1 G0 R7 R6 R5 R4 R3 R2 R1 R0 B7 B6 B5 B4 B3 B2 B1 B0*/
unsigned int LED_DataArray[LED_NUM];
/*LED灯操作*/
void LED_Action(void) {
LED_Control(RGB_SCALE_WARM_WHITE,0x0F);
delay(30);
LED_Control(RGB_SCALE_WARM_WHITE,0x00);
}
/*LED初始化*/
void LED_Configuration(void) {
SET_OUTPUT(LCD_LED_PIN);
}
/*LED写数据*/
void LED_WriteData(void) {
unsigned char tempCounter_LED, tempCounter_Bit;
for (tempCounter_LED = 0; tempCounter_LED < LED_NUM; tempCounter_LED++) {
for (tempCounter_Bit = 0; tempCounter_Bit < 24; tempCounter_Bit++) {
if (LED_DataArray[tempCounter_LED] & (0x800000 >> tempCounter_Bit)) {
LED_DATA_HIGH;
DELAY_NS(300);
LED_DATA_LOW;
DELAY_NS(200);
}
else {
LED_DATA_HIGH;
LED_DATA_LOW;
DELAY_NS(200);
}
}
}
}
/*LED控制 RGB_Scale:RGB色彩配比 luminance:亮度(0~0xFF)*/
void LED_Control(unsigned char RGB_Scale, unsigned char luminance) {
unsigned char temp_Counter;
for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) {
LED_DataArray[temp_Counter] = 0;
switch(RGB_Scale) {
case RGB_SCALE_R10_G7_B5: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*7/10) << 16 | luminance*5/10; break;
case RGB_SCALE_R10_G7_B4: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*7/10) << 16 | luminance*4/10; break;
case RGB_SCALE_R10_G8_B7: LED_DataArray[temp_Counter] = (luminance*10/10) << 8 | (luminance*8/10) << 16 | luminance*7/10; break;
}
}
LED_WriteData();
}
/*LED渐变控制 RGB_Scale:RGB色彩配比 luminance:亮度(0~0xFF) change_Time:渐变时间(ms)*/
void LED_GraduallyControl(unsigned char RGB_Scale, unsigned char luminance, unsigned int change_Interval) {
unsigned char temp_Counter;
unsigned char LED_R_Data[LED_NUM], LED_G_Data[LED_NUM], LED_B_Data[LED_NUM];
bool LED_R_Flag = 0, LED_G_Flag = 0, LED_B_Flag = 0;
for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) {
switch(RGB_Scale) {
case RGB_SCALE_R10_G7_B5: {
LED_R_Data[temp_Counter] = luminance*10/10;
LED_G_Data[temp_Counter] = luminance*7/10;
LED_B_Data[temp_Counter] = luminance*5/10;
}break;
case RGB_SCALE_R10_G7_B4: {
LED_R_Data[temp_Counter] = luminance*10/10;
LED_G_Data[temp_Counter] = luminance*7/10;
LED_B_Data[temp_Counter] = luminance*4/10;
}break;
case RGB_SCALE_R10_G8_B7: {
LED_R_Data[temp_Counter] = luminance*10/10;
LED_G_Data[temp_Counter] = luminance*8/10;
LED_B_Data[temp_Counter] = luminance*7/10;
}break;
}
}
for (temp_Counter = 0; temp_Counter < LED_NUM; temp_Counter++) {
if ((unsigned char)(LED_DataArray[temp_Counter] >> 8) > LED_R_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x000100;
else if ((unsigned char)(LED_DataArray[temp_Counter] >> 8) < LED_R_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x000100;
while (1) {
else LED_R_Flag = 1;
if ((unsigned char)(LED_DataArray[temp_Counter]>>16) > LED_G_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x010000;
else if ((unsigned char)(LED_DataArray[temp_Counter]>>16) < LED_G_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x010000;
else LED_G_Flag = 1;
if ((unsigned char)LED_DataArray[temp_Counter] > LED_B_Data[temp_Counter]) LED_DataArray[temp_Counter] -= 0x000001;
else if ((unsigned char)LED_DataArray[temp_Counter] < LED_B_Data[temp_Counter]) LED_DataArray[temp_Counter] += 0x000001;
else LED_B_Flag = 1;
}
LED_WriteData();
if (LED_R_Flag && LED_G_Flag && LED_B_Flag) break;
else delay(change_Interval);
}
}
#endif
#endif // DWIN_CREALITY_LCD

View file

@ -0,0 +1,105 @@
/**
* 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
/**
******************************************************************************
* @file rotary_encoder.h
* @author LEO / Creality3D
* @date 2019/07/06
* @version 2.0.1
* @brief
******************************************************************************
**/
#include "../../inc/MarlinConfig.h"
#include "../../MarlinCore.h"
/*********************** Encoder Set ***********************/
#define ENCODER_PHASE_0 0
#define ENCODER_PHASE_1 2
#define ENCODER_PHASE_2 3
#define ENCODER_PHASE_3 1
#define ENCODER_PULSES_PER_STEP 4
#define BUTTON_PRESSED(BN) !READ(BTN_## BN)
typedef struct {
bool encoderRateEnabled = 0;
int encoderMoveValue = 0;
millis_t lastEncoderTime = 0;
} ENCODER_Rate;
extern ENCODER_Rate EncoderRate;
typedef enum {
ENCODER_DIFF_NO = 0,
ENCODER_DIFF_CW = 1,
ENCODER_DIFF_CCW = 2,
ENCODER_DIFF_ENTER = 3
} ENCODER_DiffState;
/*编码器初始化 PB12:Encoder_A PB13:Encoder_B PB14:Encoder_C*/
void Encoder_Configuration(void);
/*接收数据解析 返回值:ENCODER_DIFF_NO,无状态; ENCODER_DIFF_CW,顺时针旋转; ENCODER_DIFF_CCW,逆时针旋转; ENCODER_DIFF_ENTER,按下*/
ENCODER_DiffState Encoder_ReceiveAnalyze(void);
/*********************** Encoder LED ***********************/
#if PIN_EXISTS(LCD_LED)
#define LED_NUM 4
#define LED_DATA_HIGH WRITE(LCD_LED_PIN, 1)
#define LED_DATA_LOW WRITE(LCD_LED_PIN, 0)
#define RGB_SCALE_R10_G7_B5 1
#define RGB_SCALE_R10_G7_B4 2
#define RGB_SCALE_R10_G8_B7 3
#define RGB_SCALE_NEUTRAL_WHITE RGB_SCALE_R10_G7_B5 //正白
#define RGB_SCALE_WARM_WHITE RGB_SCALE_R10_G7_B4 //暖白
#define RGB_SCALE_COOL_WHITE RGB_SCALE_R10_G8_B7 //冷白
extern unsigned int LED_DataArray[LED_NUM];
/*状态LED初始化*/
void STATE_LED_Configuration(void);
/*LED灯操作*/
void LED_Action(void);
/*LED初始化*/
void LED_Configuration(void);
/*LED写数据*/
void LED_WriteData(void);
/*LED控制 RGB_Scale:RGB色彩配比 luminance:亮度(0~0xFF)*/
void LED_Control(unsigned char RGB_Scale, unsigned char luminance);
/*LED渐变控制 RGB_Scale:RGB色彩配比 luminance:亮度(0~0xFF) change_Time:渐变时间(ms)*/
void LED_GraduallyControl(unsigned char RGB_Scale, unsigned char luminance, unsigned int change_Interval);
#endif

View file

@ -40,7 +40,7 @@ MarlinUI ui;
#include "../gcode/queue.h"
#include "fontutils.h"
#include "../sd/cardreader.h"
#if ENABLED(EXTENSIBLE_UI)
#if EITHER(EXTENSIBLE_UI, DWIN_CREALITY_LCD)
#define START_OF_UTF8_CHAR(C) (((C) & 0xC0u) != 0x80u)
#endif
#endif
@ -56,7 +56,7 @@ MarlinUI ui;
#else
constexpr uint8_t MAX_MESSAGE_LENGTH = MAX_LANG_CHARSIZE * (LCD_WIDTH);
#endif
#elif ENABLED(EXTENSIBLE_UI)
#elif EITHER(EXTENSIBLE_UI, DWIN_CREALITY_LCD)
constexpr uint8_t MAX_MESSAGE_LENGTH = 63;
#endif
@ -145,41 +145,42 @@ millis_t MarlinUI::next_button_update_ms; // = 0
volatile int8_t encoderDiff; // Updated in update_buttons, added to encoderPosition every LCD update
#endif
#if HAS_LCD_MENU
#include "menu/menu.h"
#if ENABLED(SDSUPPORT)
#include "../sd/cardreader.h"
#if ENABLED(SDSUPPORT)
#if ENABLED(SCROLL_LONG_FILENAMES)
uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
#endif
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
const char *outstr = theCard.longest_filename();
if (theCard.longFilename[0]) {
#if ENABLED(SCROLL_LONG_FILENAMES)
if (doScroll) {
for (uint8_t l = FILENAME_LENGTH; l--;)
hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor
static uint8_t filename_scroll_hash;
if (filename_scroll_hash != hash) { // If the hash changed...
filename_scroll_hash = hash; // Save the new hash
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
filename_scroll_pos = 0; // Reset scroll to the start
lcd_status_update_delay = 8; // Don't scroll right away
}
outstr += filename_scroll_pos;
}
#else
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
#endif
}
return outstr;
}
#if MARLINUI_SCROLL_NAME
uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
#endif
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
const char *outstr = theCard.longest_filename();
if (theCard.longFilename[0]) {
#if MARLINUI_SCROLL_NAME
if (doScroll) {
for (uint8_t l = FILENAME_LENGTH; l--;)
hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor
static uint8_t filename_scroll_hash;
if (filename_scroll_hash != hash) { // If the hash changed...
filename_scroll_hash = hash; // Save the new hash
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
filename_scroll_pos = 0; // Reset scroll to the start
lcd_status_update_delay = 8; // Don't scroll right away
}
outstr += filename_scroll_pos;
}
#else
theCard.longFilename[maxlen] = '\0'; // cutoff at screen edge
#endif
}
return outstr;
}
#endif
#if HAS_LCD_MENU
#include "menu/menu.h"
screenFunc_t MarlinUI::currentScreen; // Initialized in CTOR
bool MarlinUI::screen_changed;
@ -1579,5 +1580,7 @@ void MarlinUI::update() {
set_status_P(eeprom_err(msgid));
#endif
}
#endif
#endif
#endif // EEPROM_AUTO_INIT
#endif // EEPROM_SETTINGS

View file

@ -27,6 +27,10 @@
#include "../libs/buzzer.h"
#endif
#if ENABLED(SDSUPPORT)
#include "../sd/cardreader.h"
#endif
#if EITHER(HAS_LCD_MENU, ULTIPANEL_FEEDMULTIPLY)
#define HAS_ENCODER_ACTION 1
#endif
@ -111,7 +115,7 @@
#endif // HAS_LCD_MENU
#endif
#endif // HAS_SPI_LCD
// REPRAPWORLD_KEYPAD (and ADC_KEYPAD)
#if ENABLED(REPRAPWORLD_KEYPAD)
@ -287,9 +291,13 @@ public:
static void init_lcd();
FORCE_INLINE static void refresh() { refresh(LCDVIEW_CLEAR_CALL_REDRAW); }
#else
#if ENABLED(DWIN_CREALITY_LCD)
static void refresh();
#else
static inline void refresh() {}
#endif
static inline bool detected() { return true; }
static inline void init_lcd() {}
static inline void refresh() {}
#endif
#if HAS_DISPLAY
@ -451,6 +459,16 @@ public:
#endif
#if ENABLED(SDSUPPORT)
#if BOTH(SCROLL_LONG_FILENAMES, HAS_LCD_MENU)
#define MARLINUI_SCROLL_NAME 1
#endif
#if MARLINUI_SCROLL_NAME
static uint8_t filename_scroll_pos, filename_scroll_max;
#endif
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll);
#endif
#if HAS_LCD_MENU
#if ENABLED(TOUCH_BUTTONS)
@ -464,13 +482,6 @@ public:
static void enable_encoder_multiplier(const bool onoff);
#endif
#if ENABLED(SDSUPPORT)
#if ENABLED(SCROLL_LONG_FILENAMES)
static uint8_t filename_scroll_pos, filename_scroll_max;
#endif
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll);
#endif
#if IS_KINEMATIC
static bool processing_manual_move;
#else

View file

@ -50,6 +50,11 @@
#include "planner.h"
#include "stepper.h"
#include "temperature.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/dwin/dwin.h"
#endif
#include "../lcd/ultralcd.h"
#include "../libs/vector_3.h" // for matrix_3x3
#include "../gcode/gcode.h"
@ -804,6 +809,10 @@ void MarlinSettings::postprocess() {
const int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp,
(&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp;
const uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed;
#elif ENABLED(DWIN_CREALITY_LCD)
const int16_t (&ui_preheat_hotend_temp)[2] = HMI_ValueStruct.preheat_hotend_temp,
(&ui_preheat_bed_temp)[2] = HMI_ValueStruct.preheat_bed_temp;
const uint8_t (&ui_preheat_fan_speed)[2] = HMI_ValueStruct.preheat_fan_speed;
#else
constexpr int16_t ui_preheat_hotend_temp[2] = { PREHEAT_1_TEMP_HOTEND, PREHEAT_2_TEMP_HOTEND },
ui_preheat_bed_temp[2] = { PREHEAT_1_TEMP_BED, PREHEAT_2_TEMP_BED };
@ -1664,7 +1673,11 @@ void MarlinSettings::postprocess() {
int16_t (&ui_preheat_hotend_temp)[2] = ui.preheat_hotend_temp,
(&ui_preheat_bed_temp)[2] = ui.preheat_bed_temp;
uint8_t (&ui_preheat_fan_speed)[2] = ui.preheat_fan_speed;
#else
#elif ENABLED(DWIN_CREALITY_LCD)
int16_t (&ui_preheat_hotend_temp)[2] = HMI_ValueStruct.preheat_hotend_temp,
(&ui_preheat_bed_temp)[2] = HMI_ValueStruct.preheat_bed_temp;
uint8_t (&ui_preheat_fan_speed)[2] = HMI_ValueStruct.preheat_fan_speed;
#else
int16_t ui_preheat_hotend_temp[2], ui_preheat_bed_temp[2];
uint8_t ui_preheat_fan_speed[2];
#endif
@ -2539,14 +2552,22 @@ void MarlinSettings::reset() {
//
// Preheat parameters
//
#if HAS_HOTEND && HAS_LCD_MENU
ui.preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND;
ui.preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND;
ui.preheat_bed_temp[0] = PREHEAT_1_TEMP_BED;
ui.preheat_bed_temp[1] = PREHEAT_2_TEMP_BED;
ui.preheat_fan_speed[0] = PREHEAT_1_FAN_SPEED;
ui.preheat_fan_speed[1] = PREHEAT_2_FAN_SPEED;
#if HAS_HOTEND
#if ENABLED(DWIN_CREALITY_LCD)
HMI_ValueStruct.preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND;
HMI_ValueStruct.preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND;
HMI_ValueStruct.preheat_bed_temp[0] = PREHEAT_1_TEMP_BED;
HMI_ValueStruct.preheat_bed_temp[1] = PREHEAT_2_TEMP_BED;
HMI_ValueStruct.preheat_fan_speed[0] = PREHEAT_1_FAN_SPEED;
HMI_ValueStruct.preheat_fan_speed[1] = PREHEAT_2_FAN_SPEED;
#elif HAS_LCD_MENU
ui.preheat_hotend_temp[0] = PREHEAT_1_TEMP_HOTEND;
ui.preheat_hotend_temp[1] = PREHEAT_2_TEMP_HOTEND;
ui.preheat_bed_temp[0] = PREHEAT_1_TEMP_BED;
ui.preheat_bed_temp[1] = PREHEAT_2_TEMP_BED;
ui.preheat_fan_speed[0] = PREHEAT_1_FAN_SPEED;
ui.preheat_fan_speed[1] = PREHEAT_2_FAN_SPEED;
#endif
#endif
//

View file

@ -32,6 +32,11 @@
#include "../HAL/shared/Delay.h"
#include "../lcd/ultralcd.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/dwin/dwin.h"
#endif
#if ENABLED(EXTENSIBLE_UI)
#include "../lcd/extui/ui_api.h"
#endif
@ -560,6 +565,7 @@ volatile bool Temperature::raw_temps_ready = false;
#define MAX_CYCLE_TIME_PID_AUTOTUNE 20L
#endif
if (((ms - t1) + (ms - t2)) > (MAX_CYCLE_TIME_PID_AUTOTUNE * 60L * 1000L)) {
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0));
TERN_(EXTENSIBLE_UI, ExtUI::onPidTuning(ExtUI::result_t::PID_TUNING_TIMEOUT));
SERIAL_ECHOLNPGM(STR_PID_TIMEOUT);
break;
@ -612,7 +618,7 @@ volatile bool Temperature::raw_temps_ready = false;
goto EXIT_M303;
}
ui.update();
TERN(DWIN_CREALITY_LCD, DWIN_Update(), ui.update());
}
disable_all_heaters();
@ -794,10 +800,12 @@ void Temperature::_temp_error(const heater_ind_t heater, PGM_P const serial_msg,
}
void Temperature::max_temp_error(const heater_ind_t heater) {
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(1));
_temp_error(heater, PSTR(STR_T_MAXTEMP), GET_TEXT(MSG_ERR_MAXTEMP));
}
void Temperature::min_temp_error(const heater_ind_t heater) {
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0));
_temp_error(heater, PSTR(STR_T_MINTEMP), GET_TEXT(MSG_ERR_MINTEMP));
}
@ -1029,8 +1037,10 @@ void Temperature::manage_heater() {
#if WATCH_HOTENDS
// Make sure temperature is increasing
if (watch_hotend[e].next_ms && ELAPSED(ms, watch_hotend[e].next_ms)) { // Time to check this extruder?
if (degHotend(e) < watch_hotend[e].target) // Failed to increase enough?
if (degHotend(e) < watch_hotend[e].target) { // Failed to increase enough?
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0));
_temp_error((heater_ind_t)e, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD));
}
else // Start again if the target is still far off
start_watching_hotend(e);
}
@ -1071,8 +1081,10 @@ void Temperature::manage_heater() {
#if WATCH_BED
// Make sure temperature is increasing
if (watch_bed.elapsed(ms)) { // Time to check the bed?
if (degBed() < watch_bed.target) // Failed to increase enough?
if (degBed() < watch_bed.target) { // Failed to increase enough?
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0));
_temp_error(H_BED, str_t_heating_failed, GET_TEXT(MSG_HEATING_FAILED_LCD));
}
else // Start again if the target is still far off
start_watching_bed();
}
@ -1981,6 +1993,7 @@ void Temperature::init() {
sm.state = TRRunaway;
case TRRunaway:
TERN_(DWIN_CREALITY_LCD, Popup_Window_Temperature(0));
_temp_error(heater_id, str_t_thermal_runaway, GET_TEXT(MSG_THERMAL_RUNAWAY));
}
}
@ -3082,7 +3095,13 @@ void Temperature::tick() {
} while (wait_for_heatup && TEMP_CONDITIONS);
if (wait_for_heatup) {
ui.reset_status();
#if ENABLED(DWIN_CREALITY_LCD)
HMI_flag.heat_flag = 0;
duration_t elapsed = print_job_timer.duration(); // print timer
heat_time = elapsed.value;
#else
ui.reset_status();
#endif
TERN_(PRINTER_EVENT_LEDS, printerEventLEDs.onHeatingDone());
}

View file

@ -544,6 +544,8 @@
#include "stm32f1/pins_CHITU3D_V5.h" // STM32F1 env:chitu_f103 env:chitu_v5_gpio_init
#elif MB(CHITU3D_V6)
#include "stm32f1/pins_CHITU3D_V6.h" // STM32F1 env:chitu_f103
#elif MB(CREALITY_V4)
#include "stm32f1/pins_CREALITY_V4.h" // STM32F1 env:STM32F103RET6_creality
//
// ARM Cortex-M4F

View file

@ -201,7 +201,7 @@
#define MOSI_PIN PA7
#define SS_PIN PA4
#endif
#define ON_BOARD_SPI_DEVICE 1 //SPI1
#define ON_BOARD_SPI_DEVICE 1 // SPI1
#define ONBOARD_SD_CS_PIN PA4 // Chip select for "System" SD card
#if HAS_GRAPHICAL_LCD

View file

@ -0,0 +1,167 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 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/>.
*
*/
/**
* CREALITY (STM32F103) board pin assignments
*/
#ifndef __STM32F1__
#error "Oops! Select an STM32F1 board in 'Tools > Board.'"
#endif
#if HOTENDS > 1 || E_STEPPERS > 1
#error "CREALITY supports up to 1 hotends / E-steppers. Comment out this line to continue."
#endif
#define BOARD_INFO_NAME "CREALITY V4"
#define DEFAULT_MACHINE_NAME "Ender 3 V2"
//
// EEPROM
//
/* I2C */
#define IIC_BL24CXX_EEPROM // EEPROM on I2C-0
//#define E2END 0x3FFF // 16Kb (24c16)
#define IIC_EEPROM_SDA PA11
#define IIC_EEPROM_SCL PA12
// SD EEPROM was in your original build, so...
#define SDCARD_EEPROM_EMULATION
/* SPI */
//#define SPI_EEPROM // EEPROM on SPI-0
//#define SPI_CHAN_EEPROM1 ?
//#define SPI_EEPROM1_CS ?
// 2K EEPROM
//#define SPI_EEPROM2_CS ?
// 32Mb FLASH
//#define SPI_FLASH_CS ?
/* FLASH */
//#define FLASH_EEPROM_EMULATION
//
// Servos
//
#define SERVO0_PIN PB0 // BLTouch OUT
//
// Limit Switches
//
#define X_STOP_PIN PA5
#define Y_STOP_PIN PA6
#define Z_STOP_PIN PA7
#define Z_PROBE_PIN PB1 // BLTouch IN
//
// Steppers
//
#define X_ENABLE_PIN PC3
#define X_STEP_PIN PC2
#define X_DIR_PIN PB9
#define Y_ENABLE_PIN PC3
#define Y_STEP_PIN PB8
#define Y_DIR_PIN PB7
#define Z_ENABLE_PIN PC3
#define Z_STEP_PIN PB6
#define Z_DIR_PIN PB5
#define E0_ENABLE_PIN PC3
#define E0_STEP_PIN PB4
#define E0_DIR_PIN PB3
//
// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role
//
#define DISABLE_DEBUG
//
// Temperature Sensors
//
#define TEMP_0_PIN PC5 // TH1
#define TEMP_BED_PIN PC4 // TB1
//
// Heaters / Fans
//
#define HEATER_0_PIN PA1 // HEATER1
#define HEATER_BED_PIN PA2 // HOT BED
#define FAN_PIN PA0 // FAN
#define FAN_SOFT_PWM
//
// SD Card
//
#define SD_DETECT_PIN PC7
#define SDCARD_CONNECTION ONBOARD
#define ON_BOARD_SPI_DEVICE 1
#define ONBOARD_SD_CS_PIN PA4 // SDSS
#define SDIO_SUPPORT
#if ENABLED(RET6_12864_LCD)
/* RET6 12864 LCD */
#define LCD_PINS_RS PB12
#define LCD_PINS_ENABLE PB15
#define LCD_PINS_D4 PB13
#define BTN_ENC PB2
#define BTN_EN1 PB10
#define BTN_EN2 PB14
#define BEEPER_PIN PC6
#elif ENABLED(VET6_12864_LCD)
/* VET6 12864 LCD */
#define LCD_PINS_RS PA4
#define LCD_PINS_ENABLE PA7
#define LCD_PINS_D4 PA5
#define BTN_ENC PC5
#define BTN_EN1 PB10
#define BTN_EN2 PA6
#elif ENABLED(DWIN_CREALITY_LCD)
/* RET6 DWIN ENCODER LCD */
#define BTN_ENC PB14
#define BTN_EN1 PB15
#define BTN_EN2 PB12
//#define LCD_LED_PIN PB2
#define BEEPER_PIN PB13
#elif ENABLED(DWIN_VET6_CREALITY_LCD)
/* VET6 DWIN ENCODER LCD */
#define BTN_ENC PA6
#define BTN_EN1 PA7
#define BTN_EN2 PA4
#define BEEPER_PIN PA5
#endif

View file

@ -28,6 +28,11 @@
#include "../MarlinCore.h"
#include "../lcd/ultralcd.h"
#if ENABLED(DWIN_CREALITY_LCD)
#include "../lcd/dwin/dwin.h"
#endif
#include "../module/planner.h" // for synchronize
#include "../module/printcounter.h"
#include "../gcode/queue.h"
@ -385,7 +390,11 @@ void CardReader::mount() {
void CardReader::manage_media() {
static uint8_t prev_stat = TERN(INIT_SDCARD_ON_BOOT, 2, 0);
uint8_t stat = uint8_t(IS_SD_INSERTED());
if (stat != prev_stat && ui.detected()) {
if (stat == prev_stat) return;
flag.workDirIsRoot = true; // Return to root on mount/release
if (ui.detected()) {
uint8_t old_stat = prev_stat;
prev_stat = stat; // Change now to prevent re-entry
@ -420,6 +429,8 @@ void CardReader::manage_media() {
void CardReader::release() {
endFilePrint();
flag.mounted = false;
flag.workDirIsRoot = true;
nrFiles = 0;
}
void CardReader::openAndPrintFile(const char *name) {
@ -440,6 +451,7 @@ void CardReader::startFileprint() {
void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0);
TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting);
flag.sdprinting = flag.abort_sd_printing = false;
if (isFileOpen()) file.close();
TERN_(SD_RESORT, if (re_sort) presort());
@ -944,7 +956,7 @@ void CardReader::cdroot() {
#if HAS_FOLDER_SORTING
const uint16_t bit = i & 0x07, ind = i >> 3;
if (bit == 0) isDir[ind] = 0x00;
if (flag.filenameIsDir) isDir[ind] |= _BV(bit);
if (flag.filenameIsDir) SBI(isDir[ind], bit);
#endif
#endif
}
@ -972,7 +984,7 @@ void CardReader::cdroot() {
#if HAS_FOLDER_SORTING
#if ENABLED(SDSORT_USES_RAM)
// Folder sorting needs an index and bit to test for folder-ness.
#define _SORT_CMP_DIR(fs) IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_NODIR() : IS_DIR(fs > 0 ? o1 : o2)
#define _SORT_CMP_DIR(fs) (IS_DIR(o1) == IS_DIR(o2) ? _SORT_CMP_NODIR() : IS_DIR(fs > 0 ? o1 : o2))
#else
#define _SORT_CMP_DIR(fs) ((dir1 == flag.filenameIsDir) ? _SORT_CMP_NODIR() : (fs > 0 ? dir1 : !dir1))
#endif
@ -1062,13 +1074,14 @@ void CardReader::cdroot() {
#endif // SDCARD_SORT_ALPHA
uint16_t CardReader::get_num_Files() {
return
#if ENABLED(SDCARD_SORT_ALPHA) && SDSORT_USES_RAM && SDSORT_CACHE_NAMES
if (!isMounted()) return 0;
return (
#if ALL(SDCARD_SORT_ALPHA, SDSORT_USES_RAM, SDSORT_CACHE_NAMES)
nrFiles // no need to access the SD card for filenames
#else
countFilesInWorkDir()
#endif
;
);
}
//
@ -1084,9 +1097,7 @@ void CardReader::fileHasFinished() {
startFileprint();
}
else {
endFilePrint();
TERN_(SDCARD_SORT_ALPHA, presort());
endFilePrint(TERN_(SD_RESORT, true));
marlin_state = MF_SD_COMPLETE;
}

View file

@ -152,6 +152,7 @@ public:
static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
static inline uint32_t getIndex() { return sdpos; }
static inline uint32_t getFileSize() { return filesize; }
static inline bool eof() { return sdpos >= filesize; }
static inline void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); }
static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; }

View file

@ -0,0 +1,14 @@
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - 40
rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE common.inc

View file

@ -0,0 +1,16 @@
import os
Import("env")
# Relocate firmware from 0x08000000 to 0x08007000
for define in env['CPPDEFINES']:
if define[0] == "VECT_TAB_ADDR":
env['CPPDEFINES'].remove(define)
env['CPPDEFINES'].append(("VECT_TAB_ADDR", "0x08007000"))
custom_ld_script = os.path.abspath("buildroot/share/PlatformIO/ldscripts/creality.ld")
for i, flag in enumerate(env["LINKFLAGS"]):
if "-Wl,-T" in flag:
env["LINKFLAGS"][i] = "-Wl,-T" + custom_ld_script
elif flag == "-T":
env["LINKFLAGS"][i + 1] = custom_ld_script

View file

@ -0,0 +1,15 @@
#!/usr/bin/env bash
#
# Build tests for STM32F103RET6_creality
#
# exit on first failure
set -e
#
# Build with configs included in the PR
#
use_example_configs "Creality/Ender-3 V2"
exec_test $1 $2 "Ender 3 v2"
restore_configs

View file

@ -689,6 +689,22 @@ platform = ${common_stm32f1.platform}
extends = env:chitu_f103
build_flags = ${env:chitu_f103.build_flags} -DCHITU_V5_Z_MIN_BUGFIX
#
# Creality (STM32F103RET6)
#
[env:STM32F103RET6_creality]
platform = ${common_stm32f1.platform}
extends = common_stm32f1
board = genericSTM32F103RC
build_flags = !python Marlin/src/HAL/STM32F1/build_flags.py
${common.build_flags} -std=gnu++14 -DSTM32_XL_DENSITY -DTEMP_TIMER_CHAN=4
extra_scripts = buildroot/share/PlatformIO/scripts/creality.py
lib_ignore = ${common_stm32f1.lib_ignore}
LiquidCrystal, LiquidTWI2, U8glib-HAL, Adafruit_MAX31865, Arduino-L6470, SailfishLCD, SlowSoftI2CMaster
debug_tool = jlink
upload_protocol = jlink
monitor_speed = 115200
#
# STM32F401VE
# 'STEVAL-3DP001V1' STM32F401VE board - https://www.st.com/en/evaluation-tools/steval-3dp001v1.html