From 6713185aea9e5550fc8961d15693fcac21261518 Mon Sep 17 00:00:00 2001 From: InsanityAutomation Date: Sun, 14 Jan 2024 15:35:57 -0500 Subject: [PATCH] LPC4078 Initial Commit Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com> --- Marlin/Configuration.h | 118 ++-- Marlin/src/HAL/LPC4078/HAL.cpp | 125 ++++ Marlin/src/HAL/LPC4078/HAL.h | 267 ++++++++ Marlin/src/HAL/LPC4078/HAL_SPI.cpp | 404 ++++++++++++ Marlin/src/HAL/LPC4078/MarlinSPI.h | 45 ++ Marlin/src/HAL/LPC4078/MarlinSerial.cpp | 78 +++ Marlin/src/HAL/LPC4078/MarlinSerial.h | 108 ++++ Marlin/src/HAL/LPC4078/MinSerial.cpp | 51 ++ Marlin/src/HAL/LPC4078/Servo.h | 69 ++ Marlin/src/HAL/LPC4078/SoftwareSPI.cpp | 47 ++ Marlin/src/HAL/LPC4078/SoftwareSPI.h | 5 + Marlin/src/HAL/LPC4078/eeprom_internal.cpp | 116 ++++ Marlin/src/HAL/LPC4078/endstop_interrupts.h | 191 ++++++ Marlin/src/HAL/LPC4078/fast_pwm.cpp | 37 ++ Marlin/src/HAL/LPC4078/fastio.h | 120 ++++ Marlin/src/HAL/LPC4078/inc/Conditionals_LCD.h | 22 + Marlin/src/HAL/LPC4078/inc/Conditionals_adv.h | 26 + .../src/HAL/LPC4078/inc/Conditionals_post.h | 34 + Marlin/src/HAL/LPC4078/inc/SanityCheck.h | 276 ++++++++ Marlin/src/HAL/LPC4078/include/SPI.h | 197 ++++++ Marlin/src/HAL/LPC4078/main.cpp | 111 ++++ Marlin/src/HAL/LPC4078/pinsDebug.h | 57 ++ Marlin/src/HAL/LPC4078/spi_pins.h | 54 ++ Marlin/src/HAL/LPC4078/timers.cpp | 65 ++ Marlin/src/HAL/LPC4078/timers.h | 165 +++++ .../src/HAL/LPC4078/u8g/LCD_I2C_routines.cpp | 89 +++ Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.h | 28 + Marlin/src/HAL/LPC4078/u8g/LCD_defines.h | 46 ++ Marlin/src/HAL/LPC4078/u8g/LCD_delay.h | 43 ++ .../src/HAL/LPC4078/u8g/LCD_pin_routines.cpp | 59 ++ Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.h | 37 ++ .../u8g/u8g_com_HAL_LPC1768_hw_spi.cpp | 129 ++++ .../u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp | 198 ++++++ .../u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp | 138 ++++ .../u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp | 147 +++++ .../u8g/u8g_com_HAL_LPC1768_sw_spi.cpp | 209 ++++++ Marlin/src/HAL/platforms.h | 2 + Marlin/src/HAL/shared/servo.h | 2 + Marlin/src/core/boards.h | 1 + Marlin/src/pins/lpc4078/pins_EBAB.h | 605 ++++++++++++++++++ Marlin/src/pins/pins.h | 7 + ini/lpc176x.ini | 24 + 42 files changed, 4493 insertions(+), 59 deletions(-) create mode 100644 Marlin/src/HAL/LPC4078/HAL.cpp create mode 100644 Marlin/src/HAL/LPC4078/HAL.h create mode 100644 Marlin/src/HAL/LPC4078/HAL_SPI.cpp create mode 100644 Marlin/src/HAL/LPC4078/MarlinSPI.h create mode 100644 Marlin/src/HAL/LPC4078/MarlinSerial.cpp create mode 100644 Marlin/src/HAL/LPC4078/MarlinSerial.h create mode 100644 Marlin/src/HAL/LPC4078/MinSerial.cpp create mode 100644 Marlin/src/HAL/LPC4078/Servo.h create mode 100644 Marlin/src/HAL/LPC4078/SoftwareSPI.cpp create mode 100644 Marlin/src/HAL/LPC4078/SoftwareSPI.h create mode 100644 Marlin/src/HAL/LPC4078/eeprom_internal.cpp create mode 100644 Marlin/src/HAL/LPC4078/endstop_interrupts.h create mode 100644 Marlin/src/HAL/LPC4078/fast_pwm.cpp create mode 100644 Marlin/src/HAL/LPC4078/fastio.h create mode 100644 Marlin/src/HAL/LPC4078/inc/Conditionals_LCD.h create mode 100644 Marlin/src/HAL/LPC4078/inc/Conditionals_adv.h create mode 100644 Marlin/src/HAL/LPC4078/inc/Conditionals_post.h create mode 100644 Marlin/src/HAL/LPC4078/inc/SanityCheck.h create mode 100644 Marlin/src/HAL/LPC4078/include/SPI.h create mode 100644 Marlin/src/HAL/LPC4078/main.cpp create mode 100644 Marlin/src/HAL/LPC4078/pinsDebug.h create mode 100644 Marlin/src/HAL/LPC4078/spi_pins.h create mode 100644 Marlin/src/HAL/LPC4078/timers.cpp create mode 100644 Marlin/src/HAL/LPC4078/timers.h create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.h create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_defines.h create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_delay.h create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.h create mode 100644 Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp create mode 100644 Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp create mode 100644 Marlin/src/pins/lpc4078/pins_EBAB.h diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h index f88f5b9dbd..47be4f97a9 100644 --- a/Marlin/Configuration.h +++ b/Marlin/Configuration.h @@ -61,14 +61,14 @@ // @section info // Author info of this build printed to the host during boot and M115 -#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes. +#define STRING_CONFIG_H_AUTHOR "InsanityAutomation" // Who made the changes. //#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes) // @section machine // Choose the name from boards.h that matches your setup #ifndef MOTHERBOARD - #define MOTHERBOARD BOARD_RAMPS_14_EFB + #define MOTHERBOARD BOARD_EBAB #endif /** @@ -79,7 +79,7 @@ * * :[-1, 0, 1, 2, 3, 4, 5, 6, 7] */ -#define SERIAL_PORT 0 +#define SERIAL_PORT -1 /** * Serial Port Baud Rate @@ -101,7 +101,7 @@ * Currently Ethernet (-2) is only supported on Teensy 4.1 boards. * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] */ -//#define SERIAL_PORT_2 -1 +#define SERIAL_PORT_2 0 //#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE /** @@ -116,7 +116,7 @@ //#define BLUETOOTH // Name displayed in the LCD "Ready" message and Info menu -//#define CUSTOM_MACHINE_NAME "3D Printer" +#define CUSTOM_MACHINE_NAME "FatBoy" // Printer's unique ID, used by some programs to differentiate between machines. // Choose your own or use a service like https://www.uuidgenerator.net/version4 @@ -139,21 +139,21 @@ * TMC5160, TMC5160_STANDALONE * :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE'] */ -#define X_DRIVER_TYPE A4988 -#define Y_DRIVER_TYPE A4988 -#define Z_DRIVER_TYPE A4988 +#define X_DRIVER_TYPE TB6560 +#define Y_DRIVER_TYPE TB6560 +#define Z_DRIVER_TYPE TB6560 //#define X2_DRIVER_TYPE A4988 -//#define Y2_DRIVER_TYPE A4988 -//#define Z2_DRIVER_TYPE A4988 -//#define Z3_DRIVER_TYPE A4988 -//#define Z4_DRIVER_TYPE A4988 +#define Y2_DRIVER_TYPE TB6560 +#define Z2_DRIVER_TYPE TB6560 +#define Z3_DRIVER_TYPE TB6560 +#define Z4_DRIVER_TYPE TB6560 //#define I_DRIVER_TYPE A4988 //#define J_DRIVER_TYPE A4988 //#define K_DRIVER_TYPE A4988 //#define U_DRIVER_TYPE A4988 //#define V_DRIVER_TYPE A4988 //#define W_DRIVER_TYPE A4988 -#define E0_DRIVER_TYPE A4988 +#define E0_DRIVER_TYPE TMC2209 //#define E1_DRIVER_TYPE A4988 //#define E2_DRIVER_TYPE A4988 //#define E3_DRIVER_TYPE A4988 @@ -561,7 +561,7 @@ #define TEMP_SENSOR_5 0 #define TEMP_SENSOR_6 0 #define TEMP_SENSOR_7 0 -#define TEMP_SENSOR_BED 1 +#define TEMP_SENSOR_BED 11 #define TEMP_SENSOR_PROBE 0 #define TEMP_SENSOR_CHAMBER 0 #define TEMP_SENSOR_COOLER 0 @@ -637,7 +637,7 @@ // Above this temperature the heater will be switched off. // This can protect components from overheating, but NOT from shorts and failures. // (Use MINTEMP for thermistor short/failure protection.) -#define HEATER_0_MAXTEMP 275 +#define HEATER_0_MAXTEMP 300 #define HEATER_1_MAXTEMP 275 #define HEATER_2_MAXTEMP 275 #define HEATER_3_MAXTEMP 275 @@ -645,7 +645,7 @@ #define HEATER_5_MAXTEMP 275 #define HEATER_6_MAXTEMP 275 #define HEATER_7_MAXTEMP 275 -#define BED_MAXTEMP 150 +#define BED_MAXTEMP 120 #define CHAMBER_MAXTEMP 60 /** @@ -654,7 +654,7 @@ * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP. */ -#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT +#define HOTEND_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT #define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT #define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT @@ -757,7 +757,7 @@ * When set to any value below 255, enables a form of PWM to the bed that acts like a divider * so don't use it unless you are OK with PWM on your bed. (See the comment on enabling PIDTEMPBED) */ -#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current +#define MAX_BED_POWER 180 // limits duty cycle to bed; 255=full current /** * PID Bed Heating @@ -771,7 +771,7 @@ * * With this option disabled, bang-bang will be used. BED_LIMIT_SWITCHING enables hysteresis. */ -//#define PIDTEMPBED +#define PIDTEMPBED #if ENABLED(PIDTEMPBED) //#define MIN_BED_POWER 0 @@ -842,8 +842,8 @@ #define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature // is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max. - //#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) - //#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) + #define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash) + #define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash) #endif // @section safety @@ -1236,7 +1236,7 @@ * Override with M92 (when enabled below) * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] */ -#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 } +#define DEFAULT_AXIS_STEPS_PER_UNIT { 40, 40, 200, 425 } /** * Enable support for M92. Disable to save at least ~530 bytes of flash. @@ -1261,7 +1261,7 @@ * Override with M201 * X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]] */ -#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 } +#define DEFAULT_MAX_ACCELERATION { 12000, 12000, 500, 10000 } //#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2 #if ENABLED(LIMITED_MAX_ACCEL_EDITING) @@ -1276,9 +1276,9 @@ * M204 R Retract Acceleration * M204 T Travel Acceleration */ -#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves +#define DEFAULT_ACCELERATION 7000 // X, Y, Z and E acceleration for printing moves #define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts -#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves +#define DEFAULT_TRAVEL_ACCELERATION 7000 // X, Y, Z acceleration for travel (non printing) moves /** * Default Jerk limits (mm/s) @@ -1330,7 +1330,7 @@ * * See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained */ -//#define S_CURVE_ACCELERATION +#define S_CURVE_ACCELERATION //=========================================================================== //============================= Z Probe Options ============================= @@ -1346,10 +1346,10 @@ * The probe replaces the Z-MIN endstop and is used for Z homing. * (Automatically enables USE_PROBE_FOR_Z_HOMING.) */ -#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN +//#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN // Force the use of the probe for Z-axis homing -//#define USE_PROBE_FOR_Z_HOMING +#define USE_PROBE_FOR_Z_HOMING /** * Z_MIN_PROBE_PIN @@ -1406,7 +1406,7 @@ /** * The BLTouch probe uses a Hall effect sensor and emulates a servo. */ -//#define BLTOUCH +#define BLTOUCH /** * MagLev V4 probe by MDD @@ -1647,7 +1647,7 @@ * A total of 2 does fast/slow probes with a weighted average. * A total of 3 or more adds more slow probes, taking the average. */ -//#define MULTIPLE_PROBING 2 +#define MULTIPLE_PROBING 2 //#define EXTRA_PROBING 1 /** @@ -1670,7 +1670,7 @@ #define Z_PROBE_ERROR_TOLERANCE 3 // (mm) Tolerance for early trigger (<= -probe.offset.z + ZPET) //#define Z_AFTER_PROBING 5 // (mm) Z position after probing is done -#define Z_PROBE_LOW_POINT -2 // (mm) Farthest distance below the trigger-point to go before stopping +#define Z_PROBE_LOW_POINT -5 // (mm) Farthest distance below the trigger-point to go before stopping // For M851 provide ranges for adjusting the X, Y, and Z probe offsets //#define PROBE_OFFSET_XMIN -50 // (mm) @@ -1749,9 +1749,9 @@ // @section motion // Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way. -#define INVERT_X_DIR false -#define INVERT_Y_DIR true -#define INVERT_Z_DIR false +#define INVERT_X_DIR true +#define INVERT_Y_DIR false +#define INVERT_Z_DIR true //#define INVERT_I_DIR false //#define INVERT_J_DIR false //#define INVERT_K_DIR false @@ -1821,8 +1821,8 @@ // @section geometry // The size of the printable area -#define X_BED_SIZE 200 -#define Y_BED_SIZE 200 +#define X_BED_SIZE 1200 +#define Y_BED_SIZE 1200 // Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions. #define X_MIN_POS 0 @@ -1830,7 +1830,7 @@ #define Z_MIN_POS 0 #define X_MAX_POS X_BED_SIZE #define Y_MAX_POS Y_BED_SIZE -#define Z_MAX_POS 200 +#define Z_MAX_POS 1000 //#define I_MIN_POS 0 //#define I_MAX_POS 50 //#define J_MIN_POS 0 @@ -1882,7 +1882,7 @@ #endif #if ANY(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS) - //#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD + #define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD #endif /** @@ -2041,7 +2041,7 @@ */ //#define AUTO_BED_LEVELING_3POINT //#define AUTO_BED_LEVELING_LINEAR -//#define AUTO_BED_LEVELING_BILINEAR +#define AUTO_BED_LEVELING_BILINEAR //#define AUTO_BED_LEVELING_UBL //#define MESH_BED_LEVELING @@ -2049,14 +2049,14 @@ * Commands to execute at the end of G29 probing. * Useful to retract or move the Z probe out of the way. */ -//#define EVENT_GCODE_AFTER_G29 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" +//#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10" /** * Normally G28 leaves leveling disabled on completion. Enable one of * these options to restore the prior leveling state or to always enable * leveling immediately after G28. */ -//#define RESTORE_LEVELING_AFTER_G28 +#define RESTORE_LEVELING_AFTER_G28 //#define ENABLE_LEVELING_AFTER_G28 /** @@ -2071,7 +2071,7 @@ /** * Enable detailed logging of G28, G29, M48, etc. * Turn on with the command 'M111 S32'. - * NOTE: Requires a lot of flash! + * NOTE: Requires a lot of PROGMEM! */ //#define DEBUG_LEVELING_FEATURE @@ -2088,7 +2088,7 @@ */ #define ENABLE_LEVELING_FADE_HEIGHT #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT) - #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height. + #define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height. #endif /** @@ -2102,7 +2102,7 @@ /** * Enable the G26 Mesh Validation Pattern tool. */ - //#define G26_MESH_VALIDATION + #define G26_MESH_VALIDATION #if ENABLED(G26_MESH_VALIDATION) #define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle. #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26. @@ -2118,7 +2118,7 @@ #if ANY(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR) // Set the number of grid points per dimension. - #define GRID_MAX_POINTS_X 3 + #define GRID_MAX_POINTS_X 15 #define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X // Probe along the Y axis, advancing X after each column @@ -2128,7 +2128,7 @@ // Beyond the probed grid, continue the implied tilt? // Default is to maintain the height of the nearest edge. - //#define EXTRAPOLATE_BEYOND_GRID + #define EXTRAPOLATE_BEYOND_GRID // // Subdivision of the grid by Catmull-Rom method. @@ -2204,12 +2204,12 @@ * Add a bed leveling sub-menu for ABL or MBL. * Include a guided procedure if manual probing is enabled. */ -//#define LCD_BED_LEVELING +#define LCD_BED_LEVELING #if ENABLED(LCD_BED_LEVELING) #define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis. - #define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment - //#define MESH_EDIT_MENU // Add a menu to edit mesh points + #define LCD_PROBE_Z_RANGE 8 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment + #define MESH_EDIT_MENU // Add a menu to edit mesh points #endif // Add a menu item to move between bed corners for manual bed adjustment @@ -2271,7 +2271,7 @@ * - Allows Z homing only when XY positions are known and trusted. * - If stepper drivers sleep, XY homing may be required again before Z homing. */ -//#define Z_SAFE_HOMING +#define Z_SAFE_HOMING #if ENABLED(Z_SAFE_HOMING) #define Z_SAFE_HOMING_X_POINT X_CENTER // (mm) X point for Z homing @@ -2358,12 +2358,12 @@ * M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes) * M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.) */ -//#define EEPROM_SETTINGS // Persistent storage with M500 and M501 +#define EEPROM_SETTINGS // Persistent storage with M500 and M501 //#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release! -#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save flash. +#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM. #define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load #if ENABLED(EEPROM_SETTINGS) - //#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. + #define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors. //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build. #endif @@ -2421,11 +2421,11 @@ * P1 Raise the nozzle always to Z-park height. * P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS. */ -//#define NOZZLE_PARK_FEATURE +#define NOZZLE_PARK_FEATURE #if ENABLED(NOZZLE_PARK_FEATURE) // Specify a park position as { X, Y, Z_raise } - #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 } + #define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MIN_POS + 10), 5 } #define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X #define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance #define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis) @@ -2648,7 +2648,7 @@ * SD Card support is disabled by default. If your controller has an SD slot, * you must uncomment the following option or it won't work. */ -//#define SDSUPPORT +#define SDSUPPORT /** * SD CARD: ENABLE CRC @@ -2728,7 +2728,7 @@ // // Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu. // -//#define INDIVIDUAL_AXIS_HOMING_MENU +#define INDIVIDUAL_AXIS_HOMING_MENU //#define INDIVIDUAL_AXIS_HOMING_SUBMENU // @@ -2737,7 +2737,7 @@ // If you have a speaker that can produce tones, enable it here. // By default Marlin assumes you have a buzzer with a fixed frequency. // -//#define SPEAKER +#define SPEAKER // // The duration and frequency for the UI feedback sound. @@ -2931,7 +2931,7 @@ // RepRapDiscount FULL GRAPHIC Smart Controller // https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller // -//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER +#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER // // K.3D Full Graphic Smart Controller diff --git a/Marlin/src/HAL/LPC4078/HAL.cpp b/Marlin/src/HAL/LPC4078/HAL.cpp new file mode 100644 index 0000000000..3cdf636480 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/HAL.cpp @@ -0,0 +1,125 @@ +/** + * 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 . + * + */ +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" +#include "../shared/Delay.h" +#include "../../../gcode/parser.h" + +DefaultSerial1 USBSerial(false, MCDCSerial0); + +uint32_t MarlinHAL::adc_result = 0; + +// U8glib required functions +extern "C" { + void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); } + void u8g_MicroDelay() { u8g_xMicroDelay(1); } + void u8g_10MicroDelay() { u8g_xMicroDelay(10); } + void u8g_Delay(uint16_t val) { delay(val); } +} + +// return free heap space +int freeMemory() { + char stack_end; + void *heap_start = malloc(sizeof(uint32_t)); + if (heap_start == 0) return 0; + + uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start; + free(heap_start); + return result; +} + +void MarlinHAL::reboot() { MCUCore::nvic_system_reset(); } + +uint8_t MarlinHAL::get_reset_source() { + #if ENABLED(USE_WATCHDOG) + if (watchdog_timed_out()) return RST_WATCHDOG; + #endif + return RST_POWER_ON; +} + +void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); } + +void flashFirmware(const int16_t) { + delay(500); // Give OS time to disconnect + //USB_Connect(false); // USB clear connection + delay(1000); // Give OS time to notice + hal.reboot(); +} + +#if ENABLED(USE_WATCHDOG) + + #define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8.0f, 4.0f) // 4 or 8 second timeout + + void MarlinHAL::watchdog_init() { + #if ENABLED(WATCHDOG_RESET_MANUAL) + // We enable the watchdog timer, but only for the interrupt. + + // Configure WDT to only trigger an interrupt + // Disable WDT interrupt (just in case, to avoid triggering it!) + NVIC_DisableIRQ(WDT_IRQn); + + // We NEED memory barriers to ensure Interrupts are actually disabled! + // ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the ) + __DSB(); + __ISB(); + + // WDT defaults to trigger an interrupt + + // Configure and enable WDT interrupt. + NVIC_ClearPendingIRQ(WDT_IRQn); + NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups + NVIC_EnableIRQ(WDT_IRQn); + #else + MCUI::watchdog_set_timeout_triggers_reset(); + #endif + MCUI::watchdog_set_timeout_in_seconds(WDT_TIMEOUT); + MCUI::watchdog_enable(); + } + + void MarlinHAL::watchdog_refresh() { + MCUI::watchdog_feed(); + #if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED) + static millis_t next_flash = millis(); + if (ELAPSED(millis(), next_flash)) { + next_flash = millis() + 200; + TOGGLE(LED_PIN); // heartbeat indicator + } + #endif + } + + // Timeout state + bool MarlinHAL::watchdog_timed_out() { return MCUI::watchdog_has_triggered(); } + void MarlinHAL::watchdog_clear_timeout_flag() { MCUI::watchdog_clear_timeout_flag(); } + +#endif // USE_WATCHDOG + +// For M42/M43, scan command line for pin code +// return index into pin map array if found and the pin is valid. +// return dval if not found or not a valid pin. +int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) { + const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100; + const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2; + return ind > -1 ? ind : dval; +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/HAL.h b/Marlin/src/HAL/LPC4078/HAL.h new file mode 100644 index 0000000000..c4803909a7 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/HAL.h @@ -0,0 +1,267 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * 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 . + * + */ +#pragma once + +/** + * HAL_LPC1768/HAL.h + * Hardware Abstraction Layer for NXP LPC1768 + */ + +#define CPU_32_BIT + +#include +#include +#include + +#include "../shared/Marduino.h" +#include "../shared/Delay.h" +#include "../shared/math_32bit.h" +#include "../shared/HAL_SPI.h" +#include "fastio.h" +#include "MarlinSerial.h" + +#include + +// ------------------------ +// Serial ports +// ------------------------ + +typedef ForwardSerial1Class< decltype(MCDCSerial0) > DefaultSerial1; +extern DefaultSerial1 USBSerial; + +#define _MSERIAL(X) MSerial##X +#define MSERIAL(X) _MSERIAL(X) + +#if SERIAL_PORT == -1 + #define MYSERIAL1 USBSerial +#elif WITHIN(SERIAL_PORT, 0, 3) + #define MYSERIAL1 MSERIAL(SERIAL_PORT) +#else + #error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." +#endif + +#ifdef SERIAL_PORT_2 + #if SERIAL_PORT_2 == -1 + #define MYSERIAL2 USBSerial + #elif WITHIN(SERIAL_PORT_2, 0, 3) + #define MYSERIAL2 MSERIAL(SERIAL_PORT_2) + #else + #error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB." + #endif +#endif + +#ifdef SERIAL_PORT_3 + #if SERIAL_PORT_3 == -1 + #define MYSERIAL3 USBSerial + #elif WITHIN(SERIAL_PORT_3, 0, 3) + #define MYSERIAL3 MSERIAL(SERIAL_PORT_3) + #else + #error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB." + #endif +#endif + +#ifdef MMU2_SERIAL_PORT + #if MMU2_SERIAL_PORT == -1 + #define MMU2_SERIAL USBSerial + #elif WITHIN(MMU2_SERIAL_PORT, 0, 3) + #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT) + #else + #error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #endif +#endif + +#ifdef LCD_SERIAL_PORT + #if LCD_SERIAL_PORT == -1 + #define LCD_SERIAL USBSerial + #elif WITHIN(LCD_SERIAL_PORT, 0, 3) + #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT) + #else + #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB." + #endif + #if HAS_DGUS_LCD + #define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available() + #endif +#endif + +// +// Interrupts +// + +#define CRITICAL_SECTION_START() const bool irqon = !MCUCore::primask(); MCUCore::nvic_interrupts_disable() +#define CRITICAL_SECTION_END() if (irqon) MCUCore::nvic_interrupts_enable() + +// +// ADC +// + +#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift), + // (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift) + // Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16 + // 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels + +#define ADC_LOWPASS_K_VALUE (2) // Higher values increase rise time + // Rise time sample delays for 100% signal convergence on full range step + // (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273) + // K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step + // Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels) + +#define HAL_ADC_VREF 3.3 // ADC voltage reference + +#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t +#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL + +// +// Pin Mapping for M42, M43, M226 +// + +// Test whether the pin is valid +constexpr bool VALID_PIN(const pin_t pin) { + return MCUI::pin_is_valid(pin); +} + +// Get the analog index for a digital pin +constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) { + return (MCUI::pin_is_valid(pin) && MCUI::pin_has_adc(pin)) ? pin : -1; +} + +// Return the index of a pin number +constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { + return MCUI::pin_index(pin); +} + +// Get the pin number at the given index +constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) { + return MCUI::pin_index(index); +} + +// Parse a G-code word into a pin index +int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); +// P0.6 thru P0.9 are for the onboard SD card +#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09, + +// ------------------------ +// Defines +// ------------------------ + +void flashFirmware(const int16_t); + +#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment + +// Default graphical display delays +#define CPU_ST7920_DELAY_1 600 +#define CPU_ST7920_DELAY_2 750 +#define CPU_ST7920_DELAY_3 750 + +// ------------------------ +// Free Memory Accessor +// ------------------------ + +#pragma GCC diagnostic push +#if GCC_VERSION <= 50000 + #pragma GCC diagnostic ignored "-Wunused-function" +#endif + +int freeMemory(); + +#pragma GCC diagnostic pop + +// ------------------------ +// MarlinHAL Class +// ------------------------ + +class MarlinHAL { +public: + + // Earliest possible init, before setup() + MarlinHAL() {} + + static void init(); // Called early in setup() + static void init_board() {} // Called less early in setup() + static void reboot(); // Restart the firmware from 0x0 + + // Interrupts + static bool isr_state() { return MCUCore::primask(); } + static void isr_on() { MCUCore::nvic_interrupts_enable(); } + static void isr_off() { MCUCore::nvic_interrupts_disable(); } + + static void delay_ms(const int ms) { DELAY_US(ms * 1000); } + + // Watchdog + static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {}); + static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {}); + static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; }); + static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {}); + + // Tasks, called from idle() + static void idletask(); + + // Reset + static uint8_t get_reset_source(); + static void clear_reset_source(); + + // Free SRAM + static int freeMemory() { return ::freeMemory(); } + + // + // ADC Methods + // + + using FilteredADC = MCUI::ADC; + + // Called by Temperature::init once at startup + static void adc_init() { + // Turn on and initialise ADC in burst mode + MCUI::adc_hardware.init(); + MCUI::adc_hardware.burst_start(); + } + + // Called by Temperature::init for each sensor at startup + static void adc_enable(const pin_t pin) { + FilteredADC::enable_channel(pin); + } + + // Begin ADC sampling on the given pin. Called from Temperature::isr! + static uint32_t adc_result; + static void adc_start(const pin_t pin) { + adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits + } + + // Is the ADC ready for reading? + static bool adc_ready() { return true; } + + // The current value of the ADC register + static uint16_t adc_value() { return uint16_t(adc_result); } + + /** + * Set the PWM duty cycle for the pin to the given value. + * Optionally invert the duty cycle [default = false] + * Optionally change the scale of the provided value to enable finer PWM duty control [default = 255] + */ + static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false); + + /** + * Set the frequency of the timer corresponding to the provided pin + * All Hardware PWM pins will run at the same frequency and + * All Software PWM pins will run at the same frequency + */ + static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired); +}; diff --git a/Marlin/src/HAL/LPC4078/HAL_SPI.cpp b/Marlin/src/HAL/LPC4078/HAL_SPI.cpp new file mode 100644 index 0000000000..3af5677fbc --- /dev/null +++ b/Marlin/src/HAL/LPC4078/HAL_SPI.cpp @@ -0,0 +1,404 @@ +// /** +// * 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 . +// * +// */ + +// /** +// * Software SPI functions originally from Arduino Sd2Card Library +// * Copyright (c) 2009 by William Greiman +// */ + +// /** +// * For TARGET_LPC4078 +// */ + +// /** +// * Hardware SPI and Software SPI implementations are included in this file. +// * The hardware SPI runs faster and has higher throughput but is not compatible +// * with some LCD interfaces/adapters. +// * +// * Control of the slave select pin(s) is handled by the calling routines. +// * +// * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card +// * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with +// * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is +// * active. If any of these pins are shared then the software SPI must be used. +// * +// * A more sophisticated hardware SPI can be found at the following link. +// * This implementation has not been fully debugged. +// * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e +// */ + +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" +#include + +// Hardware SPI and SPIClass + +#include "../shared/HAL_SPI.h" + +#define LPC_SOFTWARE_SPI + +// ------------------------ +// Public functions +// ------------------------ +#if ENABLED(LPC_SOFTWARE_SPI) + #include "SoftwareSPI.h" + + // Software SPI + static uint8_t SPI_speed = SPI_FULL_SPEED; + + static uint8_t spiTransfer(uint8_t b) { + return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN); + } + + void spiBegin() { + swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN); + } + + void spiInit(uint8_t spiRate) { + SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN); + } + + uint8_t spiRec() { return spiTransfer(0xFF); } + + void spiRead(uint8_t*buf, uint16_t nbyte) { + for (int i = 0; i < nbyte; i++) + buf[i] = spiTransfer(0xFF); + } + + void spiSend(uint8_t b) { (void)spiTransfer(b); } + + void spiSend(const uint8_t *buf, size_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) + (void)spiTransfer(buf[i]); + } + + void spiSendBlock(uint8_t token, const uint8_t *buf) { + (void)spiTransfer(token); + for (uint16_t i = 0; i < 512; i++) + (void)spiTransfer(buf[i]); + } + +#else + + #ifdef SD_SPI_SPEED + #define INIT_SPI_SPEED SD_SPI_SPEED + #else + #define INIT_SPI_SPEED SPI_FULL_SPEED + #endif + + void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0 + + void spiInit(uint8_t spiRate) { + #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN + SPI.setModule(1); + #elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN + SPI.setModule(2); + #endif + SPI.setDataSize(DATA_SIZE_8BIT); + SPI.setDataMode(SPI_MODE0); + + SPI.setClock(SPISettings::spiRate2Clock(spiRate)); + SPI.begin(); + } + + static uint8_t doio(uint8_t b) { + return SPI.transfer(b & 0x00FF) & 0x00FF; + } + + void spiSend(uint8_t b) { doio(b); } + + void spiSend(const uint8_t *buf, size_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]); + } + + void spiSend(uint32_t chan, byte b) {} + + void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {} + + // Read single byte from SPI + uint8_t spiRec() { return doio(0xFF); } + + uint8_t spiRec(uint32_t chan) { return 0; } + + // Read from SPI into buffer + void spiRead(uint8_t *buf, uint16_t nbyte) { + for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF); + } + + uint8_t spiTransfer(uint8_t b) { return doio(b); } + + // Write from buffer to SPI + void spiSendBlock(uint8_t token, const uint8_t *buf) { + (void)spiTransfer(token); + for (uint16_t i = 0; i < 512; i++) + (void)spiTransfer(buf[i]); + } + + // Begin SPI transaction, set clock, bit order, data mode + void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) { + // TODO: Implement this method + } + +#endif // LPC_SOFTWARE_SPI + +// /** +// * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset. +// */ +// static inline void waitSpiTxEnd(LPC_SSP_TypeDef *spi_d) { +// while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1 +// while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0 +// } + +// // Retain the pin init state of the SPI, to avoid init more than once, +// // even if more instances of SPIClass exist +// static bool spiInitialised[BOARD_NR_SPI] = { false }; + +// SPIClass::SPIClass(uint8_t device) { +// // Init things specific to each SPI device +// // clock divider setup is a bit of hack, and needs to be improved at a later date. + +// #if BOARD_NR_SPI >= 1 +// _settings[0].spi_d = LPC_SSP0; +// _settings[0].dataMode = SPI_MODE0; +// _settings[0].dataSize = DATA_SIZE_8BIT; +// _settings[0].clock = SPI_CLOCK_MAX; +// //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock); +// #endif + +// #if BOARD_NR_SPI >= 2 +// _settings[1].spi_d = LPC_SSP1; +// _settings[1].dataMode = SPI_MODE0; +// _settings[1].dataSize = DATA_SIZE_8BIT; +// _settings[1].clock = SPI_CLOCK_MAX; +// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock); +// #endif + +// setModule(device); + +// // Init the GPDMA controller +// // TODO: call once in the constructor? or each time? +// GPDMA_Init(); +// } + +// SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) { +// #if BOARD_NR_SPI >= 1 +// if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1); +// #endif +// #if BOARD_NR_SPI >= 2 +// if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2); +// #endif +// } + +// void SPIClass::begin() { +// // Init the SPI pins in the first begin call +// if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) || +// (_currentSetting->spi_d == LPC_SSP1 && spiInitialised[1] == false)) { +// pin_t sck, miso, mosi; +// if (_currentSetting->spi_d == LPC_SSP0) { +// sck = BOARD_SPI1_SCK_PIN; +// miso = BOARD_SPI1_MISO_PIN; +// mosi = BOARD_SPI1_MOSI_PIN; +// spiInitialised[0] = true; +// } +// else if (_currentSetting->spi_d == LPC_SSP1) { +// sck = BOARD_SPI2_SCK_PIN; +// miso = BOARD_SPI2_MISO_PIN; +// mosi = BOARD_SPI2_MOSI_PIN; +// spiInitialised[1] = true; +// } +// PINSEL_CFG_Type PinCfg; // data structure to hold init values +// PinCfg.Funcnum = 2; +// PinCfg.OpenDrain = 0; +// PinCfg.Pinmode = 0; +// PinCfg.Pinnum = LPC176x::pin_bit(sck); +// PinCfg.Portnum = LPC176x::pin_port(sck); +// PINSEL_ConfigPin(&PinCfg); +// SET_OUTPUT(sck); + +// PinCfg.Pinnum = LPC176x::pin_bit(miso); +// PinCfg.Portnum = LPC176x::pin_port(miso); +// PINSEL_ConfigPin(&PinCfg); +// SET_INPUT(miso); + +// PinCfg.Pinnum = LPC176x::pin_bit(mosi); +// PinCfg.Portnum = LPC176x::pin_port(mosi); +// PINSEL_ConfigPin(&PinCfg); +// SET_OUTPUT(mosi); +// } + +// updateSettings(); +// SSP_Cmd(_currentSetting->spi_d, ENABLE); // start SSP running +// } + +// void SPIClass::beginTransaction(const SPISettings &cfg) { +// setBitOrder(cfg.bitOrder); +// setDataMode(cfg.dataMode); +// setDataSize(cfg.dataSize); +// //setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock)); +// begin(); +// } + +// uint8_t SPIClass::transfer(const uint16_t b) { +// // Send and receive a single byte +// SSP_ReceiveData(_currentSetting->spi_d); // read any previous data +// SSP_SendData(_currentSetting->spi_d, b); +// waitSpiTxEnd(_currentSetting->spi_d); // wait for it to finish +// return SSP_ReceiveData(_currentSetting->spi_d); +// } + +// uint16_t SPIClass::transfer16(const uint16_t data) { +// return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF); +// } + +// void SPIClass::end() { +// // Neither is needed for Marlin +// //SSP_Cmd(_currentSetting->spi_d, DISABLE); +// //SSP_DeInit(_currentSetting->spi_d); +// } + +// void SPIClass::send(uint8_t data) { +// SSP_SendData(_currentSetting->spi_d, data); +// } + +// void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) { +// //TODO: LPC dma can only write 0xFFF bytes at once. +// GPDMA_Channel_CFG_Type GPDMACfg; + +// /* Configure GPDMA channel 0 -------------------------------------------------------------*/ +// /* DMA Channel 0 */ +// GPDMACfg.ChannelNum = 0; +// // Source memory +// GPDMACfg.SrcMemAddr = (uint32_t)buf; +// // Destination memory - Not used +// GPDMACfg.DstMemAddr = 0; +// // Transfer size +// GPDMACfg.TransferSize = length; +// // Transfer width +// GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE; +// // Transfer type +// GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P; +// // Source connection - unused +// GPDMACfg.SrcConn = 0; +// // Destination connection +// GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx; + +// GPDMACfg.DMALLI = 0; + +// // Enable dma on SPI +// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE); + +// // Only increase memory if minc is true +// GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0); + +// // Setup channel with given parameter +// GPDMA_Setup(&GPDMACfg); + +// // Enable DMA +// GPDMA_ChannelCmd(0, ENABLE); + +// // Wait for data transfer +// while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { } + +// // Clear err and int +// GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0); +// GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0); + +// // Disable DMA +// GPDMA_ChannelCmd(0, DISABLE); + +// waitSpiTxEnd(_currentSetting->spi_d); + +// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE); +// } + +// uint16_t SPIClass::read() { +// return SSP_ReceiveData(_currentSetting->spi_d); +// } + +// void SPIClass::read(uint8_t *buf, uint32_t len) { +// for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF); +// } + +// void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; } + +// void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed + +// void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; } + +// void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; } + +// void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; } + +// /** +// * Set up/tear down +// */ +// void SPIClass::updateSettings() { +// //SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?! + +// // Divide PCLK by 2 for SSP0 +// //CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2); + +// SSP_CFG_Type HW_SPI_init; // data structure to hold init values +// SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode +// HW_SPI_init.ClockRate = _currentSetting->clock; +// HW_SPI_init.Databit = _currentSetting->dataSize; + +// /** +// * SPI Mode CPOL CPHA Shift SCK-edge Capture SCK-edge +// * 0 0 0 Falling Rising +// * 1 0 1 Rising Falling +// * 2 1 0 Rising Falling +// * 3 1 1 Falling Rising +// */ +// switch (_currentSetting->dataMode) { +// case SPI_MODE0: +// HW_SPI_init.CPHA = SSP_CPHA_FIRST; +// HW_SPI_init.CPOL = SSP_CPOL_HI; +// break; +// case SPI_MODE1: +// HW_SPI_init.CPHA = SSP_CPHA_SECOND; +// HW_SPI_init.CPOL = SSP_CPOL_HI; +// break; +// case SPI_MODE2: +// HW_SPI_init.CPHA = SSP_CPHA_FIRST; +// HW_SPI_init.CPOL = SSP_CPOL_LO; +// break; +// case SPI_MODE3: +// HW_SPI_init.CPHA = SSP_CPHA_SECOND; +// HW_SPI_init.CPOL = SSP_CPOL_LO; +// break; +// default: +// break; +// } + +// // TODO: handle bitOrder +// SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers +// } + +// #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN +// SPIClass SPI(1); +// #elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN +// SPIClass SPI(2); +// #endif + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/MarlinSPI.h b/Marlin/src/HAL/LPC4078/MarlinSPI.h new file mode 100644 index 0000000000..fab245f904 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/MarlinSPI.h @@ -0,0 +1,45 @@ +/** + * 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 . + * + */ +#pragma once + +#include + +/** + * Marlin currently requires 3 SPI classes: + * + * SPIClass: + * This class is normally provided by frameworks and has a semi-default interface. + * This is needed because some libraries reference it globally. + * + * SPISettings: + * Container for SPI configs for SPIClass. As above, libraries may reference it globally. + * + * These two classes are often provided by frameworks so we cannot extend them to add + * useful methods for Marlin. + * + * MarlinSPI: + * Provides the default SPIClass interface plus some Marlin goodies such as a simplified + * interface for SPI DMA transfer. + * + */ + +using MarlinSPI = SPIClass; diff --git a/Marlin/src/HAL/LPC4078/MarlinSerial.cpp b/Marlin/src/HAL/LPC4078/MarlinSerial.cpp new file mode 100644 index 0000000000..d18ceedf7e --- /dev/null +++ b/Marlin/src/HAL/LPC4078/MarlinSerial.cpp @@ -0,0 +1,78 @@ +/** + * 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 . + * + */ +#ifdef TARGET_LPC4078 + +#include "MarlinSerial.h" + +#include "../../inc/MarlinConfig.h" + +MarlinCDCSerial MCDCSerial0; + +#define MarlinSerial(ID) \ + MarlinSerial _MSerial##ID(ID); \ + MSerialT MSerial##ID(true, _MSerial##ID) + +#if USING_HW_SERIAL0 + MarlinSerial(0); +#endif +#if USING_HW_SERIAL1 + MarlinSerial(1); +#endif +#if USING_HW_SERIAL2 + MarlinSerial(2); +#endif +#if USING_HW_SERIAL3 + MarlinSerial(3); +#endif + +#if ENABLED(EMERGENCY_PARSER) + + bool MarlinSerial::recv_callback(const char c) { + // Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro) + if (false) {} + #if USING_HW_SERIAL0 + else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c); + #endif + #if USING_HW_SERIAL1 + else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c); + #endif + #if USING_HW_SERIAL2 + else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c); + #endif + #if USING_HW_SERIAL3 + else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c); + #endif + return true; + } + + #include "../../feature/e_parser.h" + + EmergencyParser::State emergency_state; + + bool CDC_RecvCallback(const char c) { + emergency_parser.update(emergency_state, c); + return true; + } + +#endif + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/MarlinSerial.h b/Marlin/src/HAL/LPC4078/MarlinSerial.h new file mode 100644 index 0000000000..60869e76c9 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/MarlinSerial.h @@ -0,0 +1,108 @@ +/** + * 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 . + * + */ +#pragma once + +#include +#include +#include + +#include + +#include "../../inc/MarlinConfigPre.h" +#if ENABLED(EMERGENCY_PARSER) + #include "../../feature/e_parser.h" +#endif +#include "../../core/serial_hook.h" + +#ifndef SERIAL_PORT + #define SERIAL_PORT 0 +#endif +#ifndef RX_BUFFER_SIZE + #define RX_BUFFER_SIZE 128 +#endif +#ifndef TX_BUFFER_SIZE + #define TX_BUFFER_SIZE 32 +#endif + +class MarlinCDCSerial : public HardwareSerial { + public: + MarlinCDCSerial() {} + void begin(unsigned long baudrate) override {} + void begin(unsigned long baudrate, uint16_t config) override { } + void end() override { } + int available() override { + return MCUI::CDCSerial0::available(); + } + int peek() override { char c = 0; return MCUI::CDCSerial0::peek((uint8_t*)&c)? c : -1; } + int read() override { char c = 0; return MCUI::CDCSerial0::read((uint8_t*)&c, 1)? c : -1; } + void flush() override {}; + size_t write(uint8_t c) override { return write(&c, 1); } + size_t write(const uint8_t *buffer, size_t size) override { return MCUI::CDCSerial0::connected() ? MCUI::CDCSerial0::write(buffer, size) : 0; } + using Print::write; + operator bool() override { return true; } +}; +extern MarlinCDCSerial MCDCSerial0; + +class MarlinSerial : public HardwareSerial { + public: + MarlinSerial(const uint32_t uart_id) : uart_device(uart_id) {} + void begin(unsigned long baudrate) override { + uart_device.configure_pins(P0_02, P0_03); + uart_device.init({ .baud = baudrate }); + #if ENABLED(EMERGENCY_PARSER) + uart_device.set_rx_callback([this](char rx_value){ return this->recv_callback(rx_value); } ); + #endif + } + void begin(unsigned long baudrate, uint16_t config) override { + begin(baudrate); + } + void end() override { } + int available() override { + return uart_device.rx_available(); + } + int peek() override { char c = 0; return uart_device.peek(&c)? c : -1; } + int read() override { char c = 0; return uart_device.read(&c)? c : -1; } + void flush() override {}; + size_t write(uint8_t c) override { return write(&c, 1); } + size_t write(const uint8_t *buffer, size_t size) override { return uart_device.write((const char *)buffer, size); } + using Print::write; // pull in write(str) and write(buf, size) from Print + operator bool() override { return true; } + + bool recv_callback(char value); + private: + MCUI::BufferedUARTC uart_device; +}; + +// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads +// of 'available' and 'read' method are not used in this multiple inheritance scenario. +// Instead, use a ForwardSerial here that adapts the interface. +typedef ForwardSerial1Class MSerialT; +extern MSerialT MSerial0; +extern MSerialT MSerial1; +extern MSerialT MSerial2; +extern MSerialT MSerial3; + +// Consequently, we can't use a RuntimeSerial either. The workaround would be to use +// a RuntimeSerial> type here. Ignore for now until it's actually required. +#if ENABLED(SERIAL_RUNTIME_HOOK) + #error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x." +#endif diff --git a/Marlin/src/HAL/LPC4078/MinSerial.cpp b/Marlin/src/HAL/LPC4078/MinSerial.cpp new file mode 100644 index 0000000000..809a06b85d --- /dev/null +++ b/Marlin/src/HAL/LPC4078/MinSerial.cpp @@ -0,0 +1,51 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2021 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 . + * + */ +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" +#include "HAL.h" + +#if ENABLED(POSTMORTEM_DEBUGGING) + +#include "../shared/MinSerial.h" +#include + +static void TX(char c) { _DBC(c); } +void install_min_serial() { HAL_min_serial_out = &TX; } + +#if DISABLED(DYNAMIC_VECTORTABLE) +extern "C" { + __attribute__((naked)) void JumpHandler_ASM() { + __asm__ __volatile__ ( + "b CommonHandler_ASM\n" + ); + } + void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler(); + void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler(); + void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler(); + void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler(); + void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler(); +} +#endif + +#endif // POSTMORTEM_DEBUGGING +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/Servo.h b/Marlin/src/HAL/LPC4078/Servo.h new file mode 100644 index 0000000000..f02f503a67 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/Servo.h @@ -0,0 +1,69 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 + * Copyright (c) 2009 Michael Margolis. All right reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#pragma once + +/** + * Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers - + * Version 2 Copyright (c) 2009 Michael Margolis. All right reserved. + * + * The only modification was to update/delete macros to match the LPC176x. + */ + +#include + +class libServo: public Servo { + public: + void move(const int value) { + constexpr uint16_t servo_delay[] = SERVO_DELAY; + static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long."); + + if (attach(servo_info[servoIndex].Pin.nbr) >= 0) { // try to reattach + write(value); + safe_delay(servo_delay[servoIndex]); // delay to allow servo to reach position + TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach()); + } + + } +}; + +class libServo; +typedef libServo hal_servo_t; diff --git a/Marlin/src/HAL/LPC4078/SoftwareSPI.cpp b/Marlin/src/HAL/LPC4078/SoftwareSPI.cpp new file mode 100644 index 0000000000..156f0acc20 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/SoftwareSPI.cpp @@ -0,0 +1,47 @@ +#ifdef TARGET_LPC4078 + +#include +#include "SoftwareSPI.h" + +#include + +uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) { + for (uint8_t i = 0; i < 8; i++) { + if (spi_speed == 0) { + MCUI::gpio_set(mosi_pin, !!(b & 0x80)); + MCUI::gpio_set(sck_pin, HIGH); + b <<= 1; + if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1; + MCUI::gpio_set(sck_pin, LOW); + } + else { + const uint8_t state = (b & 0x80) ? HIGH : LOW; + for (uint8_t j = 0; j < spi_speed; j++) + MCUI::gpio_set(mosi_pin, state); + + for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++) + MCUI::gpio_set(sck_pin, HIGH); + + b <<= 1; + if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1; + + for (uint8_t j = 0; j < spi_speed; j++) + MCUI::gpio_set(sck_pin, LOW); + } + } + return b; +} + +void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) { + pinMode(sck_pin, OUTPUT); + if (MCUI::pin_is_valid(miso_pin)) pinMode(miso_pin, INPUT); + pinMode(mosi_pin, OUTPUT); +} + +uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) { + MCUI::gpio_set(mosi_pin, HIGH); + MCUI::gpio_set(sck_pin, LOW); + return (SystemCoreClock == 120000000 ? 44 : 38) / std::pow(2, 6 - std::min(spiRate, (uint8_t)6)); +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/SoftwareSPI.h b/Marlin/src/HAL/LPC4078/SoftwareSPI.h new file mode 100644 index 0000000000..7b4fe79b44 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/SoftwareSPI.h @@ -0,0 +1,5 @@ +#include + +uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin); +void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin); +uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin); diff --git a/Marlin/src/HAL/LPC4078/eeprom_internal.cpp b/Marlin/src/HAL/LPC4078/eeprom_internal.cpp new file mode 100644 index 0000000000..69e2e15592 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/eeprom_internal.cpp @@ -0,0 +1,116 @@ +/** + * 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 . + * + */ +#ifdef TARGET_LPC4078 + +/** + * Emulate EEPROM storage using Flash Memory + * + * Use a single 32K flash sector to store EEPROM data. To reduce the + * number of erase operations a simple "leveling" scheme is used that + * maintains a number of EEPROM "slots" within the larger flash sector. + * Each slot is used in turn and the entire sector is only erased when all + * slots have been used. + * + * A simple RAM image is used to hold the EEPROM data during I/O operations + * and this is flushed to the next available slot when an update is complete. + * If RAM usage becomes an issue we could store this image in one of the two + * 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently + * unused). + */ +#include "../../inc/MarlinConfig.h" + +#include "../shared/eeprom_api.h" + +//#include + +#ifndef MARLIN_EEPROM_SIZE + #define MARLIN_EEPROM_SIZE 4032 // 4KB +#endif + +size_t PersistentStore::capacity() { return 4032; } + +constexpr uint32_t page_size = MCUI::EEPROM::page_size; +uint32_t buffered_page = 0; +uint8_t page_buffer[page_size]; +bool buffered_page_dirty = false; + +bool PersistentStore::access_start() { + MCUI::EEPROM::init(); + MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size); + return true; +} + +bool PersistentStore::access_finish() { + if (buffered_page_dirty) { + MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size); + } + return true; +} + +bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) { + uint32_t address = pos; + //printf("Marlin::eeprom::write(pos = %d, size = %d)\n", pos, size); + uint32_t value_index = 0; + for (uint32_t addr = address; addr < address + size; ++addr) { + uint32_t page_address = addr & 0xFFFFFFC0; + if (page_address != buffered_page) { + //printf("Marlin::eeprom::write(@%ld):: page change new(%ld) != current(%d)\n",addr, page_address, buffered_page); + if (buffered_page_dirty == true) MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size); + buffered_page = page_address; + buffered_page_dirty = false; + MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size); + } + page_buffer[addr & ~0xFFFFFFC0] = value[value_index++]; + buffered_page_dirty = true; + } + + pos += size; + crc16(crc, value, size); + + return false; // return true for any error +} + +bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) { + uint32_t address = pos; + //printf("Marlin::eeprom::read(pos = %d, size = %d, writing = %d)\n", pos, size, writing); + uint32_t value_index = 0; + for (uint32_t addr = address; addr < address + size; ++addr) { + uint32_t page_address = addr & 0xFFFFFFC0; + if (page_address != buffered_page) { + if (buffered_page_dirty) { + MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size); + buffered_page_dirty = false; + } + buffered_page = page_address; + MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size); + } + if (writing) value[value_index++] = page_buffer[addr & ~0xFFFFFFC0]; + else crc16(crc, &page_buffer[addr & ~0xFFFFFFC0], 1); + } + + if (writing) crc16(crc, value, size); + pos += size; + + return false; // return true for any error +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/endstop_interrupts.h b/Marlin/src/HAL/LPC4078/endstop_interrupts.h new file mode 100644 index 0000000000..e4ac17f608 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/endstop_interrupts.h @@ -0,0 +1,191 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * Endstop Interrupts + * + * Without endstop interrupts the endstop pins must be polled continually in + * the temperature-ISR via endstops.update(), most of the time finding no change. + * With this feature endstops.update() is called only when we know that at + * least one endstop has changed state, saving valuable CPU cycles. + * + * This feature only works when all used endstop pins can generate an 'external interrupt'. + * + * Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'. + * (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino) + */ + +#include "../../module/endstops.h" + +// One ISR for all EXT-Interrupts +void endstop_ISR() { endstops.update(); } + +void setup_endstop_interrupts() { + #define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE) + #define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2) + + #if HAS_X_MAX + #if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN) + #error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(X_MAX_PIN); + #endif + #if HAS_X_MIN + #if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN) + #error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(X_MIN_PIN); + #endif + #if HAS_Y_MAX + #if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN) + #error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Y_MAX_PIN); + #endif + #if HAS_Y_MIN + #if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN) + #error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Y_MIN_PIN); + #endif + #if HAS_Z_MAX + #if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN) + #error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z_MAX_PIN); + #endif + #if HAS_Z_MIN + #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN) + #error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z_MIN_PIN); + #endif + #if HAS_Z2_MAX + #if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN) + #error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z2_MAX_PIN); + #endif + #if HAS_Z2_MIN + #if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN) + #error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z2_MIN_PIN); + #endif + #if HAS_Z3_MAX + #if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN) + #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z3_MAX_PIN); + #endif + #if HAS_Z3_MIN + #if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN) + #error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z3_MIN_PIN); + #endif + #if HAS_Z4_MAX + #if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN) + #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z4_MAX_PIN); + #endif + #if HAS_Z4_MIN + #if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN) + #error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z4_MIN_PIN); + #endif + #if HAS_Z_MIN_PROBE_PIN + #if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN) + #error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue." + #endif + _ATTACH(Z_MIN_PROBE_PIN); + #endif + #if HAS_I_MAX + #if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN) + #error "I_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(I_MAX_PIN); + #elif HAS_I_MIN + #if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN) + #error "I_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(I_MIN_PIN); + #endif + #if HAS_J_MAX + #if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN) + #error "J_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(J_MAX_PIN); + #elif HAS_J_MIN + #if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN) + #error "J_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(J_MIN_PIN); + #endif + #if HAS_K_MAX + #if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN) + #error "K_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(K_MAX_PIN); + #elif HAS_K_MIN + #if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN) + #error "K_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(K_MIN_PIN); + #endif + #if HAS_U_MAX + #if !LPC1768_PIN_INTERRUPT_M(U_MAX_PIN) + #error "U_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(U_MAX_PIN); + #elif HAS_U_MIN + #if !LPC1768_PIN_INTERRUPT_M(U_MIN_PIN) + #error "U_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(U_MIN_PIN); + #endif + #if HAS_V_MAX + #if !LPC1768_PIN_INTERRUPT_M(V_MAX_PIN) + #error "V_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(V_MAX_PIN); + #elif HAS_V_MIN + #if !LPC1768_PIN_INTERRUPT_M(V_MIN_PIN) + #error "V_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(V_MIN_PIN); + #endif + #if HAS_W_MAX + #if !LPC1768_PIN_INTERRUPT_M(W_MAX_PIN) + #error "W_MAX_PIN is not INTERRUPT-capable." + #endif + _ATTACH(W_MAX_PIN); + #elif HAS_W_MIN + #if !LPC1768_PIN_INTERRUPT_M(W_MIN_PIN) + #error "W_MIN_PIN is not INTERRUPT-capable." + #endif + _ATTACH(W_MIN_PIN); + #endif +} diff --git a/Marlin/src/HAL/LPC4078/fast_pwm.cpp b/Marlin/src/HAL/LPC4078/fast_pwm.cpp new file mode 100644 index 0000000000..d202a49d28 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/fast_pwm.cpp @@ -0,0 +1,37 @@ +/** + * 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 . + * + */ +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" +#include + +void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) { + if (!MCUI::pin_is_valid(pin)) return; + if (MCUI::pwm_attach_pin(pin)) + MCUI::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range +} + +void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) { + MCUI::pwm_set_frequency(pin, f_desired); +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/fastio.h b/Marlin/src/HAL/LPC4078/fastio.h new file mode 100644 index 0000000000..9e384d6cf6 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/fastio.h @@ -0,0 +1,120 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * Fast I/O Routines for LPC1768/9 + * Use direct port manipulation to save scads of processor time. + * Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al. + */ + +/** + * Description: Fast IO functions LPC1768 + * + * For TARGET LPC1768 + */ + +#include "../shared/Marduino.h" +#include + +#define PWM_PIN(P) true // all pins are software PWM capable + +#define LPC_PIN(pin) MCUI::gpio_pin(pin) +#define LPC_GPIO(port) MCUI::gpio_port(port) + +#define SET_DIR_INPUT(IO) MCUI::gpio_set_input(IO) +#define SET_DIR_OUTPUT(IO) MCUI::gpio_set_output(IO) + +#define SET_MODE(IO, mode) pinMode(IO, mode) + +#define WRITE_PIN_SET(IO) MCUI::gpio_set(IO) +#define WRITE_PIN_CLR(IO) MCUI::gpio_clear(IO) + +#define READ_PIN(IO) MCUI::gpio_get(IO) +#define WRITE_PIN(IO,V) MCUI::gpio_set(IO, V) + +/** + * Magic I/O routines + * + * Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW); + * + * Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html + */ + +/// Read a pin +#define _READ(IO) READ_PIN(IO) + +/// Write to a pin +#define _WRITE(IO,V) WRITE_PIN(IO,V) + +/// toggle a pin +#define _TOGGLE(IO) MCUI::gpio_toggle(IO) + +/// set pin as input +#define _SET_INPUT(IO) SET_DIR_INPUT(IO) + +/// set pin as output +#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO) + +/// set pin as input with pullup mode +#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) + +/// set pin as input with pulldown mode +#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT) + +/// check if pin is an input +#define _IS_INPUT(IO) (!MCUI::gpio_get_dir(IO)) + +/// check if pin is an output +#define _IS_OUTPUT(IO) (MCUI::gpio_get_dir(IO)) + +/// Read a pin wrapper +#define READ(IO) _READ(IO) + +/// Write to a pin wrapper +#define WRITE(IO,V) _WRITE(IO,V) + +/// toggle a pin wrapper +#define TOGGLE(IO) _TOGGLE(IO) + +/// set pin as input wrapper +#define SET_INPUT(IO) _SET_INPUT(IO) +/// set pin as input with pullup wrapper +#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) +/// set pin as input with pulldown wrapper +#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0) +/// set pin as output wrapper - reads the pin and sets the output to that value +#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0) +// set pin as PWM +#define SET_PWM SET_OUTPUT + +/// check if pin is an input wrapper +#define IS_INPUT(IO) _IS_INPUT(IO) +/// check if pin is an output wrapper +#define IS_OUTPUT(IO) _IS_OUTPUT(IO) + +// Shorthand +#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) + +// digitalRead/Write wrappers +#define extDigitalRead(IO) digitalRead(IO) +#define extDigitalWrite(IO,V) digitalWrite(IO,V) diff --git a/Marlin/src/HAL/LPC4078/inc/Conditionals_LCD.h b/Marlin/src/HAL/LPC4078/inc/Conditionals_LCD.h new file mode 100644 index 0000000000..5f1c4b1601 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/inc/Conditionals_LCD.h @@ -0,0 +1,22 @@ +/** + * 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 . + * + */ +#pragma once diff --git a/Marlin/src/HAL/LPC4078/inc/Conditionals_adv.h b/Marlin/src/HAL/LPC4078/inc/Conditionals_adv.h new file mode 100644 index 0000000000..8e7cab185f --- /dev/null +++ b/Marlin/src/HAL/LPC4078/inc/Conditionals_adv.h @@ -0,0 +1,26 @@ +/** + * 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 . + * + */ +#pragma once + +#if DISABLED(NO_SD_HOST_DRIVE) + #define HAS_SD_HOST_DRIVE 1 +#endif diff --git a/Marlin/src/HAL/LPC4078/inc/Conditionals_post.h b/Marlin/src/HAL/LPC4078/inc/Conditionals_post.h new file mode 100644 index 0000000000..865b71be7d --- /dev/null +++ b/Marlin/src/HAL/LPC4078/inc/Conditionals_post.h @@ -0,0 +1,34 @@ +/** + * 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 . + * + */ +#pragma once + +#if USE_FALLBACK_EEPROM + #define FLASH_EEPROM_EMULATION +#elif ANY(I2C_EEPROM, SPI_EEPROM) + #define USE_SHARED_EEPROM 1 +#endif + +// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785) +// TODO: Which other boards are incompatible? +#if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0 + #define PRINTCOUNTER_SYNC 1 +#endif diff --git a/Marlin/src/HAL/LPC4078/inc/SanityCheck.h b/Marlin/src/HAL/LPC4078/inc/SanityCheck.h new file mode 100644 index 0000000000..f2f75e5854 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/inc/SanityCheck.h @@ -0,0 +1,276 @@ +/** + * 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 . + * + */ +#pragma once + +// #if PIO_PLATFORM_VERSION < 1001 +// #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically." +// #endif +// #if PIO_FRAMEWORK_VERSION < 2006 +// #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries." +// #endif + +/** + * Detect an old pins file by checking for old ADC pins values. + */ +#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && !WITHIN(_CAT(P,_PIN), TERN(LPC1768_IS_SKRV1_3, 0, 2), 3) // Include P0_00 and P0_01 for SKR V1.3 board +#if _OLD_TEMP_PIN(TEMP_BED) + #error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_0) + #error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_1) + #error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_2) + #error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_3) + #error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_4) + #error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_5) + #error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_6) + #error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#elif _OLD_TEMP_PIN(TEMP_7) + #error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)." +#endif +#undef _OLD_TEMP_PIN + +/** + * Because PWM hardware channels all share the same frequency, along with the + * fallback software channels, FAST_PWM_FAN is incompatible with Servos. + */ +static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards."); + +#if SPINDLE_LASER_FREQUENCY + static_assert(!NUM_SERVOS, "BLTOUCH and Servos are incompatible with SPINDLE_LASER_FREQUENCY on LPC176x boards."); +#endif + +/** + * Test LPC176x-specific configuration values for errors at compile-time. + */ + +//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11) +// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector" +//#endif + +#if MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF) + #if IS_RRD_FG_SC && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI) + #error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI." + #endif +#endif + +static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported on LPC176x."); + +/** + * Flag any serial port conflicts + * + * Port | TX | RX | + * --- | --- | --- | + * Serial | P0_02 | P0_03 | + * Serial1 | P0_15 | P0_16 | + * Serial2 | P0_10 | P0_11 | + * Serial3 | P0_00 | P0_01 | + */ +#define ANY_TX(N,V...) DO(IS_TX##N,||,V) +#define ANY_RX(N,V...) DO(IS_RX##N,||,V) + +#if USING_HW_SERIAL0 + #define IS_TX0(P) (P == P0_02) + #define IS_RX0(P) (P == P0_03) + #if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI) + #error "Serial port pins (0) conflict with Trinamic SPI pins!" + #elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN)) + #error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!" + #elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN)) + #error "Serial port pins (0) conflict with X/Y axis SPI pins!" + #endif + #undef IS_TX0 + #undef IS_RX0 +#endif + +#if USING_HW_SERIAL1 + #define IS_TX1(P) (P == P0_15) + #define IS_RX1(P) (P == P0_16) + #define _IS_TX1_1 IS_TX1 + #define _IS_RX1_1 IS_RX1 + #if IS_TX1(TMC_SW_SCK) + #error "Serial port pins (1) conflict with other pins!" + #elif HAS_ROTARY_ENCODER + #if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1) + #error "Serial port pins (1) conflict with Encoder Buttons!" + #elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \ + || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN) + #error "Serial port pins (1) conflict with LCD pins!" + #endif + #endif + #undef IS_TX1 + #undef IS_RX1 + #undef _IS_TX1_1 + #undef _IS_RX1_1 +#endif + +#if USING_HW_SERIAL2 + #define IS_TX2(P) (P == P0_10) + #define IS_RX2(P) (P == P0_11) + #define _IS_TX2_1 IS_TX2 + #define _IS_RX2_1 IS_RX2 + #if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN)) + #error "Serial port pins (2) conflict with X2 pins!" + #elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN)) + #error "Serial port pins (2) conflict with Y2 pins!" + #elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN)) + #error "Serial port pins (2) conflict with Z2 pins!" + #elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN)) + #error "Serial port pins (2) conflict with Z3 pins!" + #elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN)) + #error "Serial port pins (2) conflict with Z4 pins!" + #elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) + #error "Serial port pins (2) conflict with other pins!" + #elif Y_HOME_TO_MIN && IS_TX2(Y_STOP_PIN) + #error "Serial port pins (2) conflict with Y endstop pin!" + #elif USES_Z_MIN_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN) + #error "Serial port pins (2) conflict with probe pin!" + #elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN) + #error "Serial port pins (2) conflict with X/Y stepper pins!" + #elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN))) + #error "Serial port pins (2) conflict with E1 stepper pins!" + #elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN) + #error "Serial port pins (2) conflict with E stepper pins!" + #endif + #undef IS_TX2 + #undef IS_RX2 + #undef _IS_TX2_1 + #undef _IS_RX2_1 +#endif + +#if USING_HW_SERIAL3 + #define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00) + #define PIN_IS_RX3(P) (P##_PIN == P0_01) + #if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX) + #error "Serial port pins (3) conflict with X endstop pins!" + #elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX) + #error "Serial port pins (3) conflict with X/Y axis UART pins!" + #elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP) + #error "Serial port pins (3) conflict with X2 pins!" + #elif PIN_IS_TX3(Y2_DIR) || PIN_IS_RX3(Y2_STEP) + #error "Serial port pins (3) conflict with Y2 pins!" + #elif PIN_IS_TX3(Z2_DIR) || PIN_IS_RX3(Z2_STEP) + #error "Serial port pins (3) conflict with Z2 pins!" + #elif PIN_IS_TX3(Z3_DIR) || PIN_IS_RX3(Z3_STEP) + #error "Serial port pins (3) conflict with Z3 pins!" + #elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP) + #error "Serial port pins (3) conflict with Z4 pins!" + #elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP)) + #error "Serial port pins (3) conflict with E1 pins!" + #endif + #undef PIN_IS_TX3 + #undef PIN_IS_RX3 +#endif + +#undef ANY_TX +#undef ANY_RX + +// +// Flag any i2c pin conflicts +// +#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM) + #define USEDI2CDEV_M 1 // /Wire.cpp + + #if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1) + #define PIN_IS_SDA0(P) (P##_PIN == P0_27) + #define IS_SCL0(P) (P == P0_28) + #if ENABLED(SDSUPPORT) && PIN_IS_SDA0(SD_DETECT) + #error "SDA0 overlaps with SD_DETECT_PIN!" + #elif PIN_IS_SDA0(E0_AUTO_FAN) + #error "SDA0 overlaps with E0_AUTO_FAN_PIN!" + #elif PIN_IS_SDA0(BEEPER) + #error "SDA0 overlaps with BEEPER_PIN!" + #elif IS_SCL0(BTN_ENC) + #error "SCL0 overlaps with Encoder Button!" + #elif IS_SCL0(SD_SS_PIN) + #error "SCL0 overlaps with SD_SS_PIN!" + #elif IS_SCL0(LCD_SDSS) + #error "SCL0 overlaps with LCD_SDSS!" + #endif + #undef PIN_IS_SDA0 + #undef IS_SCL0 + #elif USEDI2CDEV_M == 1 // P0_00 [D20] (SCA) ............ P0_01 [D21] (SCL) + #define PIN_IS_SDA1(P) (PIN_EXISTS(P) && P##_PIN == P0_00) + #define PIN_IS_SCL1(P) (P##_PIN == P0_01) + #if PIN_IS_SDA1(X_MIN) || PIN_IS_SCL1(X_MAX) + #error "One or more i2c (1) pins overlaps with X endstop pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(X2_DIR) || PIN_IS_SCL1(X2_STEP) + #error "One or more i2c (1) pins overlaps with X2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Y2_DIR) || PIN_IS_SCL1(Y2_STEP) + #error "One or more i2c (1) pins overlaps with Y2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z2_DIR) || PIN_IS_SCL1(Z2_STEP) + #error "One or more i2c (1) pins overlaps with Z2 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z3_DIR) || PIN_IS_SCL1(Z3_STEP) + #error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals." + #elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP) + #error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP)) + #error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals." + #endif + #undef PIN_IS_SDA1 + #undef PIN_IS_SCL1 + #elif USEDI2CDEV_M == 2 // P0_10 [D38] (X_ENABLE_PIN) ... P0_11 [D55] (X_DIR_PIN) + #define PIN_IS_SDA2(P) (P##_PIN == P0_10) + #define PIN_IS_SCL2(P) (P##_PIN == P0_11) + #if PIN_IS_SDA2(Y_STOP) + #error "i2c SDA2 overlaps with Y endstop pin!" + #elif USES_Z_MIN_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE) + #error "i2c SDA2 overlaps with Z probe pin!" + #elif PIN_IS_SDA2(X_ENABLE) || PIN_IS_SDA2(Y_ENABLE) + #error "i2c SDA2 overlaps with X/Y ENABLE pin!" + #elif AXIS_HAS_SPI(X) && PIN_IS_SDA2(X_CS) + #error "i2c SDA2 overlaps with X CS pin!" + #elif PIN_IS_SDA2(X2_ENABLE) + #error "i2c SDA2 overlaps with X2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Y2_ENABLE) + #error "i2c SDA2 overlaps with Y2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z2_ENABLE) + #error "i2c SDA2 overlaps with Z2 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z3_ENABLE) + #error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(Z4_ENABLE) + #error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE) + #error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals." + #elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS) + #error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals." + #elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR)) + #error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals." + #elif PIN_IS_SDA2(X_DIR) || PIN_IS_SDA2(Y_DIR) + #error "One or more i2c pins overlaps with X/Y DIR pin! Disable i2c peripherals." + #endif + #undef PIN_IS_SDA2 + #undef PIN_IS_SCL2 + #endif + + #undef USEDI2CDEV_M +#endif + +#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED) + #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x." +#elif ENABLED(SERIAL_STATS_DROPPED_RX) + #error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x." +#endif diff --git a/Marlin/src/HAL/LPC4078/include/SPI.h b/Marlin/src/HAL/LPC4078/include/SPI.h new file mode 100644 index 0000000000..02bfdf8398 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/include/SPI.h @@ -0,0 +1,197 @@ +/** + * 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 . + * + */ +#pragma once + +#include "../../shared/HAL_SPI.h" + +#include +// #include +// #include + +//#define MSBFIRST 1 + +#define SPI_MODE0 0 +#define SPI_MODE1 1 +#define SPI_MODE2 2 +#define SPI_MODE3 3 + +#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF)) +#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */ +#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */ +#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */ +#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */ +#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */ +#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */ +#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */ +#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */ +#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */ +#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */ +#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */ +#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */ +#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */ + +#define DATA_SIZE_8BIT SSP_DATABIT_8 +#define DATA_SIZE_16BIT SSP_DATABIT_16 + +#define SPI_CLOCK_MAX_TFT 30000000UL +#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED +#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED +#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED +#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED +#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 +#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 +#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h + +#define SPI_CLOCK_MAX SPI_CLOCK_DIV2 + +#define BOARD_NR_SPI 2 + +//#define BOARD_SPI1_NSS_PIN PA4 ?! +#define BOARD_SPI1_SCK_PIN P0_15 +#define BOARD_SPI1_MISO_PIN P0_17 +#define BOARD_SPI1_MOSI_PIN P0_18 + +//#define BOARD_SPI2_NSS_PIN PB12 ?! +#define BOARD_SPI2_SCK_PIN P0_07 +#define BOARD_SPI2_MISO_PIN P0_08 +#define BOARD_SPI2_MOSI_PIN P0_09 + +class SPISettings { +public: + SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) { + init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT); + } + SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { + if (__builtin_constant_p(inClock)) + init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); + else + init_MightInline(inClock, inBitOrder, inDataMode, inDataSize); + } + SPISettings() { + init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT); + } + + //uint32_t spiRate() const { return spi_speed; } + + static uint32_t spiRate2Clock(uint32_t spiRate) { + uint32_t Marlin_speed[7]; // CPSR is always 2 + Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED + Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED + Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED + Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED + Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5 + Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6 + Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h + return Marlin_speed[spiRate > 6 ? 6 : spiRate]; + } + +private: + void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) { + init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize); + } + void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) { + clock = inClock; + bitOrder = inBitOrder; + dataMode = inDataMode; + dataSize = inDataSize; + } + + //uint32_t spi_speed; + uint32_t clock; + uint32_t dataSize; + //uint32_t clockDivider; + uint8_t bitOrder; + uint8_t dataMode; + //LPC_SSP_TypeDef *spi_d; + + friend class SPIClass; +}; + +/** + * @brief Wirish SPI interface. + * + * This is the same interface is available across HAL + * + * This implementation uses software slave management, so the caller + * is responsible for controlling the slave select line. + */ +class SPIClass { +public: + /** + * @param spiPortNumber Number of the SPI port to manage. + */ + SPIClass(uint8_t spiPortNumber); + + /** + * Init using pins + */ + SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1); + + /** + * Select and configure the current selected SPI device to use + */ + void begin(); + + /** + * Disable the current SPI device + */ + void end(); + + void beginTransaction(const SPISettings&); + void endTransaction() {} + + // Transfer using 1 "Data Size" + uint8_t transfer(uint16_t data); + // Transfer 2 bytes in 8 bit mode + uint16_t transfer16(uint16_t data); + + void send(uint8_t data); + + uint16_t read(); + void read(uint8_t *buf, uint32_t len); + + void dmaSend(void *buf, uint16_t length, bool minc); + + /** + * @brief Sets the number of the SPI peripheral to be used by + * this HardwareSPI instance. + * + * @param spi_num Number of the SPI port. 1-2 in low density devices + * or 1-3 in high density devices. + */ + void setModule(uint8_t device); + + void setClock(uint32_t clock); + void setBitOrder(uint8_t bitOrder); + void setDataMode(uint8_t dataMode); + void setDataSize(uint32_t ds); + + inline uint32_t getDataSize() { return _currentSetting->dataSize; } + +private: + SPISettings _settings[BOARD_NR_SPI]; + SPISettings *_currentSetting; + + void updateSettings(); +}; + +extern SPIClass SPI; diff --git a/Marlin/src/HAL/LPC4078/main.cpp b/Marlin/src/HAL/LPC4078/main.cpp new file mode 100644 index 0000000000..40b77728bd --- /dev/null +++ b/Marlin/src/HAL/LPC4078/main.cpp @@ -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 . + * + */ +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" +#include "../../core/millis_t.h" +#include "../../sd/cardreader.h" + +#include +#include + +TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial()); + +void MarlinHAL::init() { + + MCUI::pwm_init(); + + // Init LEDs + #if PIN_EXISTS(LED) + SET_DIR_OUTPUT(LED_PIN); + WRITE_PIN_CLR(LED_PIN); + #if PIN_EXISTS(LED2) + SET_DIR_OUTPUT(LED2_PIN); + WRITE_PIN_CLR(LED2_PIN); + #if PIN_EXISTS(LED3) + SET_DIR_OUTPUT(LED3_PIN); + WRITE_PIN_CLR(LED3_PIN); + #if PIN_EXISTS(LED4) + SET_DIR_OUTPUT(LED4_PIN); + WRITE_PIN_CLR(LED4_PIN); + #endif + #endif + #endif + + // Flash status LED 3 times to indicate Marlin has started booting + for(int i = 0; i < 6; ++i) { + TOGGLE(LED_PIN); + delay(100); + } + #endif + + // Init Servo Pins + #define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW) + #if HAS_SERVO_0 + INIT_SERVO(0); + #endif + #if HAS_SERVO_1 + INIT_SERVO(1); + #endif + #if HAS_SERVO_2 + INIT_SERVO(2); + #endif + #if HAS_SERVO_3 + INIT_SERVO(3); + #endif + + #if PIN_EXISTS(SD_SS) + OUT_WRITE(SD_SS_PIN, HIGH); + #endif + + #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN + OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH); + #endif + + TERN_(HAS_SD_HOST_DRIVE, MCUI::USBDevice::msc_storage_init()); // Enable USB SD card access + MCUI::USBDevice::connect(2000, LED_PIN); + + HAL_timer_init(); + + TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler +} + +// HAL idle task +void MarlinHAL::idletask() { + #if HAS_SHARED_MEDIA + // If Marlin is using the SD card we need to lock it to prevent access from + // a PC via USB. + // Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but + // this will not reliably detect delete operations. To be safe we will lock + // the disk if Marlin has it mounted. Unfortunately there is currently no way + // to unmount the disk from the LCD menu. + // if (IS_SD_PRINTING() || IS_SD_FILE_OPEN()) + if (card.isMounted()) + MCUI::USBDevice::msc_storage_lock(); + else + MCUI::USBDevice::msc_storage_release(); + #endif + // Perform USB stack housekeeping + MCUI::USBDevice::msc_run_deferred_commands(); +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/pinsDebug.h b/Marlin/src/HAL/LPC4078/pinsDebug.h new file mode 100644 index 0000000000..a1bae08d92 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/pinsDebug.h @@ -0,0 +1,57 @@ +/** + * 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 . + * + */ + +/** + * Support routines for LPC1768 + */ + +/** + * Translation of routines & variables used by pinsDebug.h + */ + +#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS +#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) +#define digitalRead_mod(p) extDigitalRead(p) +#define PRINT_PORT(p) +#define GET_ARRAY_PIN(p) pin_array[p].pin +#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), MCUI::pin_port(p), MCUI::pin_bit(p)); SERIAL_ECHO(buffer); }while(0) +#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), MCUI::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0) +#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin + +// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities +#ifndef M43_NEVER_TOUCH + #define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins +#endif + +bool GET_PINMODE(const pin_t pin) { + if (!MCUI::pin_is_valid(pin) || MCUI::pin_adc_enabled(pin)) // found an invalid pin or active analog pin + return false; + + return MCUI::gpio_direction(pin); +} + +#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) + +void print_port(const pin_t) {} +void pwm_details(const pin_t) {} +bool pwm_status(const pin_t) { return false; } diff --git a/Marlin/src/HAL/LPC4078/spi_pins.h b/Marlin/src/HAL/LPC4078/spi_pins.h new file mode 100644 index 0000000000..78bb0ec962 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/spi_pins.h @@ -0,0 +1,54 @@ +/** + * 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 . + * + */ +#pragma once + +#include "../../core/macros.h" + +#if ALL(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN) + #define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently + // needed due to the speed and mode required for communicating with each device being different. + // This requirement can be removed if the SPI access to these devices is updated to use + // spiBeginTransaction. +#endif + +/** onboard SD card */ +//#define SD_SCK_PIN P0_07 +//#define SD_MISO_PIN P0_08 +//#define SD_MOSI_PIN P0_09 +//#define SD_SS_PIN P0_06 +/** external */ +#ifndef SD_SCK_PIN + #define SD_SCK_PIN P0_15 +#endif +#ifndef SD_MISO_PIN + #define SD_MISO_PIN P0_17 +#endif +#ifndef SD_MOSI_PIN + #define SD_MOSI_PIN P0_18 +#endif +#ifndef SD_SS_PIN + #define SD_SS_PIN P1_23 +#endif +#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h + #undef SDSS + #define SDSS SD_SS_PIN +#endif diff --git a/Marlin/src/HAL/LPC4078/timers.cpp b/Marlin/src/HAL/LPC4078/timers.cpp new file mode 100644 index 0000000000..eb6d8a70ae --- /dev/null +++ b/Marlin/src/HAL/LPC4078/timers.cpp @@ -0,0 +1,65 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com + * + * 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 . + * + */ + +/** + * Description: + * + * Timers for LPC1768 + */ + +#ifdef TARGET_LPC4078 + +#include "../../inc/MarlinConfig.h" + +void HAL_timer_init() { + SBI(MCUI::system_control.PCONP, SBIT_TIMER0); // Power ON Timer 0 + STEP_TIMER_REF.PR = (HAL_TIMER_RATE) / (STEPPER_TIMER_RATE) - 1; // Use prescaler to set frequency if needed + + SBI(MCUI::system_control.PCONP, SBIT_TIMER1); // Power ON Timer 1 + TEMP_TIMER_REF.PR = (HAL_TIMER_RATE) / 1000000 - 1; +} + +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { + switch (timer_num) { + case MF_TIMER_STEP: + STEP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them + STEP_TIMER_REF.MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency + STEP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable + + MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER0, MCUCore::nvic_encode_priority(0, 1, 0)); + MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0); + break; + + case MF_TIMER_TEMP: + TEMP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them + TEMP_TIMER_REF.MR0 = uint32_t(TEMP_TIMER_RATE) / frequency; + TEMP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable + + MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER1, MCUCore::nvic_encode_priority(0, 2, 0)); + MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1); + break; + + default: break; + } +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/timers.h b/Marlin/src/HAL/LPC4078/timers.h new file mode 100644 index 0000000000..3db982168f --- /dev/null +++ b/Marlin/src/HAL/LPC4078/timers.h @@ -0,0 +1,165 @@ +/** + * Marlin 3D Printer Firmware + * + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com + * + * 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 . + * + */ +#pragma once + +/** + * HAL For LPC1768 + */ + + +#include +#include + +#include "../../core/macros.h" + +#define SBIT_TIMER0 1 +#define SBIT_TIMER1 2 + +#define SBIT_CNTEN 0 + +#define SBIT_MR0I 0 // Timer 0 Interrupt when TC matches MR0 +#define SBIT_MR0R 1 // Timer 0 Reset TC on Match +#define SBIT_MR0S 2 // Timer 0 Stop TC and PC on Match +#define SBIT_MR1I 3 +#define SBIT_MR1R 4 +#define SBIT_MR1S 5 +#define SBIT_MR2I 6 +#define SBIT_MR2R 7 +#define SBIT_MR2S 8 +#define SBIT_MR3I 9 +#define SBIT_MR3R 10 +#define SBIT_MR3S 11 + +// ------------------------ +// Defines +// ------------------------ + +#define _HAL_TIMER(T) _CAT(MCUI::timer, T) +#define _HAL_TIMER_IRQ(T) TIMER##T##_IRQn +#define __HAL_TIMER_ISR(T) extern "C" void TIMER##T##_IRQHandler() +#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T) + +typedef uint32_t hal_timer_t; +#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF + +#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals + +#ifndef MF_TIMER_STEP + #define MF_TIMER_STEP 0 // Timer Index for Stepper +#endif +#ifndef MF_TIMER_PULSE + #define MF_TIMER_PULSE MF_TIMER_STEP +#endif +#ifndef MF_TIMER_TEMP + #define MF_TIMER_TEMP 1 // Timer Index for Temperature +#endif +#ifndef MF_TIMER_PWM + #define MF_TIMER_PWM 3 // Timer Index for PWM +#endif + +#define TEMP_TIMER_RATE 1000000 +#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency + +#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) +#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs +#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US) + +#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer +#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE +#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US + +#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP) +#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP) +#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP) + +#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP) +#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP) + +#ifndef HAL_STEP_TIMER_ISR + #define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP) +#endif +#ifndef HAL_TEMP_TIMER_ISR + #define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP) +#endif + +// Timer references by index +#define STEP_TIMER_REF _HAL_TIMER(MF_TIMER_STEP) +#define TEMP_TIMER_REF _HAL_TIMER(MF_TIMER_TEMP) + +// ------------------------ +// Public functions +// ------------------------ +void HAL_timer_init(); +void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency); + +FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) { + switch (timer_num) { + case MF_TIMER_STEP: STEP_TIMER_REF.MR0 = compare; break; // Stepper Timer Match Register 0 + case MF_TIMER_TEMP: TEMP_TIMER_REF.MR0 = compare; break; // Temp Timer Match Register 0 + } +} + +FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: return STEP_TIMER_REF.MR0; // Stepper Timer Match Register 0 + case MF_TIMER_TEMP: return TEMP_TIMER_REF.MR0; // Temp Timer Match Register 0 + } + return 0; +} + +FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: return STEP_TIMER_REF.TC; // Stepper Timer Count + case MF_TIMER_TEMP: return TEMP_TIMER_REF.TC; // Temp Timer Count + } + return 0; +} + +FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0); break; // Enable interrupt handler + case MF_TIMER_TEMP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1); break; // Enable interrupt handler + } +} + +FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER0); break; // Disable interrupt handler + case MF_TIMER_TEMP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER1); break; // Disable interrupt handler + } +} + +FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER0); // Check if interrupt is enabled or not + case MF_TIMER_TEMP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER1); // Check if interrupt is enabled or not + } + return false; +} + +FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) { + switch (timer_num) { + case MF_TIMER_STEP: SBI(STEP_TIMER_REF.IR, SBIT_CNTEN); break; + case MF_TIMER_TEMP: SBI(TEMP_TIMER_REF.IR, SBIT_CNTEN); break; + } +} + +#define HAL_timer_isr_epilogue(T) NOOP diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.cpp b/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.cpp new file mode 100644 index 0000000000..e714c3c16d --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.cpp @@ -0,0 +1,89 @@ +/** + * 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 . + * + */ + +// adapted from I2C/master/master.c example +// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html + +#ifdef TARGET_LPC1768 + +#include "../include/i2c_util.h" +#include "../../../core/millis_t.h" + +extern int millis(); + +#ifdef __cplusplus + extern "C" { +#endif + +////////////////////////////////////////////////////////////////////////////////////// + +#define I2CDEV_S_ADDR 0x78 // From SSD1306 (actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write) + +// Send slave address and write bit +uint8_t u8g_i2c_start(const uint8_t sla) { + // Sometimes TX data ACK or NAK status is returned. That mean the start state didn't + // happen which means only the value of the slave address was send. Keep looping until + // the slave address and write bit are actually sent. + do{ + _I2C_Stop(I2CDEV_M); // output stop state on I2C bus + _I2C_Start(I2CDEV_M); // output start state on I2C bus + while ((I2C_status != I2C_I2STAT_M_TX_START) + && (I2C_status != I2C_I2STAT_M_TX_RESTART) + && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted + + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address + LPC_I2C1->I2DAT = I2CDEV_S_ADDR & I2C_I2DAT_BITMASK; // transmit slave address & write bit + LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; + while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK) + && (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for slaw to finish + }while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK)); + return 1; +} + +void u8g_i2c_init(const uint8_t clock_option) { + configure_i2c(clock_option); + u8g_i2c_start(0); // Send slave address and write bit +} + +uint8_t u8g_i2c_send_byte(uint8_t data) { + #define I2C_TIMEOUT 3 + LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data + LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; + const millis_t timeout = millis() + I2C_TIMEOUT; + while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(millis(), timeout)); // wait for xmit to finish + // had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens + return 1; +} + +void u8g_i2c_stop() { +} + +#ifdef __cplusplus + } +#endif + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.h b/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.h new file mode 100644 index 0000000000..2d976c92d2 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_I2C_routines.h @@ -0,0 +1,28 @@ +/** + * 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 . + * + */ +#pragma once + +void u8g_i2c_init(const uint8_t clock_options); +//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos); +uint8_t u8g_i2c_start(uint8_t sla); +uint8_t u8g_i2c_send_byte(uint8_t data); +void u8g_i2c_stop(); diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_defines.h b/Marlin/src/HAL/LPC4078/u8g/LCD_defines.h new file mode 100644 index 0000000000..5b58f1223a --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_defines.h @@ -0,0 +1,46 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * LPC1768 LCD-specific defines + */ + +#ifndef U8G_HAL_LINKS + + #define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn // See U8glib-HAL + +#else + + uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + + #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_LPC1768_sw_spi_fn + #define U8G_COM_HAL_HW_SPI_FN u8g_com_HAL_LPC1768_hw_spi_fn + #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn + #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn + #define U8G_COM_SSD_I2C_HAL u8g_com_HAL_LPC1768_ssd_hw_i2c_fn + +#endif diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_delay.h b/Marlin/src/HAL/LPC4078/u8g/LCD_delay.h new file mode 100644 index 0000000000..0b9e2b4fd0 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_delay.h @@ -0,0 +1,43 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * LCD delay routines - used by all the drivers. + * + * These are based on the LPC1768 routines. + * + * Couldn't just call exact copies because the overhead + * results in a one microsecond delay taking about 4µS. + */ + +#ifdef __cplusplus + extern "C" { +#endif + +void U8g_delay(int msec); +void u8g_MicroDelay(); +void u8g_10MicroDelay(); + +#ifdef __cplusplus + } +#endif diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.cpp b/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.cpp new file mode 100644 index 0000000000..4635beda8c --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.cpp @@ -0,0 +1,59 @@ +/** + * 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 . + * + */ + +/** + * Low level pin manipulation routines - used by all the drivers. + * + * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. + * + * Couldn't just call exact copies because the overhead killed the LCD update speed + * With an intermediate level the softspi was running in the 10-20kHz range which + * resulted in using about about 25% of the CPU's time. + */ + +#ifdef TARGET_LPC4078 + +#include + +extern "C" { + +#include "LCD_pin_routines.h" + +void u8g_SetPinOutput(uint8_t pin) { + MCUI::gpio_set_output(pin); +} + +void u8g_SetPinInput(uint8_t pin) { + MCUI::gpio_set_input(pin); +} + +void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) { + MCUI::gpio_set(pin, pin_status); +} + +uint8_t u8g_GetPinLevel(uint8_t pin) { + return MCUI::gpio_get(pin); +} + +} + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.h b/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.h new file mode 100644 index 0000000000..d60d93dadd --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/LCD_pin_routines.h @@ -0,0 +1,37 @@ +/** + * 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 . + * + */ +#pragma once + +/** + * Low level pin manipulation routines - used by all the drivers. + * + * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. + * + * Couldn't just call exact copies because the overhead killed the LCD update speed + * With an intermediate level the softspi was running in the 10-20kHz range which + * resulted in using about about 25% of the CPU's time. + */ + +void u8g_SetPinOutput(uint8_t internal_pin_number); +void u8g_SetPinInput(uint8_t internal_pin_number); +void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status); +uint8_t u8g_GetPinLevel(uint8_t pin); diff --git a/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp new file mode 100644 index 0000000000..ac46456409 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp @@ -0,0 +1,129 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_com_msp430_hw_spi.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2011, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef TARGET_LPC4078 + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_MARLINUI_U8GLIB + +#include +#include "../../shared/HAL_SPI.h" + +#ifndef LCD_SPI_SPEED + #ifdef SD_SPI_SPEED + #define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD + #else + #define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied + #endif +#endif + +uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_INIT: + u8g_SetPILevel(u8g, U8G_PI_CS, 1); + u8g_SetPILevel(u8g, U8G_PI_A0, 1); + u8g_SetPILevel(u8g, U8G_PI_RESET, 1); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPIOutput(u8g, U8G_PI_A0); + u8g_SetPIOutput(u8g, U8G_PI_RESET); + u8g_Delay(5); + spiBegin(); + spiInit(LCD_SPI_SPEED); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_SetPILevel(u8g, U8G_PI_A0, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g_SetPILevel(u8g, U8G_PI_CS, (arg_val ? 0 : 1)); + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + spiSend((uint8_t)arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + spiSend(*ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + spiSend(*ptr++); + arg_val--; + } + } + break; + } + return 1; +} + +#endif // HAS_MARLINUI_U8GLIB + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp new file mode 100644 index 0000000000..bf76eaf0f4 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp @@ -0,0 +1,198 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_com_arduino_ssd_i2c.c + * + * COM interface for Arduino (AND ATmega) and the SSDxxxx chip (SOLOMON) variant + * I2C protocol + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2011, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * Special pin usage: + * U8G_PI_I2C_OPTION additional options + * U8G_PI_A0_STATE used to store the last value of the command/data register selection + * U8G_PI_SET_A0 1: Signal request to update I2C device with new A0_STATE, 0: Do nothing, A0_STATE matches I2C device + * U8G_PI_SCL clock line (NOT USED) + * U8G_PI_SDA data line (NOT USED) + * + * U8G_PI_RESET reset line (currently disabled, see below) + * + * Protocol: + * SLA, Cmd/Data Selection, Arguments + * The command/data register is selected by a special instruction byte, which is sent after SLA + * + * The continue bit is always 0 so that a (re)start is equired for the change from cmd to/data mode + */ + +#ifdef TARGET_LPC1768 + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_MARLINUI_U8GLIB + +#include + +#define I2C_SLA (0x3C*2) +//#define I2C_CMD_MODE 0x080 +#define I2C_CMD_MODE 0x000 +#define I2C_DATA_MODE 0x040 + +uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) { + /* are we requested to set the a0 state? */ + if (u8g->pin_list[U8G_PI_SET_A0] == 0) return 1; + + /* setup bus, might be a repeated start */ + if (u8g_i2c_start(I2C_SLA) == 0) return 0; + if (u8g->pin_list[U8G_PI_A0_STATE] == 0) { + if (u8g_i2c_send_byte(I2C_CMD_MODE) == 0) return 0; + } + else if (u8g_i2c_send_byte(I2C_DATA_MODE) == 0) + return 0; + + u8g->pin_list[U8G_PI_SET_A0] = 0; + return 1; +} + +uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_INIT: + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH); + //u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH); + //u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: unknown mode */ + + u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]); + u8g_com_ssd_I2C_start_sequence(u8g); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + /* Currently disabled, but it could be enable. Previous restrictions have been removed */ + /* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */ + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g->pin_list[U8G_PI_A0_STATE] = 0; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */ + if (arg_val == 0 ) { + /* disable chip, send stop condition */ + u8g_i2c_stop(); + } + else { + /* enable, do nothing: any byte writing will trigger the i2c start */ + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) { + u8g_i2c_stop(); + return 0; + } + + if (u8g_i2c_send_byte(arg_val) == 0) { + u8g_i2c_stop(); + return 0; + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) { + u8g_i2c_stop(); + return 0; + } + + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + if (u8g_i2c_send_byte(*ptr++) == 0) { + u8g_i2c_stop(); + return 0; + } + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) { + u8g_i2c_stop(); + return 0; + } + + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + if (u8g_i2c_send_byte(u8g_pgm_read(ptr)) == 0) + return 0; + ptr++; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */ + break; + + } // switch + return 1; +} + +#endif // HAS_MARLINUI_U8GLIB + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp new file mode 100644 index 0000000000..c96e0f56f4 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp @@ -0,0 +1,138 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_com_LPC1768_st7920_hw_spi.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2011, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef TARGET_LPC4078 + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_MARLINUI_U8GLIB + +#include +#include "../../shared/HAL_SPI.h" +#include "../../shared/Delay.h" + +void spiBegin(); +void spiInit(uint8_t spiRate); +void spiSend(uint8_t b); +void spiSend(const uint8_t *buf, size_t n); + +static uint8_t rs_last_state = 255; + +static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) { + + if (rs != rs_last_state) { // Time to send a command/data byte + rs_last_state = rs; + spiSend(rs ? 0x0FA : 0x0F8); // Send data or command + DELAY_US(40); // Give the controller some time: 20 is bad, 30 is OK, 40 is safe + } + + spiSend(val & 0xF0); + spiSend(val << 4); +} + +uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_INIT: + u8g_SetPILevel(u8g, U8G_PI_CS, 0); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_Delay(5); + spiBegin(); + spiInit(SPI_EIGHTH_SPEED); // ST7920 max speed is about 1.1 MHz + u8g->pin_list[U8G_PI_A0_STATE] = 0; // initial RS state: command mode + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1) + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); // Note: the ST7920 has an active high chip-select + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + } + return 1; +} + +#endif // HAS_MARLINUI_U8GLIB + +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp new file mode 100644 index 0000000000..436a972850 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp @@ -0,0 +1,147 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_com_st7920_hw_spi.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2011, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef TARGET_LPC4078 + +#include "../../../inc/MarlinConfigPre.h" + +#if IS_U8GLIB_ST7920 + +#include +#include "../SoftwareSPI.h" +#include "../../shared/Delay.h" +#include "../../shared/HAL_SPI.h" + +#ifndef LCD_SPI_SPEED + #define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz +#endif + +static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL; +static uint8_t SPI_speed = 0; + +static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) { + static uint8_t rs_last_state = 255; + if (rs != rs_last_state) { + // Transfer Data (FA) or Command (F8) + swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); + rs_last_state = rs; + DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe + } + swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); + swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL); +} + +uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_INIT: + SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK]; + MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI]; + + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPIOutput(u8g, U8G_PI_SCK); + u8g_SetPIOutput(u8g, U8G_PI_MOSI); + u8g_Delay(5); + + SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL); + + u8g_SetPILevel(u8g, U8G_PI_CS, 0); + u8g_SetPILevel(u8g, U8G_PI_SCK, 0); + u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); + + u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */ + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + + case U8G_COM_MSG_CHIP_SELECT: + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + uint8_t *ptr = (uint8_t*) arg_ptr; + while (arg_val > 0) { + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + } + return 1; +} + +#endif // IS_U8GLIB_ST7920 +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp new file mode 100644 index 0000000000..03cd7b48a9 --- /dev/null +++ b/Marlin/src/HAL/LPC4078/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp @@ -0,0 +1,209 @@ +/** + * 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 . + * + */ + +/** + * Based on u8g_com_std_sw_spi.c + * + * Universal 8bit Graphics Library + * + * Copyright (c) 2015, olikraus@gmail.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef TARGET_LPC4078 + +#include "../../../inc/MarlinConfigPre.h" + +#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 + +#include +#include "../../shared/HAL_SPI.h" + +#ifndef LCD_SPI_SPEED + #define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz +#endif + +#include +#include +#include +#include + +#include + +uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { + + LOOP_L_N(i, 8) { + if (spi_speed == 0) { + LPC176x::gpio_set(mosi_pin, !!(b & 0x80)); + LPC176x::gpio_set(sck_pin, HIGH); + b <<= 1; + if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; + LPC176x::gpio_set(sck_pin, LOW); + } + else { + const uint8_t state = (b & 0x80) ? HIGH : LOW; + LOOP_L_N(j, spi_speed) + LPC176x::gpio_set(mosi_pin, state); + + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) + LPC176x::gpio_set(sck_pin, HIGH); + + b <<= 1; + if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; + + LOOP_L_N(j, spi_speed) + LPC176x::gpio_set(sck_pin, LOW); + } + } + + return b; +} + +uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) { + + LOOP_L_N(i, 8) { + const uint8_t state = (b & 0x80) ? HIGH : LOW; + if (spi_speed == 0) { + LPC176x::gpio_set(sck_pin, LOW); + LPC176x::gpio_set(mosi_pin, state); + LPC176x::gpio_set(mosi_pin, state); // need some setup time + LPC176x::gpio_set(sck_pin, HIGH); + } + else { + LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1)) + LPC176x::gpio_set(sck_pin, LOW); + + LOOP_L_N(j, spi_speed) + LPC176x::gpio_set(mosi_pin, state); + + LOOP_L_N(j, spi_speed) + LPC176x::gpio_set(sck_pin, HIGH); + } + b <<= 1; + if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1; + } + + return b; +} + +static uint8_t SPI_speed = 0; + +static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) { + #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) + swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin); + #else + swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin); + #endif +} + +uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) { + switch (msg) { + case U8G_COM_MSG_INIT: + u8g_SetPIOutput(u8g, U8G_PI_SCK); + u8g_SetPIOutput(u8g, U8G_PI_MOSI); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPIOutput(u8g, U8G_PI_A0); + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET); + SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]); + u8g_SetPILevel(u8g, U8G_PI_SCK, 0); + u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + #if EITHER(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0 + if (arg_val) { // SCK idle state needs to be set to the proper idle state before + // the next chip select goes active + u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active + u8g_SetPILevel(u8g, U8G_PI_CS, LOW); + } + else { + u8g_SetPILevel(u8g, U8G_PI_CS, HIGH); + u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive + } + #else + u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val); + #endif + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: { + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: { + uint8_t *ptr = (uint8_t *)arg_ptr; + while (arg_val > 0) { + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_SetPILevel(u8g, U8G_PI_A0, arg_val); + break; + } + return 1; +} + +#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920 +#endif // TARGET_LPC4078 diff --git a/Marlin/src/HAL/platforms.h b/Marlin/src/HAL/platforms.h index 9eaf7cea98..c8e644087b 100644 --- a/Marlin/src/HAL/platforms.h +++ b/Marlin/src/HAL/platforms.h @@ -37,6 +37,8 @@ #define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC1768/NAME) #elif defined(ARDUINO_ARCH_HC32) #define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/HC32/NAME) +#elif defined(TARGET_LPC4078) + #define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC4078/NAME) #elif defined(__STM32F1__) || defined(TARGET_STM32F1) #define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/STM32F1/NAME) #elif defined(ARDUINO_ARCH_STM32) diff --git a/Marlin/src/HAL/shared/servo.h b/Marlin/src/HAL/shared/servo.h index 786c1e6a72..434e5b4055 100644 --- a/Marlin/src/HAL/shared/servo.h +++ b/Marlin/src/HAL/shared/servo.h @@ -76,6 +76,8 @@ #include "../LPC1768/Servo.h" #elif defined(ARDUINO_ARCH_HC32) #include "../HC32/Servo.h" +#elif defined(TARGET_LPC4078) + #include "../LPC4078/Servo.h" #elif defined(__STM32F1__) || defined(TARGET_STM32F1) #include "../STM32F1/Servo.h" #elif defined(ARDUINO_ARCH_STM32) diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index 21aeab6c3b..1c90e3c734 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -410,6 +410,7 @@ #define BOARD_TEENSY31_32 5100 // Teensy3.1 and Teensy3.2 #define BOARD_TEENSY35_36 5101 // Teensy3.5 and Teensy3.6 +#define BOARD_EBAB 5102 // // STM32 ARM Cortex-M4F diff --git a/Marlin/src/pins/lpc4078/pins_EBAB.h b/Marlin/src/pins/lpc4078/pins_EBAB.h new file mode 100644 index 0000000000..83fa5bac4f --- /dev/null +++ b/Marlin/src/pins/lpc4078/pins_EBAB.h @@ -0,0 +1,605 @@ +/** + * 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 . + * + */ +#pragma once + +#ifndef BOARD_INFO_NAME + #define BOARD_INFO_NAME "Extra Big Ass Board" +#endif + +#ifndef DEFAULT_MACHINE_NAME + #define DEFAULT_MACHINE_NAME "XtraBigAssBoard" +#endif + +#define LED_PIN P3_18 // PWM0_3 + +// EXTRA PINS +#define FIL_RUNOUT_PIN P1_12 +#define PS_ON_PIN P3_15 + +// DRIVERS EXTRA PINS +#define DRIVERS_SCK P1_20 +#define DRIVERS_MISO P1_23 +#define DRIVERS_MOSI P1_24 + + +// +// Servos +// +#define SERVO0_PIN P2_05 // PWM1_6 +#define SERVO1_PIN P2_04 // PWM1_5 +#define SERVO2_PIN P2_03 // PWM1_4 +#define SERVO3_PIN P2_02 // PWM1_3 + + +// +// Limit Switches +// +#define X_MIN_PIN P0_19 +#define X_MAX_PIN P0_18 +#define Y_MIN_PIN P0_20 +#define Y_MAX_PIN P0_17 +#define Z_MIN_PIN P0_21 +#define Z_MAX_PIN P0_15 + +// +// Z Probe (when not Z_MIN_PIN) +// +#ifndef Z_MIN_PROBE_PIN + #define Z_MIN_PROBE_PIN P0_21 +#endif + +// +// Steppers +// +#define X_STEP_PIN P0_10 +#define X_DIR_PIN P4_03 +#define X_ENABLE_PIN P0_01 +#define X_CS_PIN P0_00 +#define X_DIAG_PIN P2_17 + +#define Y_STEP_PIN P1_29 +#define Y_DIR_PIN P2_14 +#define Y_ENABLE_PIN P1_28 +#define Y_CS_PIN P2_22 +#define Y_DIAG_PIN P2_16 + +#define Z_STEP_PIN P4_02 +#define Z_DIR_PIN P1_26 +#define Z_ENABLE_PIN P1_25 +#define Z_CS_PIN P4_01 +#define Z_DIAG_PIN P2_21 + +#define E0_STEP_PIN P1_19 +#define E0_DIR_PIN P0_14 +#define E0_ENABLE_PIN P1_22 +#define E0_CS_PIN P4_00 +#define E0_DIAG_PIN P2_20 + +#define E1_STEP_PIN P2_23 +#define E1_DIR_PIN P2_18 +#define E1_ENABLE_PIN P3_23 +#define E1_CS_PIN P1_18 +#define E1_DIAG_PIN P2_19 + +#define E2_STEP_PIN P3_26 +#define E2_DIR_PIN P2_25 +#define E2_ENABLE_PIN P3_25 +#define E2_CS_PIN P3_24 +#define E2_DIAG_PIN P2_26 + +#define E3_STEP_PIN P4_19 +#define E3_DIR_PIN P4_20 +#define E3_ENABLE_PIN P4_26 +#define E3_CS_PIN P4_21 +#define E3_DIAG_PIN P0_22 + +#define E4_STEP_PIN P4_17 +#define E4_DIR_PIN P4_18 +#define E4_ENABLE_PIN P4_05 +#define E4_CS_PIN P2_12 +#define E4_DIAG_PIN P2_11 + +#define E5_STEP_PIN P0_11 +#define E5_DIR_PIN P2_15 +#define E5_ENABLE_PIN P4_04 +#define E5_CS_PIN P4_16 +#define E5_DIAG_PIN P2_13 + +#define E6_STEP_PIN P2_28 +#define E6_DIR_PIN P0_28 +#define E6_ENABLE_PIN P0_31 +#define E6_CS_PIN P0_27 +#define E6_DIAG_PIN P2_24 + +#define E7_STEP_PIN P1_30 +#define E7_DIR_PIN P0_12 +#define E7_ENABLE_PIN P0_13 +#define E7_CS_PIN P2_29 +#define E7_DIAG_PIN P2_27 + +#define E8_STEP_PIN P3_15 +#define E8_DIR_PIN P3_07 +#define E8_ENABLE_PIN P2_30 +#define E8_CS_PIN P5_01 +#define E8_DIAG_PIN P2_31 + + +#if HAS_TMC_UART + #define X_SERIAL_TX_PIN P0_00 + #define X_SERIAL_RX_PIN P0_00 + #define Y_SERIAL_TX_PIN P2_22 + #define Y_SERIAL_RX_PIN P2_22 + #define Z_SERIAL_TX_PIN P4_01 + #define Z_SERIAL_RX_PIN P4_01 + #define E0_SERIAL_TX_PIN P4_00 + #define E0_SERIAL_RX_PIN P4_00 + #define E1_SERIAL_TX_PIN P1_18 + #define E1_SERIAL_RX_PIN P1_18 + #define E2_SERIAL_TX_PIN P3_24 + #define E2_SERIAL_RX_PIN P3_24 + #define E3_SERIAL_TX_PIN P4_21 + #define E3_SERIAL_RX_PIN P4_21 + #define E4_SERIAL_TX_PIN P2_12 + #define E4_SERIAL_RX_PIN P2_12 + #define E5_SERIAL_TX_PIN P4_16 + #define E5_SERIAL_RX_PIN P4_16 + #define E6_SERIAL_TX_PIN P0_27 + #define E6_SERIAL_RX_PIN P0_27 + #define E7_SERIAL_TX_PIN P2_29 + #define E7_SERIAL_RX_PIN P2_29 + #define E8_SERIAL_TX_PIN P5_01 + #define E8_SERIAL_RX_PIN P5_01 + + // Reduce baud rate to improve software serial reliability + #define TMC_BAUD_RATE 19200 +#endif // HAS_TMC_UART + +// +// Temperature Sensors +// +#define TEMP_0_PIN P0_23 +#define TEMP_1_PIN P0_24 +#define TEMP_2_PIN P0_25 +#define TEMP_3_PIN P0_26 +#define TEMP_BED_PIN P1_31 + +// +// Heaters / Fans +// + +#define HEATER_0_PIN P1_02 +#define HEATER_1_PIN P1_10 +#define HEATER_2_PIN P4_30 +#define HEATER_3_PIN P1_09 +#define HEATER_BED_PIN P4_23 + +#define FAN0_PIN P3_08 +#define FAN1_PIN P3_00 +#define FAN2_PIN P3_27 //PWM1_4 +#define FAN3_PIN P5_04 + +#define EFAN0_PIN P1_08 +#define EFAN1_PIN P4_31 +#define EFAN2_PIN P3_01 +#define EFAN3_PIN P3_10 +// +// Misc. Functions +// +#if SD_CONNECTION_IS(LCD) + #define SD_DETECT_PIN P3_02 + #define SD_SCK_PIN P1_00 + #define SD_MISO_PIN P1_04 + #define SD_MOSI_PIN P1_01 + #define SD_SS_PIN P3_03 + #define SDSS SD_SS_PIN +#elif SD_CONNECTION_IS(ONBOARD) + #define SD_DETECT_PIN P_NC + #define SD_SCK_PIN P0_07 + #define SD_MISO_PIN P0_08 + #define SD_MOSI_PIN P0_09 + #define ONBOARD_SD_CS_PIN P0_06 + #define SD_SS_PIN ONBOARD_SD_CS_PIN + #define SDSS SD_SS_PIN +#endif + +#ifndef NEOPIXEL_PIN + #define NEOPIXEL_PIN P_NC +#endif + +#ifndef FILWIDTH_PIN + #define FILWIDTH_PIN P_NC +#endif + +#ifndef FIL_RUNOUT_PIN + #define FIL_RUNOUT_PIN P_NC +#endif + +#ifndef PS_ON_PIN + #define PS_ON_PIN P_NC +#endif + +// +// Průša i3 MK2 Multiplexer Support +// +#if HAS_PRUSA_MMU1 + #ifndef E_MUX0_PIN + #define E_MUX0_PIN P_NC + #endif + #ifndef E_MUX1_PIN + #define E_MUX1_PIN P_NC + #endif + #ifndef E_MUX2_PIN + #define E_MUX2_PIN P_NC + #endif +#endif + +/** + * Default pins for TMC software SPI + */ +#if ENABLED(TMC_USE_SW_SPI) + #ifndef TMC_SW_MOSI + #define TMC_SW_MOSI P1_24 + #endif + #ifndef TMC_SW_MISO + #define TMC_SW_MISO P1_23 + #endif + #ifndef TMC_SW_SCK + #define TMC_SW_SCK P1_20 + #endif +#endif + + +////////////////////////// +// LCDs and Controllers // +////////////////////////// + +#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI) + + #define TFT_A0_PIN 43 + #define TFT_CS_PIN 49 + #define TFT_DC_PIN 43 + #define TFT_SCK_PIN SD_SCK_PIN + #define TFT_MOSI_PIN SD_MOSI_PIN + #define TFT_MISO_PIN SD_MISO_PIN + #define LCD_USE_DMA_SPI + + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 + #define BEEPER_PIN 42 + + #define TOUCH_CS_PIN 33 + + #define SD_DETECT_PIN 41 + + #define SPI_FLASH + #if ENABLED(SPI_FLASH) + #define SPI_DEVICE 1 + #define SPI_FLASH_SIZE 0x1000000 // 16MB + #define SPI_FLASH_CS_PIN 31 + #define SPI_FLASH_MOSI_PIN SD_MOSI_PIN + #define SPI_FLASH_MISO_PIN SD_MISO_PIN + #define SPI_FLASH_SCK_PIN SD_SCK_PIN + #endif + + #define TFT_BUFFER_SIZE 0xFFFF + #ifndef TFT_DRIVER + #define TFT_DRIVER ST7796 + #endif + #ifndef TOUCH_SCREEN_CALIBRATION + #if ENABLED(TFT_RES_320x240) + #ifndef TOUCH_CALIBRATION_X + #define TOUCH_CALIBRATION_X 20525 + #endif + #ifndef TOUCH_CALIBRATION_Y + #define TOUCH_CALIBRATION_Y 15335 + #endif + #ifndef TOUCH_OFFSET_X + #define TOUCH_OFFSET_X -1 + #endif + #ifndef TOUCH_OFFSET_Y + #define TOUCH_OFFSET_Y 0 + #endif + #elif ENABLED(TFT_RES_480x272) + #ifndef TOUCH_CALIBRATION_X + #define TOUCH_CALIBRATION_X 30715 + #endif + #ifndef TOUCH_CALIBRATION_Y + #define TOUCH_CALIBRATION_Y 17415 + #endif + #ifndef TOUCH_OFFSET_X + #define TOUCH_OFFSET_X 0 + #endif + #ifndef TOUCH_OFFSET_Y + #define TOUCH_OFFSET_Y -1 + #endif + #elif ENABLED(TFT_RES_480x320) + #ifndef TOUCH_CALIBRATION_X + #define TOUCH_CALIBRATION_X 30595 + #endif + #ifndef TOUCH_CALIBRATION_Y + #define TOUCH_CALIBRATION_Y 20415 + #endif + #ifndef TOUCH_OFFSET_X + #define TOUCH_OFFSET_X 2 + #endif + #ifndef TOUCH_OFFSET_Y + #define TOUCH_OFFSET_Y 1 + #endif + #elif ENABLED(TFT_RES_1024x600) + #ifndef TOUCH_CALIBRATION_X + #define TOUCH_CALIBRATION_X 65533 + #endif + #ifndef TOUCH_CALIBRATION_Y + #define TOUCH_CALIBRATION_Y 38399 + #endif + #ifndef TOUCH_OFFSET_X + #define TOUCH_OFFSET_X 2 + #endif + #ifndef TOUCH_OFFSET_Y + #define TOUCH_OFFSET_Y 1 + #endif + #endif + #endif + + #define BTN_BACK 70 + +#elif HAS_WIRED_LCD + + // + // LCD Display output pins + // + #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define LCD_PINS_RS P3_06 // CS chip select /SS chip slave select + #define LCD_PINS_EN P3_14 // SID (MOSI) + #define LCD_PINS_D4 P3_30 // SCK (CLK) clock + + #elif ALL(IS_NEWPANEL, PANEL_ONE) + + #define LCD_PINS_RS 40 + #define LCD_PINS_EN 42 + #define LCD_PINS_D4 65 + #define LCD_PINS_D5 66 + #define LCD_PINS_D6 44 + #define LCD_PINS_D7 64 + + #else + + #if ENABLED(CR10_STOCKDISPLAY) + + #define LCD_PINS_RS 27 + #define LCD_PINS_EN 29 + #define LCD_PINS_D4 25 + + #if !IS_NEWPANEL + #define BEEPER_PIN 37 + #endif + + #elif ENABLED(ZONESTAR_LCD) + + #define LCD_PINS_RS 64 + #define LCD_PINS_EN 44 + #define LCD_PINS_D4 63 + #define LCD_PINS_D5 40 + #define LCD_PINS_D6 42 + #define LCD_PINS_D7 65 + + #else + + #if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306) + #define LCD_PINS_DC 25 // Set as output on init + #define LCD_PINS_RS 27 // Pull low for 1s to init + // DOGM SPI LCD Support + #define DOGLCD_CS 16 + #define DOGLCD_MOSI 17 + #define DOGLCD_SCK 23 + #define DOGLCD_A0 LCD_PINS_DC + #else + #define LCD_PINS_RS P3_06 + #define LCD_PINS_EN P3_14 + #define LCD_PINS_D4 P3_30 + #define LCD_PINS_D5 P3_05 + #define LCD_PINS_D6 P3_29 + #endif + + #define LCD_PINS_D7 P5_00 + + #if !IS_NEWPANEL + #define BEEPER_PIN 33 + #endif + + #endif + + #if !IS_NEWPANEL + // Buttons attached to a shift register + // Not wired yet + //#define SHIFT_CLK_PIN 38 + //#define SHIFT_LD_PIN 42 + //#define SHIFT_OUT_PIN 40 + //#define SHIFT_EN_PIN 17 + #endif + + #endif + + // + // LCD Display input pins + // + #if IS_NEWPANEL + + #if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) + + #define BEEPER_PIN P3_31 + + #if ENABLED(CR10_STOCKDISPLAY) + #define BTN_EN1 17 + #define BTN_EN2 23 + #else + #define BTN_EN1 P3_11 + #define BTN_EN2 P3_12 + #endif + + #define BTN_ENC P3_28 + #define SD_DETECT_PIN P3_02 + //#define KILL_PIN P_NC + + #if ENABLED(BQ_LCD_SMART_CONTROLLER) + #define LCD_BACKLIGHT_PIN 39 + #endif + + #elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD) + + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #define SD_DETECT_PIN 42 + + #elif ENABLED(LCD_I2C_PANELOLU2) + + #define BTN_EN1 47 + #define BTN_EN2 43 + #define BTN_ENC 32 + #define LCD_SDSS SDSS + #define KILL_PIN 41 + + #elif ENABLED(LCD_I2C_VIKI) + + #define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42. + #define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13. + #define BTN_ENC -1 + + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 + + #elif ANY(VIKI2, miniVIKI) + + #define DOGLCD_CS 45 + #define DOGLCD_A0 44 + + #define BEEPER_PIN 33 + #define STAT_LED_RED_PIN 32 + #define STAT_LED_BLUE_PIN 35 + + #define BTN_EN1 22 + #define BTN_EN2 7 + #define BTN_ENC 39 + + #define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board + #define KILL_PIN 31 + + #define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270 + + #elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) + + #define DOGLCD_CS 29 + #define DOGLCD_A0 27 + + #define BEEPER_PIN 23 + #define LCD_BACKLIGHT_PIN 33 + + #define BTN_EN1 35 + #define BTN_EN2 37 + #define BTN_ENC 31 + + #define LCD_SDSS SDSS + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + + #elif ENABLED(MKS_MINI_12864) + + #define DOGLCD_A0 27 + #define DOGLCD_CS 25 + + #define BEEPER_PIN 37 + // not connected to a pin + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + + #define BTN_EN1 31 + #define BTN_EN2 33 + #define BTN_ENC 35 + + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 + + //#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270 + + #elif ENABLED(MINIPANEL) + + #define BEEPER_PIN 42 + // not connected to a pin + #define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65 + + #define DOGLCD_A0 44 + #define DOGLCD_CS 66 + + #define BTN_EN1 40 + #define BTN_EN2 63 + #define BTN_ENC 59 + + #define SD_DETECT_PIN 49 + #define KILL_PIN 64 + + //#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270 + + #elif ENABLED(ZONESTAR_LCD) + + #define ADC_KEYPAD_PIN 12 + + #elif ENABLED(AZSMZ_12864) + + // Pins only defined for RAMPS_SMART currently + + #else + + // Beeper on AUX-4 + #define BEEPER_PIN P3_31 + + // Buttons are directly attached to AUX-2 + #if IS_RRW_KEYPAD + #define SHIFT_OUT_PIN 40 + #define SHIFT_CLK_PIN 44 + #define SHIFT_LD_PIN 42 + #define BTN_EN1 64 + #define BTN_EN2 59 + #define BTN_ENC 63 + #elif ENABLED(PANEL_ONE) + #define BTN_EN1 59 // AUX2 PIN 3 + #define BTN_EN2 63 // AUX2 PIN 4 + #define BTN_ENC 49 // AUX3 PIN 7 + #else + #define BTN_EN1 P3_11 + #define BTN_EN2 P3_12 + #define BTN_ENC P3_28 + #endif + + #if ENABLED(G3D_PANEL) + #define SD_DETECT_PIN 49 + #define KILL_PIN 41 + #endif + #endif + + // CUSTOM SIMULATOR INPUTS + #define BTN_BACK 70 + + #endif // IS_NEWPANEL + +#endif // HAS_WIRED_LCD diff --git a/Marlin/src/pins/pins.h b/Marlin/src/pins/pins.h index a9349910d7..b03f77fa51 100644 --- a/Marlin/src/pins/pins.h +++ b/Marlin/src/pins/pins.h @@ -504,6 +504,13 @@ #include "lpc1769/pins_BTT_SKR_E3_TURBO.h" // LPC1769 env:LPC1769 #elif MB(FLY_CDY) #include "lpc1769/pins_FLY_CDY.h" // LPC1769 env:LPC1769 +// +// LPC4078 ARM Cortex M4 +// + +#elif MB(EBAB) + #include "lpc4078/pins_EBAB.h" // LPC4078 env:LPC4078 + // // Due (ATSAM) boards diff --git a/ini/lpc176x.ini b/ini/lpc176x.ini index 8d5d2fd157..974debe59e 100644 --- a/ini/lpc176x.ini +++ b/ini/lpc176x.ini @@ -42,3 +42,27 @@ board = nxp_lpc1768 [env:LPC1769] extends = common_LPC board = nxp_lpc1769 + +# +# NXP LPC4078 ARM Cortex-M4 +# +[env:LPC4078] +board = nxp_lpc4078 +platform = symlink://C:\Users\DMenzel\Documents\GitHub\EBAB\ebab_platform\platform-mcui +platform_packages = framework-arduino-mcui@symlink://C:\Users\DMenzel\Documents\GitHub\EBAB\ebab_platform\framework-arduino-mcui +framework = arduino +upload_protocol = jlink +debug_tool = jlink +monitor_speed = 500000 +lib_ldf_mode = off +lib_compat_mode = strict +extra_scripts = ${common.extra_scripts} + Marlin/src/HAL/LPC1768/upload_extra_script.py +build_src_filter = ${common.default_src_filter} + + +build_flags = ${common.build_flags} -IMarlin/src/HAL/LPC4078/include -DTARGET_LPC4078 -DU8G_HAL_LINKS -IMarlin/src/HAL/LPC4078/u8g -DPLATFORM_M997_SUPPORT -O3 +build_unflags = -Os +lib_deps = ${common.lib_deps} + Servo + SoftwareSerial +custom_marlin.USES_LIQUIDCRYSTAL = arduino-libraries/LiquidCrystal@~1.0.7 +custom_marlin.NEOPIXEL_LED = Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/1.5.0.zip