This commit is contained in:
Xavier Perignon
2020-06-15 14:28:33 +02:00
parent ba2f460a43
commit b5c4eadb9b
4306 changed files with 1564605 additions and 1003297 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,891 +0,0 @@
# Marlin Firmware Arduino Project Makefile
#
# Makefile Based on:
# Arduino 0011 Makefile
# Arduino adaptation by mellis, eighthave, oli.keller
# Marlin adaption by Daid
# Marlin 2.0 support and RELOC_WORKAROUND by @marcio-ao
#
# This has been tested with Arduino 0022.
#
# This makefile allows you to build sketches from the command line
# without the Arduino environment (or Java).
#
# Detailed instructions for using the makefile:
#
# 1. Modify the line containing "ARDUINO_INSTALL_DIR" to point to the directory that
# contains the Arduino installation (for example, under Mac OS X, this
# might be /Applications/Arduino.app/Contents/Resources/Java).
#
# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename
# representing the USB or serial connection to your Arduino board
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
# changes, you can use * as a wild card (e.g. UPLOAD_PORT = /dev/tty.usb*).
#
# 3. Set the line containing "MCU" to match your board's processor.
# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
# change F_CPU to 8000000. If you are using Gen7 electronics, you
# probably need to use 20000000. Either way, you must regenerate
# the speed lookup table with create_speed_lookuptable.py.
#
# 4. Type "make" and press enter to compile/verify your program.
#
# 5. Type "make upload", reset your Arduino board, and press enter to
# upload your program to the Arduino board.
#
# Note that all settings at the top of this file can be overriden from
# the command line with, for example, "make HARDWARE_MOTHERBOARD=71"
#
# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino
#
# To compile and upload simply add "upload" to the end of the line...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino upload
#
# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or
# start upload manually (using stk500) like so:
#
# avrdude -C /root/arduino/hardware/tools/avr/etc/avrdude.conf -v -p m2560 -c stk500 \
# -U flash:w:applet/Marlin.hex:i -P /dev/ttyUSB0
#
# Or, try disconnecting USB to power down and then reconnecting before running avrdude.
#
# This defines the board to compile for (see boards.h for your board's ID)
HARDWARE_MOTHERBOARD ?= 11
# Arduino source install directory, and version number
# On most linuxes this will be /usr/share/arduino
ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino
ARDUINO_VERSION ?= 106
# The installed Libraries are in the User folder
ARDUINO_USER_DIR ?= ${HOME}/Arduino
# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin)
AVR_TOOLS_PATH ?=
#Programmer configuration
UPLOAD_RATE ?= 57600
AVRDUDE_PROGRAMMER ?= arduino
# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
UPLOAD_PORT ?= /dev/ttyUSB0
#Directory used to build files in, contains all the build files, from object files to the final hex file
#on linux it is best to put an absolute path like /home/username/tmp .
BUILD_DIR ?= applet
# This defines whether Liquid_TWI2 support will be built
LIQUID_TWI2 ?= 0
# this defines if Wire is needed
WIRE ?= 0
# this defines if U8GLIB is needed (may require RELOC_WORKAROUND)
U8GLIB ?= 1
# this defines whether to include the Trinamic TMCStepper library
TMC ?= 1
# this defines whether to include the AdaFruit NeoPixel library
NEOPIXEL ?= 0
############
# Try to automatically determine whether RELOC_WORKAROUND is needed based
# on GCC versions:
# http://www.avrfreaks.net/comment/1789106#comment-1789106
CC_MAJ:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC__ | cut -f3 -d\ )
CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ )
CC_PATCHLEVEL:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_PATCHLEVEL__ | cut -f3 -d\ )
CC_VER:=$(shell echo $$(( $(CC_MAJ) * 10000 + $(CC_MIN) * 100 + $(CC_PATCHLEVEL) )))
ifeq ($(shell test $(CC_VER) -lt 40901 && echo 1),1)
@echo This version of GCC is likely broken. Enabling relocation workaround.
RELOC_WORKAROUND = 1
endif
############################################################################
# Below here nothing should be changed...
# Here the Arduino variant is selected by the board type
# HARDWARE_VARIANT = "arduino", "Sanguino", "Gen7", ...
# MCU = "atmega1280", "Mega2560", "atmega2560", "atmega644p", ...
ifeq ($(HARDWARE_MOTHERBOARD),0)
# No motherboard selected
#
# RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560
#
# MEGA/RAMPS up to 1.2
else ifeq ($(HARDWARE_MOTHERBOARD),1000)
# RAMPS 1.3 (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1010)
# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1011)
# RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1012)
# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1013)
# RAMPS 1.3 (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1014)
# RAMPS 1.4 (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1020)
# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1021)
# RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1022)
# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1023)
# RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1024)
# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1030)
# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1031)
# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1032)
# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1033)
# RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1034)
#
# RAMPS Derivatives - ATmega1280, ATmega2560
#
# 3Drag Controller
else ifeq ($(HARDWARE_MOTHERBOARD),1100)
# Velleman K8200 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
# Velleman K8400 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),1102)
# 2PrintBeta BAM&DICE with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1103)
# 2PrintBeta BAM&DICE Due with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1104)
# MKS BASE v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
# MKS v1.4 with A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
# MKS v1.5 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
# MKS v1.6 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
# MKS GEN v1.3 or 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
# zrib V2.0 control board (Chinese knock off RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
MCU ?= atmega1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
# Raise3D Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
# Rapide Lite RL200 Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
# Formbot T-Rex 2 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
# Formbot T-Rex 3
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
# Formbot Raptor
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
# Formbot Raptor 2
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
# TriGorilla Anycubic version 1.4 Rev 1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
# FYSETC F6 1.5
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# VORON
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# TRONXY V3 1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
#
# RAMBo and derivatives
#
# Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),1200)
# Mini-Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),1201)
# Mini-Rambo 1.0a
else ifeq ($(HARDWARE_MOTHERBOARD),1202)
# Einsy Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),1203)
# Einsy Retro
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
#
# Other ATmega1280, ATmega2560
#
# Cartesio CN Controls V11
else ifeq ($(HARDWARE_MOTHERBOARD),1300)
# Cartesio CN Controls V12
else ifeq ($(HARDWARE_MOTHERBOARD),1301)
# Cartesio CN Controls V15
else ifeq ($(HARDWARE_MOTHERBOARD),1302)
# Cheaptronic v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1303)
# Cheaptronic v2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1304)
# Makerbot Mightyboard Revision E
else ifeq ($(HARDWARE_MOTHERBOARD),1305)
# Megatronics
else ifeq ($(HARDWARE_MOTHERBOARD),1306)
# Megatronics v2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1307)
# Megatronics v3.0
else ifeq ($(HARDWARE_MOTHERBOARD),1308)
# Megatronics v3.1
else ifeq ($(HARDWARE_MOTHERBOARD),1309)
# Megatronics v3.2
else ifeq ($(HARDWARE_MOTHERBOARD),1310)
# Elefu Ra Board (v3)
else ifeq ($(HARDWARE_MOTHERBOARD),1311)
# Leapfrog
else ifeq ($(HARDWARE_MOTHERBOARD),1312)
# Mega controller
else ifeq ($(HARDWARE_MOTHERBOARD),1313)
# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1314)
# Geeetech GT2560 Rev. A
else ifeq ($(HARDWARE_MOTHERBOARD),1315)
# Geeetech GT2560 Rev. A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
# Geeetech GT2560 Rev B for A10(M/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
# Geeetech GT2560 Rev B for A20(M/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
#
# ATmega1281, ATmega2561
#
# Minitronics v1.0/1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1400)
MCU ?= atmega1281
# Silvergate v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1401)
MCU ?= atmega1281
#
# Sanguinololu and Derivatives - ATmega644P, ATmega1284P
#
# Sanguinololu < 1.2
else ifeq ($(HARDWARE_MOTHERBOARD),1500)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Sanguinololu 1.2 and above
else ifeq ($(HARDWARE_MOTHERBOARD),1501)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Melzi
else ifeq ($(HARDWARE_MOTHERBOARD),1502)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Melzi with ATmega1284 (MaKr3d version)
else ifeq ($(HARDWARE_MOTHERBOARD),1503)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Melzi Creality3D board (for CR-10 etc)
else ifeq ($(HARDWARE_MOTHERBOARD),1504)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Melzi Malyan M150 board
else ifeq ($(HARDWARE_MOTHERBOARD),1505)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Tronxy X5S
else ifeq ($(HARDWARE_MOTHERBOARD),1506)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# STB V1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1507)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Azteeg X1
else ifeq ($(HARDWARE_MOTHERBOARD),1508)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Anet 1.0 (Melzi clone)
else ifeq ($(HARDWARE_MOTHERBOARD),1509)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
#
# Gen3 Monolithic Electronics
else ifeq ($(HARDWARE_MOTHERBOARD),1600)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Gen3+
else ifeq ($(HARDWARE_MOTHERBOARD),1601)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Gen6
else ifeq ($(HARDWARE_MOTHERBOARD),1602)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
# Gen6 deluxe
else ifeq ($(HARDWARE_MOTHERBOARD),1603)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
# Gen7 custom (Alfons3 Version)
else ifeq ($(HARDWARE_MOTHERBOARD),1604)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644
F_CPU ?= 20000000
# Gen7 v1.1, v1.2
else ifeq ($(HARDWARE_MOTHERBOARD),1605)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
# Gen7 v1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1606)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
# Gen7 v1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1607)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega1284p
F_CPU ?= 20000000
# Alpha OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),1608)
HARDWARE_VARIANT ?= SanguinoA
MCU ?= atmega644
# Final OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),1609)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Sethi 3D_1
else ifeq ($(HARDWARE_MOTHERBOARD),1610)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#
# Teensyduino - AT90USB1286, AT90USB1286P
#
# Teensylu
else ifeq ($(HARDWARE_MOTHERBOARD),1700)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Printrboard (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1701)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Printrboard Revision F (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1702)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Brainwave (AT90USB646)
else ifeq ($(HARDWARE_MOTHERBOARD),1703)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb646
# Brainwave Pro (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1704)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# SAV Mk-I (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1705)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Teensy++2.0 (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),1706)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# 5DPrint D8 Driver Board
else ifeq ($(HARDWARE_MOTHERBOARD),1707)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# UltiMachine Archim1 (with DRV8825 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
HARDWARE_VARIANT ?= archim
MCPU = cortex-m3
F_CPU = 84000000L
IS_MCU = 0
# UltiMachine Archim2 (with TMC2130 drivers)
else ifeq ($(HARDWARE_MOTHERBOARD),3024)
HARDWARE_VARIANT ?= archim
MCPU = cortex-m3
F_CPU = 84000000L
IS_MCU = 0
endif
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
# if you are setting this to something other than 16MHz
# Set to 16Mhz if not yet set.
F_CPU ?= 16000000
# Set to microcontroller if IS_MCU not yet set
IS_MCU ?= 1
ifeq ($(IS_MCU),1)
# Set to arduino, ATmega2560 if not yet set.
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
TOOL_PREFIX = avr
MCU_FLAGS = -mmcu=$(MCU)
SIZE_FLAGS = --mcu=$(MCU) -C
else
TOOL_PREFIX = arm-none-eabi
CPU_FLAGS = -mthumb -mcpu=$(MCPU)
SIZE_FLAGS = -A
endif
# Arduino contained the main source code for the Arduino
# Libraries, the "hardware variant" are for boards
# that derives from that, and their source are present in
# the main Marlin source directory
TARGET = $(notdir $(CURDIR))
# VPATH tells make to look into these directory for source files,
# there is no need to specify explicit pathnames as long as the
# directory is added here
# The Makefile for previous versions of Marlin used VPATH for all
# source files, but for Marlin 2.0, we use VPATH only for arduino
# library files.
VPATH = .
VPATH += $(BUILD_DIR)
VPATH += $(HARDWARE_SRC)
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI
endif
ifeq ($(IS_MCU),1)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
endif
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
ifeq ($(LIQUID_TWI2), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
endif
ifeq ($(WIRE), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
endif
ifeq ($(NEOPIXEL), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
endif
ifeq ($(U8GLIB), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/csrc
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/cppsrc
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/fntsrc
endif
ifeq ($(TMC), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src/source
endif
ifeq ($(HARDWARE_VARIANT), arduino)
HARDWARE_SUB_VARIANT ?= mega
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT)
else ifeq ($(HARDWARE_VARIANT), Sanguino)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/variants/sanguino
else ifeq ($(HARDWARE_VARIANT), archim)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/libsam
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/CMSIS/Include/
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/Device/ATMEL/
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/avr
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/cores/arduino/USB
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/Wire/src
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/libraries/U8glib/src/clib
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim
LDSCRIPT = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/linker_scripts/gcc/flash.ld
LDLIBS = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/libsam_sam3x8e_gcc_rel.a
else
HARDWARE_SUB_VARIANT ?= standard
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT)
endif
LIB_SRC = wiring.c \
wiring_analog.c wiring_digital.c \
wiring_shift.c WInterrupts.c hooks.c
ifeq ($(HARDWARE_VARIANT), archim)
LIB_ASRC += wiring_pulse_asm.S
else
LIB_SRC += wiring_pulse.c
endif
ifeq ($(HARDWARE_VARIANT), Teensy)
LIB_SRC = wiring.c
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
endif
LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp
ifeq ($(NEOPIXEL), 1)
LIB_CXXSRC += Adafruit_NeoPixel.cpp
endif
ifeq ($(LIQUID_TWI2), 0)
LIB_CXXSRC += LiquidCrystal.cpp
else
LIB_SRC += twi.c
LIB_CXXSRC += Wire.cpp LiquidTWI2.cpp
endif
ifeq ($(WIRE), 1)
LIB_SRC += twi.c
LIB_CXXSRC += Wire.cpp
endif
ifeq ($(U8GLIB), 1)
LIB_CXXSRC += U8glib.cpp
LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
endif
ifeq ($(TMC), 1)
LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
endif
ifeq ($(RELOC_WORKAROUND), 1)
LD_PREFIX=-nodefaultlibs
LD_SUFFIX=-lm -lgcc -lc -lgcc
endif
#Check for Arduino 1.0.0 or higher and use the correct source files for that version
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
LIB_CXXSRC += main.cpp
else
LIB_SRC += pins_arduino.c main.c
endif
FORMAT = ihex
# Name of this Makefile (used for "make depend").
MAKEFILE = Makefile
# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs
OPT = s
DEFINES ?=
# Program settings
CC = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-gcc
CXX = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-g++
OBJCOPY = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objcopy
OBJDUMP = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-objdump
AR = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-ar
SIZE = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-size
NM = $(AVR_TOOLS_PATH)$(TOOL_PREFIX)-nm
AVRDUDE = avrdude
REMOVE = rm -f
MV = mv -f
# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
CXXDEFS = $(CDEFS)
ifeq ($(HARDWARE_VARIANT), Teensy)
CDEFS += -DUSB_SERIAL
LIB_SRC += usb.c pins_teensy.c
LIB_CXXSRC += usb_api.cpp
else ifeq ($(HARDWARE_VARIANT), archim)
CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT="Archim"'
LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp USBCore.cpp
LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
ifeq ($(U8GLIB), 1)
LIB_SRC += u8g_com_api.c u8g_pb32h1.c
endif
endif
# Add all the source directories as include directories too
CINCS = ${addprefix -I ,${VPATH}}
CXXINCS = ${addprefix -I ,${VPATH}}
# Silence warnings for library code (won't work for .h files, unfortunately)
LIBWARN = -w -Wno-packed-bitfield-compat
# Compiler flag to set the C/CPP Standard level.
CSTANDARD = -std=gnu99
CXXSTANDARD = -std=gnu++11
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes -Wno-packed-bitfield-compat -Wno-pragmas -Wunused-parameter
CXXWARN = -Wall -Wno-packed-bitfield-compat -Wno-pragmas -Wunused-parameter
CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \
-fshort-enums -ffunction-sections -fdata-sections
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
endif
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD)
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD)
ASFLAGS := $(CDEFS)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
ifeq ($(HARDWARE_VARIANT), archim)
LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align
LD_SUFFIX = $(LDLIBS)
LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
else
LD_PREFIX = -Wl,--gc-sections,--relax
LDFLAGS = -lm
CTUNING += -flto
endif
# Programming support using avrdude. Settings and variables.
AVRDUDE_PORT = $(UPLOAD_PORT)
AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i
ifeq ($(shell uname -s), Linux)
AVRDUDE_CONF = /etc/avrdude/avrdude.conf
else
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
endif
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
-p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
-b$(UPLOAD_RATE)
# Since Marlin 2.0, the source files may be distributed into several
# different directories, so it is necessary to find them recursively
SRC = $(shell find src -name '*.c' -type f)
CXXSRC = $(shell find src -name '*.cpp' -type f)
# Define all object files.
OBJ = ${patsubst %.c, $(BUILD_DIR)/arduino/%.o, ${LIB_SRC}}
OBJ += ${patsubst %.cpp, $(BUILD_DIR)/arduino/%.o, ${LIB_CXXSRC}}
OBJ += ${patsubst %.S, $(BUILD_DIR)/arduino/%.o, ${LIB_ASRC}}
OBJ += ${patsubst %.c, $(BUILD_DIR)/%.o, ${SRC}}
OBJ += ${patsubst %.cpp, $(BUILD_DIR)/%.o, ${CXXSRC}}
# Define all listing files.
LST = $(LIB_ASRC:.S=.lst) $(LIB_CXXSRC:.cpp=.lst) $(LIB_SRC:.c=.lst)
# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(CFLAGS) -I.
ALL_CXXFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(CXXFLAGS)
ALL_ASFLAGS = $(MCU_FLAGS) $(CPU_FLAGS) $(ASFLAGS) -x assembler-with-cpp
# set V=1 (eg, "make V=1") to print the full commands etc.
ifneq ($V,1)
Pecho=@echo
P=@
else
Pecho=@:
P=
endif
# Create required build hierarchy if it does not exist
$(shell mkdir -p $(dir $(OBJ)))
# Default target.
all: sizeafter
build: elf hex bin
elf: $(BUILD_DIR)/$(TARGET).elf
bin: $(BUILD_DIR)/$(TARGET).bin
hex: $(BUILD_DIR)/$(TARGET).hex
eep: $(BUILD_DIR)/$(TARGET).eep
lss: $(BUILD_DIR)/$(TARGET).lss
sym: $(BUILD_DIR)/$(TARGET).sym
# Program the device.
# Do not try to reset an Arduino if it's not one
upload: $(BUILD_DIR)/$(TARGET).hex
ifeq (${AVRDUDE_PROGRAMMER}, arduino)
stty hup < $(UPLOAD_PORT); true
endif
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
ifeq (${AVRDUDE_PROGRAMMER}, arduino)
stty -hup < $(UPLOAD_PORT); true
endif
# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) $(BUILD_DIR)/$(TARGET).hex
ELFSIZE = $(SIZE) $(SIZE_FLAGS) $(BUILD_DIR)/$(TARGET).elf; \
$(SIZE) $(BUILD_DIR)/$(TARGET).elf
sizebefore:
$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
sizeafter: build
$P if [ -f $(BUILD_DIR)/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000
coff: $(BUILD_DIR)/$(TARGET).elf
$(COFFCONVERT) -O coff-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
extcoff: $(TARGET).elf
$(COFFCONVERT) -O coff-ext-avr $(BUILD_DIR)/$(TARGET).elf $(TARGET).cof
.SUFFIXES: .elf .hex .eep .lss .sym .bin
.PRECIOUS: .o
.elf.hex:
$(Pecho) " COPY $@"
$P $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
.elf.bin:
$(Pecho) " COPY $@"
$P $(OBJCOPY) -O binary -R .eeprom $< $@
.elf.eep:
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
.elf.lss:
$(OBJDUMP) -h -S $< > $@
# Create a symbol table from ELF output file.
.elf.sym:
$(NM) -n $< > $@
# Link: create ELF output file from library.
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
$(Pecho) " CXX $@"
$P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
# Object files that were found in "src" will be stored in $(BUILD_DIR)
# in directories that mirror the structure of "src"
$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CC $<"
$P $(CC) -MMD -c $(ALL_CFLAGS) $(CWARN) $< -o $@
$(BUILD_DIR)/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CXX $<"
$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $(CXXWARN) $< -o $@
# Object files for Arduino libs will be created in $(BUILD_DIR)/arduino
$(BUILD_DIR)/arduino/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CC $<"
$P $(CC) -MMD -c $(ALL_CFLAGS) $(LIBWARN) $< -o $@
$(BUILD_DIR)/arduino/%.o: %.cpp Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CXX $<"
$P $(CXX) -MMD -c $(ALL_CXXFLAGS) $(LIBWARN) $< -o $@
$(BUILD_DIR)/arduino/%.o: %.S $(MAKEFILE)
$(Pecho) " CXX $<"
$P $(CXX) -MMD -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean:
$(Pecho) " RMDIR $(BUILD_DIR)/"
$P rm -rf $(BUILD_DIR)
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
# Automaticaly include the dependency files created by gcc
-include ${patsubst %.o, %.d, ${OBJ}}

View File

@@ -1,53 +0,0 @@
/*
================================================================================
Marlin Firmware
(c) 2011-2019 MarlinFirmware
Portions of Marlin are (c) by their respective authors.
All code complies with GPLv2 and/or GPLv3
================================================================================
Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware.
To configure Marlin you must edit Configuration.h and Configuration_adv.h
located in the root 'Marlin' folder. Check the config/examples folder to see if
there's a more suitable starting-point for your specific hardware.
Before diving in, we recommend the following essential links:
Marlin Firmware Official Website
- http://marlinfw.org/
The official Marlin Firmware website contains the most up-to-date
documentation. Contributions are always welcome!
Configuration
- https://www.youtube.com/watch?v=3gwWVFtdg-4
A good 20-minute overview of Marlin configuration by Tom Sanladerer.
(Applies to Marlin 1.0.x, so Jerk and Acceleration should be halved.)
Also... https://www.google.com/search?tbs=vid%3A1&q=configure+marlin
- http://marlinfw.org/docs/configuration/configuration.html
Marlin's configuration options are explained in more detail here.
Getting Help
- http://forums.reprap.org/list.php?415
The Marlin Discussion Forum is a great place to get help from other Marlin
users who may have experienced similar issues to your own.
- https://github.com/MarlinFirmware/Marlin/issues
With a free GitHub account you can provide us with feedback, bug reports,
and feature requests via the Marlin Issue Queue.
Contributing
- http://marlinfw.org/docs/development/contributing.html
If you'd like to contribute to Marlin, read this first!
- http://marlinfw.org/docs/development/coding_standards.html
Before submitting code get to know the Coding Standards.
*/

View File

@@ -1,76 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
////////////////////////////
// VENDOR VERSION EXAMPLE //
////////////////////////////
/**
* Marlin release version identifier
*/
//#define SHORT_BUILD_VERSION "2.0.5.3"
/**
* Verbose version identifier which should contain a reference to the location
* from where the binary was downloaded or the source code was compiled.
*/
//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " (Github)"
/**
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2020-01-31"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
*/
//#define MACHINE_NAME "3D Printer"
/**
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
* Code which is installed on the device. In most cases —unless the manufacturer
* has a distinct Github fork— the Source Code URL should just be the main
* Marlin repository.
*/
//#define SOURCE_CODE_URL "https://github.com/MarlinFirmware/Marlin"
/**
* Default generic printer UUID.
*/
//#define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff"
/**
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
//#define WEBSITE_URL "http://marlinfw.org"
/**
* Set the vendor info the serial USB interface, if changable
* Currently only supported by DUE platform
*/
//#define USB_DEVICE_VENDOR_ID 0x0000
//#define USB_DEVICE_PRODUCT_ID 0x0000
//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL

View File

@@ -1,97 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Custom Boot Screen bitmap
*
* Place this file in the root with your configuration files
* and enable SHOW_CUSTOM_BOOTSCREEN in Configuration.h.
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
#define CUSTOM_BOOTSCREEN_TIMEOUT 1000
#define CUSTOM_BOOTSCREEN_BMPWIDTH 81
#define CUSTOM_BOOTSCREEN_INVERTED
const unsigned char custom_start_bmp[] PROGMEM = {
B11111111,B11111111,B11111111,B11111111,B11101111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11101111,B11101111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11100111,B11011111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11100111,B11011111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11100011,B11011111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11110011,B11001111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11100001,B11100001,B11001111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111110,B01111000,B00000000,B00000000,B00000011,B11011101,B11111111,B11111111,B11111111,B11111111,
B11111110,B11111111,B10000000,B01111110,B00000000,B00000001,B11101110,B11111111,B11111111,B11111111,B11111111,
B11111110,B01111101,B11001111,B11111100,B00000000,B00000000,B11110111,B01111111,B11111111,B11111111,B11111111,
B11111111,B10001110,B00000110,B00000000,B00000000,B00000000,B01111011,B10111111,B11111111,B11111111,B11111111,
B11111111,B11000000,B00000000,B00000000,B00000000,B00000000,B01111101,B11011111,B11111111,B11111111,B11111111,
B11111111,B11111100,B00000001,B11111110,B00000000,B00000000,B00111110,B11100111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111100,B00000000,B00000011,B00011111,B01110011,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111000,B00000000,B00000001,B10001111,B10000001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11100000,B00000000,B00000000,B10000011,B11111001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B00000000,B11111100,B00000000,B00000000,B11110000,B11111111,B11111111,B11111111,
B11111111,B11111111,B11100000,B00001111,B11111111,B11000000,B00000000,B00000000,B11111111,B11111111,B11111111,
B11111111,B11111110,B00000011,B11111111,B11111111,B11000000,B00000000,B00000000,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111001,B00000000,B00000000,B00000000,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111100,B00000000,B00000111,B11000000,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B00000000,B00000111,B11100000,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11100000,B00000111,B11110001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,B00000111,B11111001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B00000011,B11111001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B10000011,B11111001,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11000011,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11100001,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11110000,B10111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111011,B11111000,B00111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111001,B11111000,B00111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B01111110,B11110000,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B10001110,B00000011,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11100000,B00011111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B01111111,B11111111,B11111111,B11111111,
B11111111,B00000000,B00000000,B01111111,B11111111,B11111111,B11111000,B01111111,B11111111,B11111111,B11111111,
B11111111,B10000000,B00000000,B01111111,B11111111,B11111111,B11100000,B01111111,B11111111,B11111111,B11111111,
B11111111,B11000011,B11111100,B11111111,B11111111,B11111111,B11111000,B11111111,B11111111,B11111111,B11111111,
B11111111,B11000011,B11111100,B11111111,B11111111,B11111111,B11111000,B11111111,B11111111,B11111111,B11111111,
B11111111,B10000111,B11111101,B11111111,B11111111,B11111111,B11110001,B11111111,B11111111,B11111111,B11111111,
B11111111,B10000111,B11111111,B11111111,B11111111,B11111111,B11110001,B11111111,B11111111,B11111111,B11111111,
B11111111,B00001111,B11100111,B11110011,B00001111,B11111100,B00100011,B11111100,B00111111,B11111111,B11111111,
B11111111,B00001111,B11101111,B10000000,B00000111,B11110000,B00000011,B11110000,B00011110,B00000000,B01111111,
B11111110,B00011111,B11001111,B10000001,B10000111,B11000111,B10000111,B11000111,B00001100,B00000000,B01111111,
B11111110,B00000000,B00011111,B11000111,B11000111,B10001111,B11000111,B10011111,B00001111,B00001100,B11111111,
B11111110,B00000000,B00011111,B10000111,B10001111,B00011111,B10001111,B00011111,B00001111,B00011111,B11111111,
B11111100,B00111111,B10011111,B10001111,B10001111,B00011111,B10001110,B00000000,B00011110,B00111111,B11111111,
B11111100,B01111111,B00111111,B00001111,B00011110,B00111111,B00011110,B00111111,B11111110,B00111111,B11111111,
B11111000,B01111111,B11111111,B00011111,B00011100,B00111111,B00011100,B01111111,B11111100,B01111111,B11111111,
B11111000,B11111111,B11111111,B00011110,B00011100,B01111110,B00011100,B01111111,B11111100,B01111111,B11111111,
B11110000,B11111111,B11001110,B00111110,B00111100,B01111110,B00111100,B01111111,B10111000,B11111111,B11111111,
B11110000,B11111111,B10011110,B00111100,B00111000,B01111100,B00111000,B01111110,B01111000,B11111111,B11111111,
B11100001,B11111111,B00111100,B01111100,B01111000,B01111100,B01111000,B00111100,B11110001,B11111111,B11111111,
B11100001,B11111000,B00111000,B01111000,B01111000,B00010000,B00011000,B00000001,B11110001,B11111111,B11111111,
B00000000,B00000000,B01100000,B00100000,B00111100,B00000000,B01111100,B00000111,B10000000,B01111111,B11111111,
B11111111,B11111111,B11111111,B11111111,B11111110,B00011111,B11111110,B00011111,B11111111,B11111111,B11111111
};

View File

@@ -1,62 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Custom Status Screen bitmap
*
* Place this file in the root with your configuration files
* and enable CUSTOM_STATUS_SCREEN_IMAGE in Configuration.h.
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
//
// Status Screen Logo bitmap
//
#define STATUS_LOGO_Y 8
#define STATUS_LOGO_WIDTH 39
const unsigned char status_logo_bmp[] PROGMEM = {
B11111000,B00000001,B10000000,B00000000,B00001100,
B01001000,B00000000,B10000000,B00000000,B00010010,
B01000011,B11000011,B10001100,B11010000,B00000010,
B01110001,B00100100,B10010010,B01100111,B11001100,
B01000001,B00100100,B10011110,B01000000,B00000010,
B01001001,B00100100,B10010000,B01000000,B00010010,
B11111011,B10110011,B11001110,B11100000,B00001100
};
//
// Use default bitmaps
//
#define STATUS_HOTEND_ANIM
#define STATUS_BED_ANIM
#define STATUS_HEATERS_XSPACE 20
#if HOTENDS < 2
#define STATUS_HEATERS_X 48
#define STATUS_BED_X 72
#else
#define STATUS_HEATERS_X 40
#define STATUS_BED_X 80
#endif

View File

@@ -1,79 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
// ------------------------
// Public Variables
// ------------------------
//uint8_t MCUSR;
// ------------------------
// Public functions
// ------------------------
void HAL_init() {
// 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 ENABLED(SDSUPPORT)
#include "../../sd/SdFatUtil.h"
int freeMemory() { return SdFatUtil::FreeRam(); }
#else // !SDSUPPORT
extern "C" {
extern char __bss_end;
extern char __heap_start;
extern void* __brkval;
int freeMemory() {
int free_memory;
if ((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}
}
#endif // !SDSUPPORT
#endif // __AVR__

View File

@@ -1,415 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "../shared/Marduino.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "math.h"
#ifdef USBCON
#include <HardwareSerial.h>
#else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
#include "MarlinSerial.h"
#endif
#include <stdint.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#ifndef pgm_read_ptr
// Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
// Windows Subsystem for Linux on Windows 10 as of 10/18/2019
#define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
#define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short))
#define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
#endif
// ------------------------
// Defines
// ------------------------
//#define analogInputToDigitalPin(IO) IO
#ifndef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli()
#define CRITICAL_SECTION_END() SREG = _sreg
#endif
#define ISRS_ENABLED() TEST(SREG, SREG_I)
#define ENABLE_ISRS() sei()
#define DISABLE_ISRS() cli()
// On AVR this is in math.h?
//#define square(x) ((x)*(x))
// ------------------------
// Types
// ------------------------
typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
#define HAL_SERVO_LIB Servo
// ------------------------
// Public Variables
// ------------------------
//extern uint8_t MCUSR;
// Serial ports
#ifdef USBCON
#if ENABLED(BLUETOOTH)
#define MYSERIAL0 bluetoothSerial
#else
#define MYSERIAL0 Serial
#endif
#define NUM_SERIAL 1
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#define MYSERIAL0 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#endif
#define MYSERIAL1 customizedSerial2
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#endif
#ifdef DGUS_SERIAL_PORT
#if !WITHIN(DGUS_SERIAL_PORT, -1, 3)
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#elif DGUS_SERIAL_PORT == SERIAL_PORT
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#endif
#define DGUS_SERIAL internalDgusSerial
#define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.get_tx_buffer_free
#endif
// ------------------------
// Public functions
// ------------------------
void HAL_init();
//void cli();
//void _delay_ms(const int delay);
inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
extern "C" {
int freeMemory();
}
#pragma GCC diagnostic pop
// timers
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
#define STEP_TIMER_NUM 1
#define TEMP_TIMER_NUM 0
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE 8
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double
#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() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
switch (timer_num) {
case STEP_TIMER_NUM:
// waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA);
// output mode = 00 (disconnected)
SET_COMA(1, NORMAL);
// Set the timer pre-scaler
// Generally we use a divider of 8, resulting in a 2MHz timer
// frequency on a 16MHz MCU. If you are going to change this, be
// sure to regenerate speed_lookuptable.h with
// create_speed_lookuptable.py
SET_CS(1, PRESCALER_8); // CS 2 = 1/8 prescaler
// Init Stepper ISR to 122 Hz for quick starting
// (F_CPU) / (STEPPER_TIMER_PRESCALE) / frequency
OCR1A = 0x4000;
TCNT1 = 0;
break;
case TEMP_TIMER_NUM:
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
break;
}
}
#define TIMER_OCR_1 OCR1A
#define TIMER_COUNTER_1 TCNT1
#define TIMER_OCR_0 OCR0A
#define TIMER_COUNTER_0 TCNT0
#define _CAT(a,V...) a##V
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
/**
* On AVR there is no hardware prioritization and preemption of
* interrupts, so this emulates it. The UART has first priority
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
/* 18 cycles maximum latency */
#define HAL_STEP_TIMER_ISR() \
extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER1_COMPA_vect() { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
A("push r16") /* 2 Save SREG into stack */ \
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("push r16") /* 2 Save TIMSK0 into the stack */ \
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16") /* 2 And set the new value */ \
A("lds r16, %[timsk1]") /* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
A("andi r16,~%[msk1]") /* 1 Disable the stepper ISR */ \
A("sts %[timsk1], r16") /* 2 And set the new value */ \
A("push r16") /* 2 Save TIMSK1 into stack */ \
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
A("push r16") /* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C") /* 1 Get EIND register */ \
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER1_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16") /* 1 Restore EIND register */ \
A("pop r16") /* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
A("pop r16") /* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
A("ori r16,%[msk1]") /* 1 Reenable the stepper ISR */ \
A("cli") /* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
A("sts %[timsk1], r16") /* 2 And restore the old value - This reenables the stepper ISR */ \
A("pop r16") /* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
A("sts %[timsk0], r16") /* 2 And restore the old value - This reenables the temperature ISR */ \
A("pop r16") /* 2 Get the old SREG value */ \
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
A("pop r16") /* 2 Restore R16 value */ \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i" ((uint16_t)&TIMSK0), \
[timsk1] "i" ((uint16_t)&TIMSK1), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
: \
); \
} \
void TIMER1_COMPA_vect_bottom()
/* 14 cycles maximum latency */
#define HAL_TEMP_TIMER_ISR() \
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPB_vect_bottom() asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPB_vect() { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
A("push r16") /* 2 Save SREG into stack */ \
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16") /* 2 And set the new value */ \
A("sei") /* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
A("push r16") /* 2 Save TIMSK0 into stack */ \
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
A("push r16") /* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C") /* 1 Get EIND register */ \
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16") /* 1 Restore EIND register */ \
A("pop r16") /* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
A("pop r16") /* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
A("ori r16,%[msk0]") /* 1 Enable temperature ISR */ \
A("cli") /* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don't want to reenter this handler until the current one is done */ \
A("sts %[timsk0], r16") /* 2 And restore the old value */ \
A("pop r16") /* 2 Get the old SREG */ \
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
A("pop r16") /* 2 Restore R16 */ \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i"((uint16_t)&TIMSK0), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
: \
); \
} \
void TIMER0_COMPB_vect_bottom()
// ADC
#ifdef DIDR2
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
#else
#define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
#endif
inline void HAL_adc_init() {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
}
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
#ifdef MUX5
#define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
#else
#define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
#endif
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define HAL_SENSITIVE_PINS 0, 1
#ifdef __AVR_AT90USB1286__
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
#endif
// AVR compatibility
#define strtof strtod
/**
* set_pwm_frequency
* Sets the frequency of the timer corresponding to the provided pin
* as close as possible to the provided desired frequency. Internally
* calculates the required waveform generation mode, prescaler and
* resolution values required and sets the timer registers accordingly.
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
*/
void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
* Sets the PWM duty cycle of the provided pin to the provided value
* Optionally allows inverting the duty cycle [default = false]
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
*/
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);

View File

@@ -1,792 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* MarlinSerial.cpp - Hardware serial library for Wiring
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
*
* Modified 23 November 2006 by David A. Mellis
* Modified 28 September 2010 by Mark Sproul
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
* Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
* Modified 10 June 2018 by Eduardo José Tagle (See #10991)
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
*/
#ifdef __AVR__
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
#include "../../inc/MarlinConfig.h"
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#include "MarlinSerial.h"
#include "../../MarlinCore.h"
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_r MarlinSerial<Cfg>::rx_buffer = { 0, 0, { 0 } };
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_t MarlinSerial<Cfg>::tx_buffer = { 0 };
template<typename Cfg> bool MarlinSerial<Cfg>::_written = false;
template<typename Cfg> uint8_t MarlinSerial<Cfg>::xon_xoff_state = MarlinSerial<Cfg>::XON_XOFF_CHAR_SENT | MarlinSerial<Cfg>::XON_CHAR;
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_dropped_bytes = 0;
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_buffer_overruns = 0;
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_framing_errors = 0;
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::rx_max_enqueued = 0;
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() asm volatile("": : :"memory");
#include "../../feature/e_parser.h"
// "Atomically" read the RX head index value without disabling interrupts:
// This MUST be called with RX interrupts enabled, and CAN'T be called
// from the RX ISR itself!
template<typename Cfg>
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_head() {
if (Cfg::RX_SIZE > 256) {
// Keep reading until 2 consecutive reads return the same value,
// meaning there was no update in-between caused by an interrupt.
// This works because serial RX interrupts happen at a slower rate
// than successive reads of a variable, so 2 consecutive reads with
// the same value means no interrupt updated it.
ring_buffer_pos_t vold, vnew = rx_buffer.head;
sw_barrier();
do {
vold = vnew;
vnew = rx_buffer.head;
sw_barrier();
} while (vold != vnew);
return vnew;
}
else {
// With an 8bit index, reads are always atomic. No need for special handling
return rx_buffer.head;
}
}
template<typename Cfg>
volatile bool MarlinSerial<Cfg>::rx_tail_value_not_stable = false;
template<typename Cfg>
volatile uint16_t MarlinSerial<Cfg>::rx_tail_value_backup = 0;
// Set RX tail index, taking into account the RX ISR could interrupt
// the write to this variable in the middle - So a backup strategy
// is used to ensure reads of the correct values.
// -Must NOT be called from the RX ISR -
template<typename Cfg>
FORCE_INLINE void MarlinSerial<Cfg>::atomic_set_rx_tail(typename MarlinSerial<Cfg>::ring_buffer_pos_t value) {
if (Cfg::RX_SIZE > 256) {
// Store the new value in the backup
rx_tail_value_backup = value;
sw_barrier();
// Flag we are about to change the true value
rx_tail_value_not_stable = true;
sw_barrier();
// Store the new value
rx_buffer.tail = value;
sw_barrier();
// Signal the new value is completely stored into the value
rx_tail_value_not_stable = false;
sw_barrier();
}
else
rx_buffer.tail = value;
}
// Get the RX tail index, taking into account the read could be
// interrupting in the middle of the update of that index value
// -Called from the RX ISR -
template<typename Cfg>
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_tail() {
if (Cfg::RX_SIZE > 256) {
// If the true index is being modified, return the backup value
if (rx_tail_value_not_stable) return rx_tail_value_backup;
}
// The true index is stable, return it
return rx_buffer.tail;
}
// (called with RX interrupts disabled)
template<typename Cfg>
FORCE_INLINE void MarlinSerial<Cfg>::store_rxd_char() {
static EmergencyParser::State emergency_state; // = EP_RESET
// Get the tail - Nothing can alter its value while this ISR is executing, but there's
// a chance that this ISR interrupted the main process while it was updating the index.
// The backup mechanism ensures the correct value is always returned.
const ring_buffer_pos_t t = atomic_read_rx_tail();
// Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here
ring_buffer_pos_t h = rx_buffer.head;
// Get the next element
ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
// This must read the R_UCSRA register before reading the received byte to detect error causes
if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes;
if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns;
if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors;
// Read the character from the USART
uint8_t c = R_UDR;
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
// If the character is to be stored at the index just before the tail
// (such that the head would advance to the current tail), the RX FIFO is
// full, so don't write the character or advance the head.
if (i != t) {
rx_buffer.buffer[h] = c;
h = i;
}
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
--rx_dropped_bytes;
if (Cfg::MAX_RX_QUEUED) {
// Calculate count of bytes stored into the RX buffer
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
// Keep track of the maximum count of enqueued bytes
NOLESS(rx_max_enqueued, rx_count);
}
if (Cfg::XONOFF) {
// If the last char that was sent was an XON
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
// Bytes stored into the RX buffer
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
// If over 12.5% of RX buffer capacity, send XOFF before running out of
// RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react
// and stop sending bytes. This translates to 13mS propagation time.
if (rx_count >= (Cfg::RX_SIZE) / 8) {
// At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted.
// Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens
// to be in the middle of trying to disable the RX interrupt in the main program, eventually the
// enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure
// the sending of the XOFF char is to send it HERE AND NOW.
// About to send the XOFF char
xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
// Wait until the TX register becomes empty and send it - Here there could be a problem
// - While waiting for the TX register to empty, the RX register could receive a new
// character. This must also handle that situation!
while (!B_UDRE) {
if (B_RXC) {
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
// Read the character from the USART
c = R_UDR;
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
// If the character is to be stored at the index just before the tail
// (such that the head would advance to the current tail), the FIFO is
// full, so don't write the character or advance the head.
if (i != t) {
rx_buffer.buffer[h] = c;
h = i;
}
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
--rx_dropped_bytes;
}
sw_barrier();
}
R_UDR = XOFF_CHAR;
// Clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
B_TXC = 1;
// At this point there could be a race condition between the write() function
// and this sending of the XOFF char. This interrupt could happen between the
// wait to be empty TX buffer loop and the actual write of the character. Since
// the TX buffer is full because it's sending the XOFF char, the only way to be
// sure the write() function will succeed is to wait for the XOFF char to be
// completely sent. Since an extra character could be received during the wait
// it must also be handled!
while (!B_UDRE) {
if (B_RXC) {
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
// Read the character from the USART
c = R_UDR;
if (Cfg::EMERGENCYPARSER)
emergency_parser.update(emergency_state, c);
// If the character is to be stored at the index just before the tail
// (such that the head would advance to the current tail), the FIFO is
// full, so don't write the character or advance the head.
if (i != t) {
rx_buffer.buffer[h] = c;
h = i;
}
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
--rx_dropped_bytes;
}
sw_barrier();
}
// At this point everything is ready. The write() function won't
// have any issues writing to the UART TX register if it needs to!
}
}
}
// Store the new head value - The main loop will retry until the value is stable
rx_buffer.head = h;
}
// (called with TX irqs disabled)
template<typename Cfg>
FORCE_INLINE void MarlinSerial<Cfg>::_tx_udr_empty_irq() {
if (Cfg::TX_SIZE > 0) {
// Read positions
uint8_t t = tx_buffer.tail;
const uint8_t h = tx_buffer.head;
if (Cfg::XONOFF) {
// If an XON char is pending to be sent, do it now
if (xon_xoff_state == XON_CHAR) {
// Send the character
R_UDR = XON_CHAR;
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
B_TXC = 1;
// Remember we sent it.
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
// If nothing else to transmit, just disable TX interrupts.
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
return;
}
}
// If nothing to transmit, just disable TX interrupts. This could
// happen as the result of the non atomicity of the disabling of RX
// interrupts that could end reenabling TX interrupts as a side effect.
if (h == t) {
B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
return;
}
// There is something to TX, Send the next byte
const uint8_t c = tx_buffer.buffer[t];
t = (t + 1) & (Cfg::TX_SIZE - 1);
R_UDR = c;
tx_buffer.tail = t;
// Clear the TXC bit (by writing a one to its bit location).
// Ensures flush() won't return until the bytes are actually written/
B_TXC = 1;
// Disable interrupts if there is nothing to transmit following this byte
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
}
}
// Public Methods
template<typename Cfg>
void MarlinSerial<Cfg>::begin(const long baud) {
uint16_t baud_setting;
bool useU2X = true;
#if F_CPU == 16000000UL && SERIAL_PORT == 0
// Hard-coded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards, and the firmware on the
// 8U2 on the Uno and Mega 2560.
if (baud == 57600) useU2X = false;
#endif
R_UCSRA = 0;
if (useU2X) {
B_U2X = 1;
baud_setting = (F_CPU / 4 / baud - 1) / 2;
}
else
baud_setting = (F_CPU / 8 / baud - 1) / 2;
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
R_UBRRH = baud_setting >> 8;
R_UBRRL = baud_setting;
B_RXEN = 1;
B_TXEN = 1;
B_RXCIE = 1;
if (Cfg::TX_SIZE > 0) B_UDRIE = 0;
_written = false;
}
template<typename Cfg>
void MarlinSerial<Cfg>::end() {
B_RXEN = 0;
B_TXEN = 0;
B_RXCIE = 0;
B_UDRIE = 0;
}
template<typename Cfg>
int MarlinSerial<Cfg>::peek() {
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
return h == t ? -1 : rx_buffer.buffer[t];
}
template<typename Cfg>
int MarlinSerial<Cfg>::read() {
const ring_buffer_pos_t h = atomic_read_rx_head();
// Read the tail. Main thread owns it, so it is safe to directly read it
ring_buffer_pos_t t = rx_buffer.tail;
// If nothing to read, return now
if (h == t) return -1;
// Get the next char
const int v = rx_buffer.buffer[t];
t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1);
// Advance tail - Making sure the RX ISR will always get an stable value, even
// if it interrupts the writing of the value of that variable in the middle.
atomic_set_rx_tail(t);
if (Cfg::XONOFF) {
// If the XOFF char was sent, or about to be sent...
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
// Get count of bytes in the RX buffer
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
if (rx_count < (Cfg::RX_SIZE) / 10) {
if (Cfg::TX_SIZE > 0) {
// Signal we want an XON character to be sent.
xon_xoff_state = XON_CHAR;
// Enable TX ISR. Non atomic, but it will eventually enable them
B_UDRIE = 1;
}
else {
// If not using TX interrupts, we must send the XON char now
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
while (!B_UDRE) sw_barrier();
R_UDR = XON_CHAR;
}
}
}
}
return v;
}
template<typename Cfg>
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::available() {
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1);
}
template<typename Cfg>
void MarlinSerial<Cfg>::flush() {
// Set the tail to the head:
// - Read the RX head index in a safe way. (See atomic_read_rx_head.)
// - Set the tail, making sure the RX ISR will always get a stable value, even
// if it interrupts the writing of the value of that variable in the middle.
atomic_set_rx_tail(atomic_read_rx_head());
if (Cfg::XONOFF) {
// If the XOFF char was sent, or about to be sent...
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
if (Cfg::TX_SIZE > 0) {
// Signal we want an XON character to be sent.
xon_xoff_state = XON_CHAR;
// Enable TX ISR. Non atomic, but it will eventually enable it.
B_UDRIE = 1;
}
else {
// If not using TX interrupts, we must send the XON char now
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
while (!B_UDRE) sw_barrier();
R_UDR = XON_CHAR;
}
}
}
}
template<typename Cfg>
void MarlinSerial<Cfg>::write(const uint8_t c) {
if (Cfg::TX_SIZE == 0) {
_written = true;
while (!B_UDRE) sw_barrier();
R_UDR = c;
}
else {
_written = true;
// If the TX interrupts are disabled and the data register
// is empty, just write the byte to the data register and
// be done. This shortcut helps significantly improve the
// effective datarate at high (>500kbit/s) bitrates, where
// interrupt overhead becomes a slowdown.
// Yes, there is a race condition between the sending of the
// XOFF char at the RX ISR, but it is properly handled there
if (!B_UDRIE && B_UDRE) {
R_UDR = c;
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
B_TXC = 1;
return;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!ISRS_ENABLED()) {
// Make room by polling if it is possible to transmit, and do so!
while (i == tx_buffer.tail) {
// If we can transmit another byte, do it.
if (B_UDRE) _tx_udr_empty_irq();
// Make sure compiler rereads tx_buffer.tail
sw_barrier();
}
}
else {
// Interrupts are enabled, just wait until there is space
while (i == tx_buffer.tail) sw_barrier();
}
// Store new char. head is always safe to move
tx_buffer.buffer[tx_buffer.head] = c;
tx_buffer.head = i;
// Enable TX ISR - Non atomic, but it will eventually enable TX ISR
B_UDRIE = 1;
}
}
template<typename Cfg>
void MarlinSerial<Cfg>::flushTX() {
if (Cfg::TX_SIZE == 0) {
// No bytes written, no need to flush. This special case is needed since there's
// no way to force the TXC (transmit complete) bit to 1 during initialization.
if (!_written) return;
// Wait until everything was transmitted
while (!B_TXC) sw_barrier();
// At this point nothing is queued anymore (DRIE is disabled) and
// the hardware finished transmission (TXC is set).
}
else {
// No bytes written, no need to flush. This special case is needed since there's
// no way to force the TXC (transmit complete) bit to 1 during initialization.
if (!_written) return;
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!ISRS_ENABLED()) {
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
// If there is more space, send an extra character
if (B_UDRE) _tx_udr_empty_irq();
sw_barrier();
}
}
else {
// Wait until everything was transmitted
while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier();
}
// At this point nothing is queued anymore (DRIE is disabled) and
// the hardware finished transmission (TXC is set).
}
}
/**
* Imports from print.h
*/
template<typename Cfg>
void MarlinSerial<Cfg>::print(char c, int base) {
print((long)c, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(int n, int base) {
print((long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(long n, int base) {
if (base == 0) write(n);
else if (base == 10) {
if (n < 0) { print('-'); n = -n; }
printNumber(n, 10);
}
else
printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(double n, int digits) {
printFloat(n, digits);
}
template<typename Cfg>
void MarlinSerial<Cfg>::println() {
print('\r');
print('\n');
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const String& s) {
print(s);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const char c[]) {
print(c);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(char c, int base) {
print(c, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned char b, int base) {
print(b, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
template<typename Cfg>
void MarlinSerial<Cfg>::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
template<typename Cfg>
void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
LOOP_L_N(i, digits) rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
// Hookup ISR handlers
ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>;
// Instantiate
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
#ifdef SERIAL_PORT_2
// Hookup ISR handlers
ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_RX_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_UDRE_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>;
// Instantiate
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
#endif
#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
#ifdef INTERNAL_SERIAL_PORT
ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_RX_vect)) {
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_UDRE_vect)) {
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>;
// Instantiate
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>> internalSerial;
#endif
#ifdef DGUS_SERIAL_PORT
template<typename Cfg>
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
h = tx_buffer.head; // next pos for queue.
int ret = t - h - 1;
if (ret < 0) ret += Cfg::TX_SIZE + 1;
return ret;
}
ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_RX_vect)) {
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_UDRE_vect)) {
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>;
// Instantiate
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
#endif
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;
#endif
#endif // __AVR__

View File

@@ -1,318 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* MarlinSerial.h - Hardware serial library for Wiring
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
*
* Modified 28 September 2010 by Mark Sproul
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
* Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
*/
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
#endif
#ifndef USBCON
// The presence of the UBRRH register is used to detect a UART.
#define UART_PRESENT(port) ((port == 0 && (defined(UBRRH) || defined(UBRR0H))) || \
(port == 1 && defined(UBRR1H)) || (port == 2 && defined(UBRR2H)) || \
(port == 3 && defined(UBRR3H)))
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
// requires two levels of indirection to expand macro values properly)
#define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix
#else
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
#endif
// Registers used by MarlinSerial class (expanded depending on selected serial port)
// Templated 8bit register (generic)
#define UART_REGISTER_DECL_BASE(registerbase, suffix) \
template<int portNr> struct R_##registerbase##x##suffix {}
// Templated 8bit register (specialization for each port)
#define UART_REGISTER_DECL(port, registerbase, suffix) \
template<> struct R_##registerbase##x##suffix<port> { \
constexpr R_##registerbase##x##suffix(int) {} \
FORCE_INLINE void operator=(uint8_t newVal) const { SERIAL_REGNAME(registerbase,port,suffix) = newVal; } \
FORCE_INLINE operator uint8_t() const { return SERIAL_REGNAME(registerbase,port,suffix); } \
}
// Templated 1bit register (generic)
#define UART_BIT_DECL_BASE(registerbase, suffix, bit) \
template<int portNr>struct B_##bit##x {}
// Templated 1bit register (specialization for each port)
#define UART_BIT_DECL(port, registerbase, suffix, bit) \
template<> struct B_##bit##x<port> { \
constexpr B_##bit##x(int) {} \
FORCE_INLINE void operator=(int newVal) const { \
if (newVal) \
SBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \
else \
CBI(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); \
} \
FORCE_INLINE operator bool() const { return TEST(SERIAL_REGNAME(registerbase,port,suffix),SERIAL_REGNAME(bit,port,)); } \
}
#define UART_DECL_BASE() \
UART_REGISTER_DECL_BASE(UCSR,A);\
UART_REGISTER_DECL_BASE(UDR,);\
UART_REGISTER_DECL_BASE(UBRR,H);\
UART_REGISTER_DECL_BASE(UBRR,L);\
UART_BIT_DECL_BASE(UCSR,B,RXEN);\
UART_BIT_DECL_BASE(UCSR,B,TXEN);\
UART_BIT_DECL_BASE(UCSR,A,TXC);\
UART_BIT_DECL_BASE(UCSR,B,RXCIE);\
UART_BIT_DECL_BASE(UCSR,A,UDRE);\
UART_BIT_DECL_BASE(UCSR,A,FE);\
UART_BIT_DECL_BASE(UCSR,A,DOR);\
UART_BIT_DECL_BASE(UCSR,B,UDRIE);\
UART_BIT_DECL_BASE(UCSR,A,RXC);\
UART_BIT_DECL_BASE(UCSR,A,U2X)
#define UART_DECL(port) \
UART_REGISTER_DECL(port,UCSR,A);\
UART_REGISTER_DECL(port,UDR,);\
UART_REGISTER_DECL(port,UBRR,H);\
UART_REGISTER_DECL(port,UBRR,L);\
UART_BIT_DECL(port,UCSR,B,RXEN);\
UART_BIT_DECL(port,UCSR,B,TXEN);\
UART_BIT_DECL(port,UCSR,A,TXC);\
UART_BIT_DECL(port,UCSR,B,RXCIE);\
UART_BIT_DECL(port,UCSR,A,UDRE);\
UART_BIT_DECL(port,UCSR,A,FE);\
UART_BIT_DECL(port,UCSR,A,DOR);\
UART_BIT_DECL(port,UCSR,B,UDRIE);\
UART_BIT_DECL(port,UCSR,A,RXC);\
UART_BIT_DECL(port,UCSR,A,U2X)
// Declare empty templates
UART_DECL_BASE();
// And all the specializations for each possible serial port
#if UART_PRESENT(0)
UART_DECL(0);
#endif
#if UART_PRESENT(1)
UART_DECL(1);
#endif
#if UART_PRESENT(2)
UART_DECL(2);
#endif
#if UART_PRESENT(3)
UART_DECL(3);
#endif
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
// Templated type selector
template<bool b, typename T, typename F> struct TypeSelector { typedef T type;} ;
template<typename T, typename F> struct TypeSelector<false, T, F> { typedef F type; };
template<typename Cfg>
class MarlinSerial {
protected:
// Registers
static constexpr R_UCSRxA<Cfg::PORT> R_UCSRA = 0;
static constexpr R_UDRx<Cfg::PORT> R_UDR = 0;
static constexpr R_UBRRxH<Cfg::PORT> R_UBRRH = 0;
static constexpr R_UBRRxL<Cfg::PORT> R_UBRRL = 0;
// Bits
static constexpr B_RXENx<Cfg::PORT> B_RXEN = 0;
static constexpr B_TXENx<Cfg::PORT> B_TXEN = 0;
static constexpr B_TXCx<Cfg::PORT> B_TXC = 0;
static constexpr B_RXCIEx<Cfg::PORT> B_RXCIE = 0;
static constexpr B_UDREx<Cfg::PORT> B_UDRE = 0;
static constexpr B_FEx<Cfg::PORT> B_FE = 0;
static constexpr B_DORx<Cfg::PORT> B_DOR = 0;
static constexpr B_UDRIEx<Cfg::PORT> B_UDRIE = 0;
static constexpr B_RXCx<Cfg::PORT> B_RXC = 0;
static constexpr B_U2Xx<Cfg::PORT> B_U2X = 0;
// Base size of type on buffer size
typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t;
struct ring_buffer_r {
volatile ring_buffer_pos_t head, tail;
unsigned char buffer[Cfg::RX_SIZE];
};
struct ring_buffer_t {
volatile uint8_t head, tail;
unsigned char buffer[Cfg::TX_SIZE];
};
static ring_buffer_r rx_buffer;
static ring_buffer_t tx_buffer;
static bool _written;
static constexpr uint8_t XON_XOFF_CHAR_SENT = 0x80, // XON / XOFF Character was sent
XON_XOFF_CHAR_MASK = 0x1F; // XON / XOFF character to send
// XON / XOFF character definitions
static constexpr uint8_t XON_CHAR = 17, XOFF_CHAR = 19;
static uint8_t xon_xoff_state,
rx_dropped_bytes,
rx_buffer_overruns,
rx_framing_errors;
static ring_buffer_pos_t rx_max_enqueued;
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
static volatile bool rx_tail_value_not_stable;
static volatile uint16_t rx_tail_value_backup;
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
public:
FORCE_INLINE static void store_rxd_char();
FORCE_INLINE static void _tx_udr_empty_irq();
public:
MarlinSerial() {};
static void begin(const long);
static void end();
static int peek();
static int read();
static void flush();
static ring_buffer_pos_t available();
static void write(const uint8_t c);
static void flushTX();
#ifdef DGUS_SERIAL_PORT
static ring_buffer_pos_t get_tx_buffer_free();
#endif
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = BYTE);
static void print(unsigned char, int = BYTE);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = BYTE);
static void println(unsigned char, int = BYTE);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println();
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
};
template <uint8_t serial>
struct MarlinSerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF);
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX);
static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
#ifdef SERIAL_PORT_2
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
#endif
#endif // !USBCON
#ifdef INTERNAL_SERIAL_PORT
template <uint8_t serial>
struct MarlinInternalSerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = 32;
static constexpr unsigned int TX_SIZE = 32;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_OVERRUNS = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
};
extern MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>> internalSerial;
#endif
#ifdef DGUS_SERIAL_PORT
template <uint8_t serial>
struct MarlinInternalSerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = 128;
static constexpr unsigned int TX_SIZE = 48;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_OVERRUNS = HAS_DGUS_LCD && ENABLED(DGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS);
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
};
extern MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
extern HardwareSerial bluetoothSerial;
#endif

View File

@@ -1,218 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved.
*/
/**
* A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method.
* The servos are pulsed in the background using the value most recently written using the write() method
*
* Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
* Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.
*
* The methods are:
*
* Servo - Class for manipulating servo motors connected to Arduino pins.
*
* attach(pin) - Attach a servo motor to an i/o pin.
* attach(pin, min, max) - Attach to a pin, setting min and max values in microseconds
* Default min is 544, max is 2400
*
* write() - Set the servo angle in degrees. (Invalid angles —over MIN_PULSE_WIDTH— are treated as µs.)
* writeMicroseconds() - Set the servo pulse width in microseconds.
* move(pin, angle) - Sequence of attach(pin), write(angle), safe_delay(servo_delay[servoIndex]).
* With DEACTIVATE_SERVOS_AFTER_MOVE it detaches after servo_delay[servoIndex].
* read() - Get the last-written servo pulse width as an angle between 0 and 180.
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
* attached() - Return true if a servo is attached.
* detach() - Stop an attached servo from pulsing its i/o pin.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include <avr/interrupt.h>
#include "../shared/Marduino.h"
#include "../shared/servo.h"
#include "../shared/servo_private.h"
static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
/************ static functions common to all instances ***********************/
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
if (Channel[timer] < 0)
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else {
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
}
#ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
// Interrupt handlers for Arduino
#ifdef _useTimer1
SIGNAL(TIMER1_COMPA_vect) { handle_interrupts(_timer1, &TCNT1, &OCR1A); }
#endif
#ifdef _useTimer3
SIGNAL(TIMER3_COMPA_vect) { handle_interrupts(_timer3, &TCNT3, &OCR3A); }
#endif
#ifdef _useTimer4
SIGNAL(TIMER4_COMPA_vect) { handle_interrupts(_timer4, &TCNT4, &OCR4A); }
#endif
#ifdef _useTimer5
SIGNAL(TIMER5_COMPA_vect) { handle_interrupts(_timer5, &TCNT5, &OCR5A); }
#endif
#else // WIRING
// Interrupt handlers for Wiring
#ifdef _useTimer1
void Timer1Service() { handle_interrupts(_timer1, &TCNT1, &OCR1A); }
#endif
#ifdef _useTimer3
void Timer3Service() { handle_interrupts(_timer3, &TCNT3, &OCR3A); }
#endif
#endif // WIRING
/****************** end of static functions ******************************/
void initISR(timer16_Sequence_t timer) {
#ifdef _useTimer1
if (timer == _timer1) {
TCCR1A = 0; // normal counting mode
TCCR1B = _BV(CS11); // set prescaler of 8
TCNT1 = 0; // clear the timer count
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
SBI(TIFR, OCF1A); // clear any pending interrupts;
SBI(TIMSK, OCIE1A); // enable the output compare interrupt
#else
// here if not ATmega8 or ATmega128
SBI(TIFR1, OCF1A); // clear any pending interrupts;
SBI(TIMSK1, OCIE1A); // enable the output compare interrupt
#endif
#ifdef WIRING
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
#endif
}
#endif
#ifdef _useTimer3
if (timer == _timer3) {
TCCR3A = 0; // normal counting mode
TCCR3B = _BV(CS31); // set prescaler of 8
TCNT3 = 0; // clear the timer count
#ifdef __AVR_ATmega128__
SBI(TIFR, OCF3A); // clear any pending interrupts;
SBI(ETIMSK, OCIE3A); // enable the output compare interrupt
#else
SBI(TIFR3, OCF3A); // clear any pending interrupts;
SBI(TIMSK3, OCIE3A); // enable the output compare interrupt
#endif
#ifdef WIRING
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
#endif
}
#endif
#ifdef _useTimer4
if (timer == _timer4) {
TCCR4A = 0; // normal counting mode
TCCR4B = _BV(CS41); // set prescaler of 8
TCNT4 = 0; // clear the timer count
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
}
#endif
#ifdef _useTimer5
if (timer == _timer5) {
TCCR5A = 0; // normal counting mode
TCCR5B = _BV(CS51); // set prescaler of 8
TCNT5 = 0; // clear the timer count
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
}
#endif
}
void finISR(timer16_Sequence_t timer) {
// Disable use of the given timer
#ifdef WIRING
if (timer == _timer1) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK1
#else
TIMSK
#endif
, OCIE1A); // disable timer 1 output compare interrupt
timerDetach(TIMER1OUTCOMPAREA_INT);
}
else if (timer == _timer3) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK3
#else
ETIMSK
#endif
, OCIE3A); // disable the timer3 output compare A interrupt
timerDetach(TIMER3OUTCOMPAREA_INT);
}
#else // !WIRING
// For arduino - in future: call here to a currently undefined function to reset the timer
UNUSED(timer);
#endif
}
#endif // HAS_SERVOS
#endif // __AVR__

View File

@@ -1,67 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
#include "../shared/eeprom_api.h"
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
}
}
crc16(crc, &v, 1);
pos++;
value++;
};
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
return false; // always assume success for AVR's
}
size_t PersistentStore::capacity() { return E2END + 1; }
#endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE
#endif // __AVR__

View File

@@ -1,282 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
#include "HAL.h"
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer
volatile uint16_t* ICRn; // max 1 ICR register per timer
uint8_t n; // the timer number [0->5]
uint8_t q; // the timer output [0->2] (A->C)
};
/**
* get_pwm_timer
* Get the timer information and register of the provided pin.
* Return a Timer struct containing this information.
* Used by set_pwm_frequency, set_pwm_duty
*/
Timer get_pwm_timer(const pin_t pin) {
uint8_t q = 0;
switch (digitalPinToTimer(pin)) {
// Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
#if !AVR_AT90USB1286_FAMILY
case TIMER0A:
#endif
case TIMER0B:
#endif
#ifdef TCCR1A
case TIMER1A: case TIMER1B:
#endif
break;
#if defined(TCCR2) || defined(TCCR2A)
#ifdef TCCR2
case TIMER2: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2, nullptr, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 0
};
}
#elif defined(TCCR2A)
#if ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // protect TIMER2A
case TIMER2B: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 1
};
return timer;
}
#else
case TIMER2B: ++q;
case TIMER2A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
2, q
};
return timer;
}
#endif
#endif
#endif
#ifdef OCR3C
case TIMER3C: ++q;
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C },
/*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
#elif defined(OCR3B)
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr },
/*OCRnQ*/ { &OCR3A, &OCR3B, nullptr },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
#endif
#ifdef TCCR4A
case TIMER4C: ++q;
case TIMER4B: ++q;
case TIMER4A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C },
/*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C },
/*ICRn*/ &ICR4,
/*n, q*/ 4, q
};
return timer;
}
#endif
#ifdef TCCR5A
case TIMER5C: ++q;
case TIMER5B: ++q;
case TIMER5A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C },
/*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C },
/*ICRn*/ &ICR5,
/*n, q*/ 5, q
};
return timer;
}
#endif
}
Timer timer = {
/*TCCRnQ*/ { nullptr, nullptr, nullptr },
/*OCRnQ*/ { nullptr, nullptr, nullptr },
/*ICRn*/ nullptr,
0, 0
};
return timer;
}
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
uint16_t res = 255; // resolution (TOP value)
uint8_t j = 0; // prescaler index
uint8_t wgm = 1; // waveform generation mode
// Calculating the prescaler and resolution to use to achieve closest frequency
if (f_desired != 0) {
int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
// loop over prescaler values
LOOP_S_L_N(i, 1, 8) {
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
if (timer.n == 2) {
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
#if ENABLED(USE_OCR2A_AS_TOP)
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
#endif
}
else {
// Skip TIMER2 specific prescalers when not TIMER2
if (i == 3 || i == 5) continue;
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
}
LIMIT(res_temp_fast, 1u, size);
LIMIT(res_temp_phase_correct, 1u, size);
// Calculate frequencies of test prescaler and resolution values
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
f_diff = ABS(f - f_desired),
f_fast_diff = ABS(f_temp_fast - f_desired),
f_phase_diff = ABS(f_temp_phase_correct - f_desired);
// If FAST values are closest to desired f
if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
// Remember this combination
f = f_temp_fast;
res = res_temp_fast;
j = i;
// Set the Wave Generation Mode to FAST PWM
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_FAST_PWM_OCR2A
#else
WGM2_FAST_PWM
#endif
);
}
else wgm = WGM_FAST_PWM_ICRn;
}
// If PHASE CORRECT values are closes to desired f
else if (f_phase_diff < f_diff) {
f = f_temp_phase_correct;
res = res_temp_phase_correct;
j = i;
// Set the Wave Generation Mode to PWM PHASE CORRECT
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_PWM_PC_OCR2A
#else
WGM2_PWM_PC
#endif
);
}
else wgm = WGM_PWM_PC_ICRn;
}
}
}
_SET_WGMnQ(timer.TCCRnQ, wgm);
_SET_CSn(timer.TCCRnQ, j);
if (timer.n == 2) {
#if ENABLED(USE_OCR2A_AS_TOP)
_SET_OCRnQ(timer.OCRnQ, 0, res); // Set OCR2A value (TOP) = res
#endif
}
else
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
// If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
// Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
if (v == 0)
digitalWrite(pin, invert);
else if (v == v_size)
digitalWrite(pin, !invert);
else {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
// Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
_SET_COMnQ(timer.TCCRnQ, (timer.q
#ifdef TCCR2
+ (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
#endif
), COM_CLEAR_SET + invert
);
uint16_t top;
if (timer.n == 2) { // if TIMER2
top = (
#if ENABLED(USE_OCR2A_AS_TOP)
*timer.OCRnQ[0] // top = OCR2A
#else
255 // top = 0xFF (max)
#endif
);
}
else
top = *timer.ICRn; // top = ICRn
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
}
}
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
#endif // __AVR__

View File

@@ -1,238 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Fast I/O for extended pins
*/
#ifdef __AVR__
#include "fastio.h"
#ifdef FASTIO_EXT_START
#include "../shared/Marduino.h"
#define _IS_EXT(P) WITHIN(P, FASTIO_EXT_START, FASTIO_EXT_END)
void extDigitalWrite(const int8_t pin, const uint8_t state) {
#define _WCASE(N) case N: WRITE(N, state); break
switch (pin) {
default: digitalWrite(pin, state);
#if _IS_EXT(70)
_WCASE(70);
#endif
#if _IS_EXT(71)
_WCASE(71);
#endif
#if _IS_EXT(72)
_WCASE(72);
#endif
#if _IS_EXT(73)
_WCASE(73);
#endif
#if _IS_EXT(74)
_WCASE(74);
#endif
#if _IS_EXT(75)
_WCASE(75);
#endif
#if _IS_EXT(76)
_WCASE(76);
#endif
#if _IS_EXT(77)
_WCASE(77);
#endif
#if _IS_EXT(78)
_WCASE(78);
#endif
#if _IS_EXT(79)
_WCASE(79);
#endif
#if _IS_EXT(80)
_WCASE(80);
#endif
#if _IS_EXT(81)
_WCASE(81);
#endif
#if _IS_EXT(82)
_WCASE(82);
#endif
#if _IS_EXT(83)
_WCASE(83);
#endif
#if _IS_EXT(84)
_WCASE(84);
#endif
#if _IS_EXT(85)
_WCASE(85);
#endif
#if _IS_EXT(86)
_WCASE(86);
#endif
#if _IS_EXT(87)
_WCASE(87);
#endif
#if _IS_EXT(88)
_WCASE(88);
#endif
#if _IS_EXT(89)
_WCASE(89);
#endif
#if _IS_EXT(90)
_WCASE(90);
#endif
#if _IS_EXT(91)
_WCASE(91);
#endif
#if _IS_EXT(92)
_WCASE(92);
#endif
#if _IS_EXT(93)
_WCASE(93);
#endif
#if _IS_EXT(94)
_WCASE(94);
#endif
#if _IS_EXT(95)
_WCASE(95);
#endif
#if _IS_EXT(96)
_WCASE(96);
#endif
#if _IS_EXT(97)
_WCASE(97);
#endif
#if _IS_EXT(98)
_WCASE(98);
#endif
#if _IS_EXT(99)
_WCASE(99);
#endif
#if _IS_EXT(100)
_WCASE(100);
#endif
}
}
uint8_t extDigitalRead(const int8_t pin) {
#define _RCASE(N) case N: return READ(N)
switch (pin) {
default: return digitalRead(pin);
#if _IS_EXT(70)
_RCASE(70);
#endif
#if _IS_EXT(71)
_RCASE(71);
#endif
#if _IS_EXT(72)
_RCASE(72);
#endif
#if _IS_EXT(73)
_RCASE(73);
#endif
#if _IS_EXT(74)
_RCASE(74);
#endif
#if _IS_EXT(75)
_RCASE(75);
#endif
#if _IS_EXT(76)
_RCASE(76);
#endif
#if _IS_EXT(77)
_RCASE(77);
#endif
#if _IS_EXT(78)
_RCASE(78);
#endif
#if _IS_EXT(79)
_RCASE(79);
#endif
#if _IS_EXT(80)
_RCASE(80);
#endif
#if _IS_EXT(81)
_RCASE(81);
#endif
#if _IS_EXT(82)
_RCASE(82);
#endif
#if _IS_EXT(83)
_RCASE(83);
#endif
#if _IS_EXT(84)
_RCASE(84);
#endif
#if _IS_EXT(85)
_RCASE(85);
#endif
#if _IS_EXT(86)
_RCASE(86);
#endif
#if _IS_EXT(87)
_RCASE(87);
#endif
#if _IS_EXT(88)
_RCASE(88);
#endif
#if _IS_EXT(89)
_RCASE(89);
#endif
#if _IS_EXT(90)
_RCASE(90);
#endif
#if _IS_EXT(91)
_RCASE(91);
#endif
#if _IS_EXT(92)
_RCASE(92);
#endif
#if _IS_EXT(93)
_RCASE(93);
#endif
#if _IS_EXT(94)
_RCASE(94);
#endif
#if _IS_EXT(95)
_RCASE(95);
#endif
#if _IS_EXT(96)
_RCASE(96);
#endif
#if _IS_EXT(97)
_RCASE(97);
#endif
#if _IS_EXT(98)
_RCASE(98);
#endif
#if _IS_EXT(99)
_RCASE(99);
#endif
#if _IS_EXT(100)
_RCASE(100);
#endif
}
}
#endif // FASTIO_EXT_START
#endif // __AVR__

View File

@@ -1,65 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Test AVR-specific configuration values for errors at compile-time.
*/
/**
* Digipot requirement
*/
#if ENABLED(DIGIPOT_MCP4018)
#if !defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) \
|| !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1)
#error "DIGIPOT_MCP4018 requires DIGIPOTS_I2C_SDA_* pins to be defined."
#endif
#endif
/**
* Checks for FAST PWM
*/
#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#endif
/**
* Sanity checks for Spindle / Laser PWM
*/
#if ENABLED(SPINDLE_LASER_PWM)
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
#elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#endif
/**
* The Trinamic library includes SoftwareSerial.h, leading to a compile error.
*/
#if HAS_TRINAMIC_CONFIG && ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
#error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
#if HAS_TMC_SW_SERIAL && ENABLED(MONITOR_DRIVER_STATUS)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#endif

View File

@@ -1,71 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#include "../../MarlinCore.h"
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
void watchdog_init() {
#if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S)
#define WDTO_NS WDTO_8S
#else
#define WDTO_NS WDTO_4S
#endif
#if ENABLED(WATCHDOG_RESET_MANUAL)
// Enable the watchdog timer, but only for the interrupt.
// Take care, as this requires the correct order of operation, with interrupts disabled.
// See the datasheet of any AVR chip for details.
wdt_reset();
cli();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5
// So worked for up to WDTO_2S
sei();
wdt_reset();
#else
wdt_enable(WDTO_NS); // The function handles the upper bit correct.
#endif
//delay(10000); // test it!
}
//===========================================================================
//=================================== ISR ===================================
//===========================================================================
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) {
sei(); // With the interrupt driven serial we need to allow interrupts.
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
minkill(); // interrupt-safe final kill and infinite loop
}
#endif
#endif // USE_WATCHDOG
#endif // __AVR__

View File

@@ -1,343 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../core/macros.h"
#include "../../core/serial.h"
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include <stdarg.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
// Disable UART interrupt in NVIC
NVIC_DisableIRQ( UART_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();
// Disable clock
pmc_disable_periph_clk( ID_UART );
// Configure PMC
pmc_enable_periph_clk( ID_UART );
// Disable PDC channel
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
// Reset and disable receiver and transmitter
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
// Configure mode: 8bit, No parity, 1 bit stop
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
// Enable receiver and transmitter
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
// Send character through UART with no interrupts
static void TX(char c) {
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
UART->UART_THR = c;
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
, UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Disable USB
otg_disable();
// Restart watchdog
WDT_Restart(WDT);
// Reset controller
NVIC_SystemReset();
for (;;) WDT_Restart(WDT);
}
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
#endif // ARDUINO_ARCH_SAM

File diff suppressed because it is too large Load Diff

View File

@@ -1,197 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Description: HAL for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
*/
#define CPU_32_BIT
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "timers.h"
#include <stdint.h>
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL0 customizedSerial1
#elif SERIAL_PORT == 0
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 Serial3
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
#elif SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL1 customizedSerial2
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#ifdef DGUS_SERIAL_PORT
#if DGUS_SERIAL_PORT == SERIAL_PORT
#error "DGUS_SERIAL_PORT must be different from SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#elif DGUS_SERIAL_PORT == -1
#define DGUS_SERIAL internalDgusSerial
#elif DGUS_SERIAL_PORT == 0
#define DGUS_SERIAL Serial
#elif DGUS_SERIAL_PORT == 1
#define DGUS_SERIAL Serial1
#elif DGUS_SERIAL_PORT == 2
#define DGUS_SERIAL Serial2
#elif DGUS_SERIAL_PORT == 3
#define DGUS_SERIAL Serial3
#else
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
#include "MarlinSerial.h"
#include "MarlinSerialUSB.h"
// On AVR this is in math.h?
#define square(x) ((x)*(x))
#ifndef strncpy_P
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
#endif
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*((void**)(addr)))
#undef pgm_read_word
#define pgm_read_word(addr) (*((uint16_t*)(addr)))
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
#define HAL_SERVO_LIB Servo
//
// Interrupts
//
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
#define ISRS_ENABLED() (!__get_PRIMASK())
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
void cli(); // Disable interrupts
void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
//
// EEPROM
//
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
//
// ADC
//
extern uint16_t HAL_adc_result; // result of last ADC conversion
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1)
#endif
#define HAL_ANALOG_SELECT(ch)
inline void HAL_adc_init() {}//todo
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
//
// Pin Map
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
//
// Tone
//
void toneInit();
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
void noTone(const pin_t _pin);
// Enable hooks into idle and setup for HAL
#define HAL_IDLETASK 1
void HAL_idletask();
void HAL_init();
//
// Utility functions
//
void _delay_ms(const int delay);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int freeMemory();
#pragma GCC diagnostic pop
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
#ifdef __cplusplus
}
#endif

View File

@@ -1,294 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#if HAS_USB_SERIAL
#include "MarlinSerialUSB.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
// Imports from Atmel USB Stack/CDC implementation
extern "C" {
bool usb_task_cdc_isenabled();
bool usb_task_cdc_dtr_active();
bool udi_cdc_is_rx_ready();
int udi_cdc_getc();
bool udi_cdc_is_tx_ready();
int udi_cdc_putc(int value);
};
// Pending character
static int pending_char = -1;
#if ENABLED(EMERGENCY_PARSER)
static EmergencyParser::State emergency_state; // = EP_RESET
#endif
// Public Methods
void MarlinSerialUSB::begin(const long) {}
void MarlinSerialUSB::end() {}
int MarlinSerialUSB::peek() {
if (pending_char >= 0)
return pending_char;
// If USB CDC not enumerated or not configured on the PC side
if (!usb_task_cdc_isenabled())
return -1;
// If no bytes sent from the PC
if (!udi_cdc_is_rx_ready())
return -1;
pending_char = udi_cdc_getc();
#if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(emergency_state, (char)pending_char);
#endif
return pending_char;
}
int MarlinSerialUSB::read() {
if (pending_char >= 0) {
int ret = pending_char;
pending_char = -1;
return ret;
}
// If USB CDC not enumerated or not configured on the PC side
if (!usb_task_cdc_isenabled())
return -1;
// If no bytes sent from the PC
if (!udi_cdc_is_rx_ready())
return -1;
int c = udi_cdc_getc();
#if ENABLED(EMERGENCY_PARSER)
emergency_parser.update(emergency_state, (char)c);
#endif
return c;
}
bool MarlinSerialUSB::available() {
/* If Pending chars */
return pending_char >= 0 ||
/* or USB CDC enumerated and configured on the PC side and some
bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
void MarlinSerialUSB::flush() { }
void MarlinSerialUSB::flushTX() { }
void MarlinSerialUSB::write(const uint8_t c) {
/* Do not even bother sending anything if USB CDC is not enumerated
or not configured on the PC side or there is no program on the PC
listening to our messages */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
return;
/* Wait until the PC has read the pending to be sent data */
while (usb_task_cdc_isenabled() &&
usb_task_cdc_dtr_active() &&
!udi_cdc_is_tx_ready()) {
};
/* Do not even bother sending anything if USB CDC is not enumerated
or not configured on the PC side or there is no program on the PC
listening to our messages at this point */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
return;
// Fifo full
// udi_cdc_signal_overrun();
udi_cdc_putc(c);
}
/**
* Imports from print.h
*/
void MarlinSerialUSB::print(char c, int base) {
print((long)c, base);
}
void MarlinSerialUSB::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
void MarlinSerialUSB::print(int n, int base) {
print((long)n, base);
}
void MarlinSerialUSB::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
void MarlinSerialUSB::print(long n, int base) {
if (base == 0)
write(n);
else if (base == 10) {
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
}
else
printNumber(n, base);
}
void MarlinSerialUSB::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
void MarlinSerialUSB::print(double n, int digits) {
printFloat(n, digits);
}
void MarlinSerialUSB::println() {
print('\r');
print('\n');
}
void MarlinSerialUSB::println(const String& s) {
print(s);
println();
}
void MarlinSerialUSB::println(const char c[]) {
print(c);
println();
}
void MarlinSerialUSB::println(char c, int base) {
print(c, base);
println();
}
void MarlinSerialUSB::println(unsigned char b, int base) {
print(b, base);
println();
}
void MarlinSerialUSB::println(int n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(unsigned int n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(long n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(unsigned long n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
void MarlinSerialUSB::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
LOOP_L_N(i, digits)
rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
// Preinstantiate
#if SERIAL_PORT == -1
MarlinSerialUSB customizedSerial1;
#endif
#if SERIAL_PORT_2 == -1
MarlinSerialUSB customizedSerial2;
#endif
#endif // HAS_USB_SERIAL
#endif // ARDUINO_ARCH_SAM

View File

@@ -1,160 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
Copyright (c) 2013 Arduino LLC. 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
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "../shared/Marduino.h"
#include "../shared/servo.h"
#include "../shared/servo_private.h"
static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
// ------------------------
/// Interrupt handler for the TC0 channel 1.
// ------------------------
void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
#ifdef _useTimer1
void HANDLER_FOR_TIMER1() { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); }
#endif
#ifdef _useTimer2
void HANDLER_FOR_TIMER2() { Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); }
#endif
#ifdef _useTimer3
void HANDLER_FOR_TIMER3() { Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); }
#endif
#ifdef _useTimer4
void HANDLER_FOR_TIMER4() { Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); }
#endif
#ifdef _useTimer5
void HANDLER_FOR_TIMER5() { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); }
#endif
void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) {
// clear interrupt
tc->TC_CHANNEL[channel].TC_SR;
if (Channel[timer] < 0)
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
else if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
if (SERVO(timer,Channel[timer]).Pin.isActive) // check if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
tc->TC_CHANNEL[channel].TC_RA =
tc->TC_CHANNEL[channel].TC_CV < usToTicks(REFRESH_INTERVAL) - 4
? (unsigned int)usToTicks(REFRESH_INTERVAL) // allow a few ticks to ensure the next OCR1A not missed
: tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
}
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
pmc_enable_periph_clk(id);
TC_Configure(tc, channel,
TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
TC_CMR_WAVE | // Waveform mode
TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
/* 84MHz, MCK/32, for 1.5ms: 3937 */
TC_SetRA(tc, channel, 2625); // 1ms
/* Configure and enable interrupt */
NVIC_EnableIRQ(irqn);
// TC_IER_CPAS: RA Compare
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;
// Enables the timer clock and performs a software reset to start the counting
TC_Start(tc, channel);
}
void initISR(timer16_Sequence_t timer) {
#ifdef _useTimer1
if (timer == _timer1)
_initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
#endif
#ifdef _useTimer2
if (timer == _timer2)
_initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
#endif
#ifdef _useTimer3
if (timer == _timer3)
_initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
#endif
#ifdef _useTimer4
if (timer == _timer4)
_initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
#endif
#ifdef _useTimer5
if (timer == _timer5)
_initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
#endif
}
void finISR(timer16_Sequence_t) {
#ifdef _useTimer1
TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
#endif
#ifdef _useTimer2
TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
#endif
#ifdef _useTimer3
TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
#endif
#ifdef _useTimer4
TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
#endif
#ifdef _useTimer5
TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
#endif
}
#endif // HAS_SERVOS
#endif // ARDUINO_ARCH_SAM

View File

@@ -1,61 +0,0 @@
/**
* 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
*
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Description: Tone function for Arduino Due and compatible (SAM3X8E)
* Derived from http://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#include "timers.h"
static pin_t tone_pin;
volatile static int32_t toggles;
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
tone_pin = _pin;
toggles = 2 * frequency * duration / 1000;
HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
}
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
extDigitalWrite(_pin, LOW);
}
HAL_TONE_TIMER_ISR() {
static uint8_t pin_state = 0;
HAL_timer_isr_prologue(TONE_TIMER_NUM);
if (toggles) {
toggles--;
extDigitalWrite(tone_pin, (pin_state ^= 1));
}
else noTone(tone_pin); // turn off interrupt
}
#endif // ARDUINO_ARCH_SAM

View File

@@ -1,82 +0,0 @@
/**
* 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
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EEPROM_SETTINGS)
#include "../../inc/MarlinConfig.h"
#include "../shared/eeprom_api.h"
#if !defined(E2END) && ENABLED(FLASH_EEPROM_EMULATION)
#define E2END 0xFFF // Default to Flash emulated EEPROM size (EepromEmulation_Due.cpp)
#endif
extern void eeprom_flush();
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() {
#if ENABLED(FLASH_EEPROM_EMULATION)
eeprom_flush();
#endif
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
// EEPROM has only ~100,000 write cycles,
// so only write bytes that have changed!
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
delay(2);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
}
}
crc16(crc, &v, 1);
pos++;
value++;
};
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
} while (--size);
return false;
}
size_t PersistentStore::capacity() { return E2END + 1; }
#endif // EEPROM_SETTINGS
#endif // ARDUINO_ARCH_SAM

View File

@@ -1,89 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* 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(); }
/**
* Endstop interrupts for Due based targets.
* On Due, all pins support external interrupt capability.
*/
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
#if HAS_X_MAX
_ATTACH(X_MAX_PIN);
#endif
#if HAS_X_MIN
_ATTACH(X_MIN_PIN);
#endif
#if HAS_Y_MAX
_ATTACH(Y_MAX_PIN);
#endif
#if HAS_Y_MIN
_ATTACH(Y_MIN_PIN);
#endif
#if HAS_Z_MAX
_ATTACH(Z_MAX_PIN);
#endif
#if HAS_Z_MIN
_ATTACH(Z_MIN_PIN);
#endif
#if HAS_Z2_MAX
_ATTACH(Z2_MAX_PIN);
#endif
#if HAS_Z2_MIN
_ATTACH(Z2_MIN_PIN);
#endif
#if HAS_Z3_MAX
_ATTACH(Z3_MAX_PIN);
#endif
#if HAS_Z3_MIN
_ATTACH(Z3_MIN_PIN);
#endif
#if HAS_Z4_MAX
_ATTACH(Z4_MAX_PIN);
#endif
#if HAS_Z4_MIN
_ATTACH(Z4_MIN_PIN);
#endif
#if HAS_Z_MIN_PROBE_PIN
_ATTACH(Z_MIN_PROBE_PIN);
#endif
}

View File

@@ -1,562 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Fast I/O Routines for SAM3X8E
* 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 for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
* Note the code here was specifically crafted by disassembling what GCC produces
* out of it, so GCC is able to optimize it out as much as possible to the least
* amount of instructions. Be very carefull if you modify them, as "clean code"
* leads to less efficient compiled code!!
*/
#include <pins_arduino.h>
#include "../../inc/MarlinConfigPre.h"
/**
* Utility functions
*/
// Due has 12 PWMs assigned to logical pins 2-13.
// 6, 7, 8 & 9 come from the PWM controller. The others come from the timers.
#define PWM_PIN(P) WITHIN(P, 2, 13)
#ifndef MASK
#define MASK(PIN) (1 << PIN)
#endif
/**
* Magic I/O routines
*
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
*
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
*/
// Read a pin
#define _READ(IO) bool(DIO ## IO ## _WPORT -> PIO_PDSR & MASK(DIO ## IO ## _PIN))
// Write to a pin
#define _WRITE(IO,V) do { \
volatile Pio* port = (DIO ## IO ## _WPORT); \
const uint32_t mask = MASK(DIO ## IO ## _PIN); \
if (V) port->PIO_SODR = mask; \
else port->PIO_CODR = mask; \
}while(0)
// Toggle a pin
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
#if MB(PRINTRBOARD_G2)
#include "fastio/G2_pins.h"
// Set pin as input
#define _SET_INPUT(IO) do{ \
pmc_enable_periph_clk(G2_g_APinDescription[IO].ulPeripheralId); \
PIO_Configure((DIO ## IO ## _WPORT), PIO_INPUT, MASK(DIO ## IO ## _PIN), 0); \
}while(0)
// Set pin as output
#define _SET_OUTPUT(IO) do{ \
uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
if ((PMC->PMC_PCSR0 & mask) != (mask)) PMC->PMC_PCER0 = mask; \
volatile Pio* port = (DIO ## IO ## _WPORT); \
mask = MASK(DIO ## IO ## _PIN); \
if (_READ(IO)) port->PIO_SODR = mask; \
else port->PIO_CODR = mask; \
port->PIO_IDR = mask; \
const uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
if (pin_config & PIO_PULLUP) port->PIO_PUER = mask; \
else port->PIO_PUDR = mask; \
if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \
else port->PIO_MDDR = mask; \
port->PIO_PER = mask; \
port->PIO_OER = mask; \
g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
}while(0)
/**
* Set pin as output with comments
* #define _SET_OUTPUT(IO) do{ \
* uint32_t mask = MASK(G2_g_APinDescription[IO].ulPeripheralId); \
* if ((PMC->PMC_PCSR0 & mask ) != (mask)) PMC->PMC_PCER0 = mask; \ // enable PIO clock if not already enabled
*
* volatile Pio* port = (DIO ## IO ## _WPORT); \
* const uint32_t mask = MASK(DIO ## IO ## _PIN); \
* if (_READ(IO)) port->PIO_SODR = mask; \ // set output to match input BEFORE setting direction or will glitch the output
* else port->PIO_CODR = mask; \
*
* port->PIO_IDR = mask; \ // disable interrupt
*
* uint32_t pin_config = G2_g_APinDescription[IO].ulPinConfiguration; \
* if (pin_config & PIO_PULLUP) pPio->PIO_PUER = mask; \ // enable pullup if necessary
* else pPio->PIO_PUDR = mask; \
*
* if (pin_config & PIO_OPENDRAIN) port->PIO_MDER = mask; \ // Enable multi-drive if necessary
* else port->PIO_MDDR = mask; \
*
* port->PIO_PER = mask; \
* port->PIO_OER = mask; \ // set to output
*
* g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
* }while(0)
*/
#else
// Set pin as input
#define _SET_INPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), PIO_INPUT, digitalPinToBitMask(IO), 0); \
}while(0)
// Set pin as output
#define _SET_OUTPUT(IO) do{ \
pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
PIO_Configure(digitalPinToPort(IO), _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, digitalPinToBitMask(IO), g_APinDescription[IO].ulPinConfiguration); \
g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT; \
}while(0)
#endif
// Set pin as input with pullup mode
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
// 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 output (wrapper) - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
// Set pin as PWM
#define SET_PWM SET_OUTPUT
// Check if pin is an input
#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
// Check if pin is an output
#define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0)
// Shorthand
#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); }
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
/**
* Ports and functions
* Added as necessary or if I feel like it- not a comprehensive list!
*/
// UART
#define RXD DIO0
#define TXD DIO1
// TWI (I2C)
#define SCL DIO21
#define SDA DIO20
/**
* pins
*/
#define DIO0_PIN 8
#define DIO0_WPORT PIOA
#define DIO1_PIN 9
#define DIO1_WPORT PIOA
#define DIO2_PIN 25
#define DIO2_WPORT PIOB
#define DIO3_PIN 28
#define DIO3_WPORT PIOC
#define DIO4_PIN 26
#define DIO4_WPORT PIOC
#define DIO5_PIN 25
#define DIO5_WPORT PIOC
#define DIO6_PIN 24
#define DIO6_WPORT PIOC
#define DIO7_PIN 23
#define DIO7_WPORT PIOC
#define DIO8_PIN 22
#define DIO8_WPORT PIOC
#define DIO9_PIN 21
#define DIO9_WPORT PIOC
#define DIO10_PIN 29
#define DIO10_WPORT PIOC
#define DIO11_PIN 7
#define DIO11_WPORT PIOD
#define DIO12_PIN 8
#define DIO12_WPORT PIOD
#define DIO13_PIN 27
#define DIO13_WPORT PIOB
#define DIO14_PIN 4
#define DIO14_WPORT PIOD
#define DIO15_PIN 5
#define DIO15_WPORT PIOD
#define DIO16_PIN 13
#define DIO16_WPORT PIOA
#define DIO17_PIN 12
#define DIO17_WPORT PIOA
#define DIO18_PIN 11
#define DIO18_WPORT PIOA
#define DIO19_PIN 10
#define DIO19_WPORT PIOA
#define DIO20_PIN 12
#define DIO20_WPORT PIOB
#define DIO21_PIN 13
#define DIO21_WPORT PIOB
#define DIO22_PIN 26
#define DIO22_WPORT PIOB
#define DIO23_PIN 14
#define DIO23_WPORT PIOA
#define DIO24_PIN 15
#define DIO24_WPORT PIOA
#define DIO25_PIN 0
#define DIO25_WPORT PIOD
#define DIO26_PIN 1
#define DIO26_WPORT PIOD
#define DIO27_PIN 2
#define DIO27_WPORT PIOD
#define DIO28_PIN 3
#define DIO28_WPORT PIOD
#define DIO29_PIN 6
#define DIO29_WPORT PIOD
#define DIO30_PIN 9
#define DIO30_WPORT PIOD
#define DIO31_PIN 7
#define DIO31_WPORT PIOA
#define DIO32_PIN 10
#define DIO32_WPORT PIOD
#define DIO33_PIN 1
#define DIO33_WPORT PIOC
#if !MB(PRINTRBOARD_G2) // normal DUE pin mapping
#define DIO34_PIN 2
#define DIO34_WPORT PIOC
#define DIO35_PIN 3
#define DIO35_WPORT PIOC
#define DIO36_PIN 4
#define DIO36_WPORT PIOC
#define DIO37_PIN 5
#define DIO37_WPORT PIOC
#define DIO38_PIN 6
#define DIO38_WPORT PIOC
#define DIO39_PIN 7
#define DIO39_WPORT PIOC
#define DIO40_PIN 8
#define DIO40_WPORT PIOC
#define DIO41_PIN 9
#define DIO41_WPORT PIOC
#endif // !PRINTRBOARD_G2
#define DIO42_PIN 19
#define DIO42_WPORT PIOA
#define DIO43_PIN 20
#define DIO43_WPORT PIOA
#define DIO44_PIN 19
#define DIO44_WPORT PIOC
#define DIO45_PIN 18
#define DIO45_WPORT PIOC
#define DIO46_PIN 17
#define DIO46_WPORT PIOC
#define DIO47_PIN 16
#define DIO47_WPORT PIOC
#define DIO48_PIN 15
#define DIO48_WPORT PIOC
#define DIO49_PIN 14
#define DIO49_WPORT PIOC
#define DIO50_PIN 13
#define DIO50_WPORT PIOC
#define DIO51_PIN 12
#define DIO51_WPORT PIOC
#define DIO52_PIN 21
#define DIO52_WPORT PIOB
#define DIO53_PIN 14
#define DIO53_WPORT PIOB
#define DIO54_PIN 16
#define DIO54_WPORT PIOA
#define DIO55_PIN 24
#define DIO55_WPORT PIOA
#define DIO56_PIN 23
#define DIO56_WPORT PIOA
#define DIO57_PIN 22
#define DIO57_WPORT PIOA
#define DIO58_PIN 6
#define DIO58_WPORT PIOA
#define DIO59_PIN 4
#define DIO59_WPORT PIOA
#define DIO60_PIN 3
#define DIO60_WPORT PIOA
#define DIO61_PIN 2
#define DIO61_WPORT PIOA
#define DIO62_PIN 17
#define DIO62_WPORT PIOB
#define DIO63_PIN 18
#define DIO63_WPORT PIOB
#define DIO64_PIN 19
#define DIO64_WPORT PIOB
#define DIO65_PIN 20
#define DIO65_WPORT PIOB
#define DIO66_PIN 15
#define DIO66_WPORT PIOB
#define DIO67_PIN 16
#define DIO67_WPORT PIOB
#define DIO68_PIN 1
#define DIO68_WPORT PIOA
#define DIO69_PIN 0
#define DIO69_WPORT PIOA
#define DIO70_PIN 17
#define DIO70_WPORT PIOA
#define DIO71_PIN 18
#define DIO71_WPORT PIOA
#define DIO72_PIN 30
#define DIO72_WPORT PIOC
#define DIO73_PIN 21
#define DIO73_WPORT PIOA
#define DIO74_PIN 25
#define DIO74_WPORT PIOA
#define DIO75_PIN 26
#define DIO75_WPORT PIOA
#define DIO76_PIN 27
#define DIO76_WPORT PIOA
#define DIO77_PIN 28
#define DIO77_WPORT PIOA
#define DIO78_PIN 23
#define DIO78_WPORT PIOB
#define DIO79_PIN 17
#define DIO79_WPORT PIOA
#define DIO80_PIN 12
#define DIO80_WPORT PIOB
#define DIO81_PIN 8
#define DIO81_WPORT PIOA
#define DIO82_PIN 11
#define DIO82_WPORT PIOA
#define DIO83_PIN 13
#define DIO83_WPORT PIOA
#define DIO84_PIN 4
#define DIO84_WPORT PIOD
#define DIO85_PIN 11
#define DIO85_WPORT PIOB
#define DIO86_PIN 21
#define DIO86_WPORT PIOB
#define DIO87_PIN 29
#define DIO87_WPORT PIOA
#define DIO88_PIN 15
#define DIO88_WPORT PIOB
#define DIO89_PIN 14
#define DIO89_WPORT PIOB
#define DIO90_PIN 1
#define DIO90_WPORT PIOA
#define DIO91_PIN 15
#define DIO91_WPORT PIOB
#if ARDUINO_SAM_ARCHIM
#define DIO92_PIN 11
#define DIO92_WPORT PIOC
#define DIO93_PIN 2
#define DIO93_WPORT PIOB
#define DIO94_PIN 1
#define DIO94_WPORT PIOB
#define DIO95_PIN 0
#define DIO95_WPORT PIOB
#define DIO96_PIN 10
#define DIO96_WPORT PIOC
#define DIO97_PIN 24
#define DIO97_WPORT PIOB
#define DIO98_PIN 7
#define DIO98_WPORT PIOB
#define DIO99_PIN 6
#define DIO99_WPORT PIOB
#define DIO100_PIN 8
#define DIO100_WPORT PIOB
#define DIO101_PIN 5
#define DIO101_WPORT PIOB
#define DIO102_PIN 4
#define DIO102_WPORT PIOB
#define DIO103_PIN 3
#define DIO103_WPORT PIOB
#define DIO104_PIN 20
#define DIO104_WPORT PIOC
#define DIO105_PIN 22
#define DIO105_WPORT PIOB
#define DIO106_PIN 27
#define DIO106_WPORT PIOC
#define DIO107_PIN 10
#define DIO107_WPORT PIOB
#define DIO108_PIN 9
#define DIO108_WPORT PIOB
#else // !ARDUINO_SAM_ARCHIM
#define DIO92_PIN 5
#define DIO92_WPORT PIOA
#define DIO93_PIN 12
#define DIO93_WPORT PIOB
#define DIO94_PIN 22
#define DIO94_WPORT PIOB
#define DIO95_PIN 23
#define DIO95_WPORT PIOB
#define DIO96_PIN 24
#define DIO96_WPORT PIOB
#define DIO97_PIN 20
#define DIO97_WPORT PIOC
#define DIO98_PIN 27
#define DIO98_WPORT PIOC
#define DIO99_PIN 10
#define DIO99_WPORT PIOC
#define DIO100_PIN 11
#define DIO100_WPORT PIOC
#endif // !ARDUINO_SAM_ARCHIM

View File

@@ -1,28 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#if USE_FALLBACK_EEPROM
#undef SRAM_EEPROM_EMULATION
#undef SDCARD_EEPROM_EMULATION
#define FLASH_EEPROM_EMULATION
#endif

View File

@@ -1,136 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Description: HAL for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
*/
#ifdef ARDUINO_ARCH_SAM
// ------------------------
// Includes
// ------------------------
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#include "timers.h"
// ------------------------
// Local defines
// ------------------------
#define NUM_HARDWARE_TIMERS 9
// ------------------------
// Private Variables
// ------------------------
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
{ TC0, 1, TC1_IRQn, 0}, // 1
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
{ TC1, 0, TC3_IRQn, 0}, // 3 - stepper for BOARD_ARCHIM1
{ TC1, 1, TC4_IRQn, 15}, // 4 - temperature
{ TC1, 2, TC5_IRQn, 3}, // 5 - [servo timer3]
{ TC2, 0, TC6_IRQn, 14}, // 6 - tone
{ TC2, 1, TC7_IRQn, 0}, // 7
{ TC2, 2, TC8_IRQn, 0}, // 8
};
// ------------------------
// Public functions
// ------------------------
/*
Timer_clock1: Prescaler 2 -> 42MHz
Timer_clock2: Prescaler 8 -> 10.5MHz
Timer_clock3: Prescaler 32 -> 2.625MHz
Timer_clock4: Prescaler 128 -> 656.25kHz
*/
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
Tc *tc = TimerConfig[timer_num].pTimerRegs;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
uint32_t channel = TimerConfig[timer_num].channel;
// Disable interrupt, just in case it was already enabled
NVIC_DisableIRQ(irq);
// 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();
// Disable timer interrupt
tc->TC_CHANNEL[channel].TC_IDR = TC_IDR_CPCS;
// Stop timer, just in case, to be able to reconfigure it
TC_Stop(tc, channel);
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
NVIC_SetPriority(irq, TimerConfig [timer_num].priority);
// wave mode, reset counter on match with RC,
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
// Set compare value
TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency);
// And start timer
TC_Start(tc, channel);
// enable interrupt on RC compare
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPCS;
// Finally, enable IRQ
NVIC_EnableIRQ(irq);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
NVIC_DisableIRQ(irq);
// 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();
}
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
#endif // ARDUINO_ARCH_SAM

View File

@@ -1,120 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HAL for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
*/
#include <stdint.h>
// ------------------------
// Defines
// ------------------------
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 2 // index of timer to use for stepper
#endif
#define TEMP_TIMER_NUM 4 // index of timer to use for temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
#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(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
#endif
#define HAL_TEMP_TIMER_ISR() void TC4_Handler()
#define HAL_TONE_TIMER_ISR() void TC6_Handler()
// ------------------------
// Types
// ------------------------
typedef struct {
Tc *pTimerRegs;
uint16_t channel;
IRQn_Type IRQ_Id;
uint8_t priority;
} tTimerConfig;
// ------------------------
// Public Variables
// ------------------------
extern const tTimerConfig TimerConfig[];
// ------------------------
// Public functions
// ------------------------
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) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV;
}
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
// Reading the status register clears the interrupt flag
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
#define HAL_timer_isr_epilogue(TIMER_NUM)

View File

@@ -1,300 +0,0 @@
/**
* \file
*
* \brief USB configuration file
*
* Copyright (c) 2011-2015 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
*
* \asf_license_stop
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _CONF_USB_H_
#define _CONF_USB_H_
#undef UNUSED /* To avoid a macro clash as macros.h already defines it */
#include "../../../inc/MarlinConfigPre.h"
#include "compiler.h"
/**
* USB Device Configuration
* @{
*/
//! Device definition (mandatory)
#define USB_DEVICE_MAJOR_VERSION 1
#define USB_DEVICE_MINOR_VERSION 0
#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA)
#define USB_DEVICE_ATTR \
(USB_CONFIG_ATTR_SELF_POWERED)
// (USB_CONFIG_ATTR_BUS_POWERED)
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
/**
* Device speeds support
* Low speed not supported by CDC and MSC
* @{
*/
//! To define a Low speed device
//#define USB_DEVICE_LOW_SPEED
//! To define a Full speed device
//#define USB_DEVICE_FULL_SPEED
#if MB(ARCHIM1)
#define USB_DEVICE_FULL_SPEED
#endif
//! To authorize the High speed
#ifndef USB_DEVICE_FULL_SPEED
#if (UC3A3||UC3A4)
#define USB_DEVICE_HS_SUPPORT
#elif (SAM3XA||SAM3U)
#define USB_DEVICE_HS_SUPPORT
#endif
#endif
//@}
/**
* USB Device Callbacks definitions (Optional)
* @{
*/
#define UDC_VBUS_EVENT(b_vbus_high)
#define UDC_SOF_EVENT()
#define UDC_SUSPEND_EVENT()
#define UDC_RESUME_EVENT()
#define UDC_GET_EXTRA_STRING() usb_task_extra_string()
#define USB_DEVICE_SPECIFIC_REQUEST() usb_task_other_requests()
//@}
#if ENABLED(SDSUPPORT)
/**
* USB Device low level configuration
* When only one interface is used, these configurations are defined by the class module.
* For composite device, these configuration must be defined here
* @{
*/
//! Control endpoint size
#define USB_DEVICE_EP_CTRL_SIZE 64
//! Two interfaces for this device (CDC COM + CDC DATA + MSC)
#define USB_DEVICE_NB_INTERFACE 3
//! 5 endpoints used by CDC and MSC interfaces
#if SAM3U
// (3 | USB_EP_DIR_IN) // CDC Notify endpoint
// (6 | USB_EP_DIR_IN) // CDC TX
// (5 | USB_EP_DIR_OUT) // CDC RX
// (1 | USB_EP_DIR_IN) // MSC IN
// (2 | USB_EP_DIR_OUT) // MSC OUT
# define USB_DEVICE_MAX_EP 6
# if defined(USB_DEVICE_HS_SUPPORT)
// In HS mode, size of bulk endpoints are 512
// If CDC and MSC endpoints all uses 2 banks, DPRAM is not enough: 4 bulk
// endpoints requires 4K bytes. So reduce the number of banks of CDC bulk
// endpoints to use less DPRAM. Keep MSC setting to keep MSC performance.
# define UDD_BULK_NB_BANK(ep) ((ep == 5 || ep== 6) ? 1 : 2)
#endif
#else
// (3 | USB_EP_DIR_IN) // CDC Notify endpoint
// (4 | USB_EP_DIR_IN) // CDC TX
// (5 | USB_EP_DIR_OUT) // CDC RX
// (1 | USB_EP_DIR_IN) // MSC IN
// (2 | USB_EP_DIR_OUT) // MSC OUT
# define USB_DEVICE_MAX_EP 5
# if SAM3XA && defined(USB_DEVICE_HS_SUPPORT)
// In HS mode, size of bulk endpoints are 512
// If CDC and MSC endpoints all uses 2 banks, DPRAM is not enough: 4 bulk
// endpoints requires 4K bytes. So reduce the number of banks of CDC bulk
// endpoints to use less DPRAM. Keep MSC setting to keep MSC performance.
# define UDD_BULK_NB_BANK(ep) ((ep == 4 || ep== 5) ? 1 : 2)
# endif
#endif
#endif
//@}
//@}
/**
* USB Interface Configuration
* @{
*/
/**
* Configuration of CDC interface
* @{
*/
//! Define one USB communication ports
#define UDI_CDC_PORT_NB 1
//! Interface callback definition
#define UDI_CDC_ENABLE_EXT(port) usb_task_cdc_enable(port)
#define UDI_CDC_DISABLE_EXT(port) usb_task_cdc_disable(port)
#define UDI_CDC_RX_NOTIFY(port) usb_task_cdc_rx_notify(port)
#define UDI_CDC_TX_EMPTY_NOTIFY(port)
#define UDI_CDC_SET_CODING_EXT(port,cfg) usb_task_cdc_config(port,cfg)
#define UDI_CDC_SET_DTR_EXT(port,set) usb_task_cdc_set_dtr(port,set)
#define UDI_CDC_SET_RTS_EXT(port,set)
//! Define it when the transfer CDC Device to Host is a low rate (<512000 bauds)
//! to reduce CDC buffers size
//#define UDI_CDC_LOW_RATE
//! Default configuration of communication port
#define UDI_CDC_DEFAULT_RATE 115200
#define UDI_CDC_DEFAULT_STOPBITS CDC_STOP_BITS_1
#define UDI_CDC_DEFAULT_PARITY CDC_PAR_NONE
#define UDI_CDC_DEFAULT_DATABITS 8
//! Enable id string of interface to add an extra USB string
#define UDI_CDC_IAD_STRING_ID 4
#if ENABLED(SDSUPPORT)
/**
* USB CDC low level configuration
* In standalone these configurations are defined by the CDC module.
* For composite device, these configuration must be defined here
* @{
*/
//! Endpoint numbers definition
#if SAM3U
# define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint
# define UDI_CDC_DATA_EP_IN_0 (6 | USB_EP_DIR_IN) // TX
# define UDI_CDC_DATA_EP_OUT_0 (5 | USB_EP_DIR_OUT)// RX
#else
# define UDI_CDC_COMM_EP_0 (3 | USB_EP_DIR_IN) // Notify endpoint
# define UDI_CDC_DATA_EP_IN_0 (4 | USB_EP_DIR_IN) // TX
# define UDI_CDC_DATA_EP_OUT_0 (5 | USB_EP_DIR_OUT)// RX
#endif
//! Interface numbers
#define UDI_CDC_COMM_IFACE_NUMBER_0 0
#define UDI_CDC_DATA_IFACE_NUMBER_0 1
//@}
//@}
/**
* Configuration of MSC interface
* @{
*/
//! Vendor name and Product version of MSC interface
#define UDI_MSC_GLOBAL_VENDOR_ID \
'M', 'A', 'R', 'L', 'I', 'N', '3', 'D'
#define UDI_MSC_GLOBAL_PRODUCT_VERSION \
'1', '.', '0', '0'
//! Interface callback definition
#define UDI_MSC_ENABLE_EXT() usb_task_msc_enable()
#define UDI_MSC_DISABLE_EXT() usb_task_msc_disable()
//! Enable id string of interface to add an extra USB string
#define UDI_MSC_STRING_ID 5
/**
* USB MSC low level configuration
* In standalone these configurations are defined by the MSC module.
* For composite device, these configuration must be defined here
* @{
*/
//! Endpoint numbers definition
#define UDI_MSC_EP_IN (1 | USB_EP_DIR_IN)
#define UDI_MSC_EP_OUT (2 | USB_EP_DIR_OUT)
//! Interface number
#define UDI_MSC_IFACE_NUMBER 2
//@}
//@}
//@}
/**
* Description of Composite Device
* @{
*/
//! USB Interfaces descriptor structure
#define UDI_COMPOSITE_DESC_T \
usb_iad_desc_t udi_cdc_iad; \
udi_cdc_comm_desc_t udi_cdc_comm; \
udi_cdc_data_desc_t udi_cdc_data; \
udi_msc_desc_t udi_msc
//! USB Interfaces descriptor value for Full Speed
#define UDI_COMPOSITE_DESC_FS \
.udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
.udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
.udi_cdc_data = UDI_CDC_DATA_DESC_0_FS, \
.udi_msc = UDI_MSC_DESC_FS
//! USB Interfaces descriptor value for High Speed
#define UDI_COMPOSITE_DESC_HS \
.udi_cdc_iad = UDI_CDC_IAD_DESC_0, \
.udi_cdc_comm = UDI_CDC_COMM_DESC_0, \
.udi_cdc_data = UDI_CDC_DATA_DESC_0_HS, \
.udi_msc = UDI_MSC_DESC_HS
//! USB Interface APIs
#define UDI_COMPOSITE_API \
&udi_api_cdc_comm, \
&udi_api_cdc_data, \
&udi_api_msc
//@}
/**
* USB Device Driver Configuration
* @{
*/
//@}
//! The includes of classes and other headers must be done at the end of this file to avoid compile error
#include "udi_cdc.h"
#include "udi_msc.h"
#else
#include "udi_cdc_conf.h"
#endif
#include "usb_task.h"
#endif // _CONF_USB_H_

View File

@@ -1,115 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#include "../../MarlinCore.h"
#include "watchdog.h"
// Override Arduino runtime to either config or disable the watchdog
//
// We need to configure the watchdog as soon as possible in the boot
// process, because watchdog initialization at hardware reset on SAM3X8E
// is unreliable, and there is risk of unintended resets if we delay
// that initialization to a later time.
void watchdogSetup() {
#if ENABLED(USE_WATCHDOG)
// 4 seconds timeout
uint32_t timeout = 4000;
// Calculate timeout value in WDT counter ticks: This assumes
// the slow clock is running at 32.768 kHz watchdog
// frequency is therefore 32768 / 128 = 256 Hz
timeout = (timeout << 8) / 1000;
if (timeout == 0)
timeout = 1;
else if (timeout > 0xFFF)
timeout = 0xFFF;
// We want to enable the watchdog with the specified timeout
uint32_t value =
WDT_MR_WDV(timeout) | // With the specified timeout
WDT_MR_WDD(timeout) | // and no invalid write window
#if !(SAMV70 || SAMV71 || SAME70 || SAMS70)
WDT_MR_WDRPROC | // WDT fault resets processor only - We want
// to keep PIO controller state
#endif
WDT_MR_WDDBGHLT | // WDT stops in debug state.
WDT_MR_WDIDLEHLT; // WDT stops in idle state.
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
// Configure WDT to only trigger an interrupt
value |= WDT_MR_WDFIEN; // Enable WDT fault 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();
// Initialize WDT with the given parameters
WDT_Enable(WDT, value);
// 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
// a WDT fault triggers a reset
value |= WDT_MR_WDRSTEN;
// Initialize WDT with the given parameters
WDT_Enable(WDT, value);
#endif
// Reset the watchdog
WDT_Restart(WDT);
#else
// Make sure to completely disable the Watchdog
WDT_Disable(WDT);
#endif
}
#if ENABLED(USE_WATCHDOG)
// Initialize watchdog - On SAM3X, Watchdog was already configured
// and enabled or disabled at startup, so no need to reconfigure it
// here.
void watchdog_init() {
// Reset watchdog to start clean
WDT_Restart(WDT);
}
#endif // USE_WATCHDOG
#endif

View File

@@ -1,303 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "HAL.h"
#include "timers.h"
#include <rom/rtc.h>
#include <driver/adc.h>
#include <esp_adc_cal.h>
#include <HardwareSerial.h>
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#include <ESPAsyncWebServer.h>
#include "wifi.h"
#if ENABLED(OTASUPPORT)
#include "ota.h"
#endif
#if ENABLED(WEBSUPPORT)
#include "spiffs.h"
#include "web.h"
#endif
#endif
// ------------------------
// Externs
// ------------------------
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
// ------------------------
// Local defines
// ------------------------
#define V_REF 1100
// ------------------------
// Public Variables
// ------------------------
uint16_t HAL_adc_result;
// ------------------------
// Private Variables
// ------------------------
esp_adc_cal_characteristics_t characteristics[ADC_ATTEN_MAX];
adc_atten_t attenuations[ADC1_CHANNEL_MAX] = {};
uint32_t thresholds[ADC_ATTEN_MAX];
volatile int numPWMUsed = 0,
pwmPins[MAX_PWM_PINS],
pwmValues[MAX_PWM_PINS];
// ------------------------
// Public functions
// ------------------------
#if ENABLED(WIFI_CUSTOM_COMMAND)
bool wifi_custom_command(char * const command_ptr) {
#if ENABLED(ESP3D_WIFISUPPORT)
return esp3dlib.parse(command_ptr);
#else
UNUSED(command_ptr);
return false;
#endif
}
#endif
void HAL_init() { i2s_init(); }
void HAL_init_board() {
#if ENABLED(ESP3D_WIFISUPPORT)
esp3dlib.init();
#elif ENABLED(WIFISUPPORT)
wifi_init();
#if ENABLED(OTASUPPORT)
OTA_init();
#endif
#if ENABLED(WEBSUPPORT)
spiffs_init();
web_init();
#endif
server.begin();
#endif
// ESP32 uses a GPIO matrix that allows pins to be assigned to hardware serial ports.
// The following code initializes hardware Serial1 and Serial2 to use user-defined pins
// if they have been defined.
#if defined(HARDWARE_SERIAL1_RX) && defined(HARDWARE_SERIAL1_TX)
HardwareSerial Serial1(1);
#ifdef TMC_BAUD_RATE // use TMC_BAUD_RATE for Serial1 if defined
Serial1.begin(TMC_BAUD_RATE, SERIAL_8N1, HARDWARE_SERIAL1_RX, HARDWARE_SERIAL1_TX);
#else // use default BAUDRATE if TMC_BAUD_RATE not defined
Serial1.begin(BAUDRATE, SERIAL_8N1, HARDWARE_SERIAL1_RX, HARDWARE_SERIAL1_TX);
#endif
#endif
#if defined(HARDWARE_SERIAL2_RX) && defined(HARDWARE_SERIAL2_TX)
HardwareSerial Serial2(2);
#ifdef TMC_BAUD_RATE // use TMC_BAUD_RATE for Serial1 if defined
Serial2.begin(TMC_BAUD_RATE, SERIAL_8N1, HARDWARE_SERIAL2_RX, HARDWARE_SERIAL2_TX);
#else // use default BAUDRATE if TMC_BAUD_RATE not defined
Serial2.begin(BAUDRATE, SERIAL_8N1, HARDWARE_SERIAL2_RX, HARDWARE_SERIAL2_TX);
#endif
#endif
}
void HAL_idletask() {
#if BOTH(WIFISUPPORT, OTASUPPORT)
OTA_handle();
#endif
#if ENABLED(ESP3D_WIFISUPPORT)
esp3dlib.idletask();
#endif
}
void HAL_clear_reset_source() { }
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
void _delay_ms(int delay_ms) { delay(delay_ms); }
// return free memory between end of heap (or end bss) and whatever is current
int freeMemory() { return ESP.getFreeHeap(); }
// ------------------------
// ADC
// ------------------------
#define ADC1_CHANNEL(pin) ADC1_GPIO ## pin ## _CHANNEL
adc1_channel_t get_channel(int pin) {
switch (pin) {
case 39: return ADC1_CHANNEL(39);
case 36: return ADC1_CHANNEL(36);
case 35: return ADC1_CHANNEL(35);
case 34: return ADC1_CHANNEL(34);
case 33: return ADC1_CHANNEL(33);
case 32: return ADC1_CHANNEL(32);
}
return ADC1_CHANNEL_MAX;
}
void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) {
if (attenuations[chan] != atten) {
adc1_config_channel_atten(chan, atten);
attenuations[chan] = atten;
}
}
void HAL_adc_init() {
// Configure ADC
adc1_config_width(ADC_WIDTH_12Bit);
// Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects
#if HAS_TEMP_ADC_0
adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_1
adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_2
adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_3
adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_4
adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_5
adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_6
adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_ADC_7
adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db);
#endif
#if HAS_HEATED_BED
adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db);
#endif
#if HAS_TEMP_CHAMBER
adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db);
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db);
#endif
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
// That's why we're not setting it up here.
// Calculate ADC characteristics (i.e., gain and offset factors for each attenuation level)
for (int i = 0; i < ADC_ATTEN_MAX; i++) {
esp_adc_cal_characterize(ADC_UNIT_1, (adc_atten_t)i, ADC_WIDTH_BIT_12, V_REF, &characteristics[i]);
// Change attenuation 100mV below the calibrated threshold
thresholds[i] = esp_adc_cal_raw_to_voltage(4095, &characteristics[i]);
}
}
void HAL_adc_start_conversion(const uint8_t adc_pin) {
const adc1_channel_t chan = get_channel(adc_pin);
uint32_t mv;
esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
HAL_adc_result = mv * 1023.0 / 3300.0;
// Change the attenuation level based on the new reading
adc_atten_t atten;
if (mv < thresholds[ADC_ATTEN_DB_0] - 100)
atten = ADC_ATTEN_DB_0;
else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100)
atten = ADC_ATTEN_DB_2_5;
else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100)
atten = ADC_ATTEN_DB_6;
else if (mv > thresholds[ADC_ATTEN_DB_6] - 50)
atten = ADC_ATTEN_DB_11;
else return;
adc1_set_attenuation(chan, atten);
}
void analogWrite(pin_t pin, int value) {
// Use ledc hardware for internal pins
if (pin < 34) {
static int cnt_channel = 1, pin_to_channel[40] = { 0 };
if (pin_to_channel[pin] == 0) {
ledcAttachPin(pin, cnt_channel);
ledcSetup(cnt_channel, 490, 8);
ledcWrite(cnt_channel, value);
pin_to_channel[pin] = cnt_channel++;
}
ledcWrite(pin_to_channel[pin], value);
return;
}
int idx = -1;
// Search Pin
for (int i = 0; i < numPWMUsed; ++i)
if (pwmPins[i] == pin) { idx = i; break; }
// not found ?
if (idx < 0) {
// No slots remaining
if (numPWMUsed >= MAX_PWM_PINS) return;
// Take new slot for pin
idx = numPWMUsed;
pwmPins[idx] = pin;
// Start timer on first use
if (idx == 0) HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY);
++numPWMUsed;
}
// Use 7bit internal value - add 1 to have 100% high at 255
pwmValues[idx] = (value + 1) / 2;
}
// Handle PWM timer interrupt
HAL_PWM_TIMER_ISR() {
HAL_timer_isr_prologue(PWM_TIMER_NUM);
static uint8_t count = 0;
for (int i = 0; i < numPWMUsed; ++i) {
if (count == 0) // Start of interval
WRITE(pwmPins[i], pwmValues[i] ? HIGH : LOW);
else if (pwmValues[i] == count) // End of duration
WRITE(pwmPins[i], LOW);
}
// 128 for 7 Bit resolution
count = (count + 1) & 0x7F;
HAL_timer_isr_epilogue(PWM_TIMER_NUM);
}
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,180 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
/**
* Description: HAL for Espressif ESP32 WiFi
*/
#define CPU_32_BIT
#include <stdint.h>
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "i2s.h"
#include "timers.h"
#if ENABLED(WIFISUPPORT)
#include "WebSocketSerial.h"
#endif
#if ENABLED(ESP3D_WIFISUPPORT)
#include "esp3dlib.h"
#endif
#include "FlushableHardwareSerial.h"
// ------------------------
// Defines
// ------------------------
extern portMUX_TYPE spinlock;
#define MYSERIAL0 flushableSerial
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
#define MYSERIAL1 Serial2Socket
#else
#define MYSERIAL1 webSocketSerial
#endif
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock)
#define CRITICAL_SECTION_END() portEXIT_CRITICAL(&spinlock)
#define ISRS_ENABLED() (spinlock.owner == portMUX_FREE_VAL)
#define ENABLE_ISRS() if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*(addr))
// ------------------------
// Types
// ------------------------
typedef int16_t pin_t;
#define HAL_SERVO_LIB Servo
// ------------------------
// Public Variables
// ------------------------
/** result of last ADC conversion */
extern uint16_t HAL_adc_result;
// ------------------------
// Public functions
// ------------------------
// clear reset reason
void HAL_clear_reset_source();
// reset reason
uint8_t HAL_get_reset_source();
void _delay_ms(int delay);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int freeMemory();
#pragma GCC diagnostic pop
void analogWrite(pin_t pin, int value);
// EEPROM
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
// ADC
#define HAL_ANALOG_SELECT(pin)
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
void HAL_adc_start_conversion(const uint8_t adc_pin);
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
// Enable hooks into idle and setup for HAL
#define HAL_IDLETASK 1
#define BOARD_INIT() HAL_init_board();
void HAL_idletask();
void HAL_init();
void HAL_init_board();
//
// Delay in cycles (used by DELAY_NS / DELAY_US)
//
FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
unsigned long start, ccount, stop;
/**
* It's important to care for race conditions (and overflows) here.
* Race condition example: If `stop` calculates to being close to the upper boundary of
* `uint32_t` and if at the same time a longer loop interruption kicks in (e.g. due to other
* FreeRTOS tasks or interrupts), `ccount` might overflow (and therefore be below `stop` again)
* without the loop ever being able to notice that `ccount` had already been above `stop` once
* (and that therefore the number of cycles to delay has already passed).
* As DELAY_CYCLES (through DELAY_NS / DELAY_US) is used by software SPI bit banging to drive
* LCDs and therefore might be called very, very often, this seemingly improbable situation did
* actually happen in reality. It resulted in apparently random print pauses of ~17.9 seconds
* (0x100000000 / 240 MHz) or multiples thereof, essentially ruining the current print by causing
* large blobs of filament.
*/
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (start) );
stop = start + x;
ccount = start;
if (stop >= start) {
// no overflow, so only loop while in between start and stop:
// 0x00000000 -----------------start****stop-- 0xffffffff
while (ccount >= start && ccount < stop) {
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
}
}
else {
// stop did overflow, so only loop while outside of stop and start:
// 0x00000000 **stop-------------------start** 0xffffffff
while (ccount >= start || ccount < stop) {
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) );
}
}
}

View File

@@ -1,117 +0,0 @@
/**
* 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
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "HAL.h"
#include "../shared/HAL_SPI.h"
#include <pins_arduino.h>
#include "spi_pins.h"
#include <SPI.h>
#include "../../core/macros.h"
// ------------------------
// Public Variables
// ------------------------
static SPISettings spiConfig;
// ------------------------
// Public functions
// ------------------------
#if ENABLED(SOFTWARE_SPI)
// ------------------------
// Software SPI
// ------------------------
#error "Software SPI not supported for ESP32. Use Hardware SPI."
#else
// ------------------------
// Hardware SPI
// ------------------------
void spiBegin() {
#if !PIN_EXISTS(SS)
#error "SS_PIN not defined!"
#endif
OUT_WRITE(SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
uint32_t clock;
switch (spiRate) {
case SPI_FULL_SPEED: clock = 16000000; break;
case SPI_HALF_SPEED: clock = 8000000; break;
case SPI_QUARTER_SPEED: clock = 4000000; break;
case SPI_EIGHTH_SPEED: clock = 2000000; break;
case SPI_SIXTEENTH_SPEED: clock = 1000000; break;
case SPI_SPEED_5: clock = 500000; break;
case SPI_SPEED_6: clock = 250000; break;
default: clock = 1000000; // Default from the SPI library
}
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
SPI.begin();
}
uint8_t spiRec() {
SPI.beginTransaction(spiConfig);
uint8_t returnByte = SPI.transfer(0xFF);
SPI.endTransaction();
return returnByte;
}
void spiRead(uint8_t* buf, uint16_t nbyte) {
SPI.beginTransaction(spiConfig);
SPI.transferBytes(0, buf, nbyte);
SPI.endTransaction();
}
void spiSend(uint8_t b) {
SPI.beginTransaction(spiConfig);
SPI.transfer(b);
SPI.endTransaction();
}
void spiSendBlock(uint8_t token, const uint8_t* buf) {
SPI.beginTransaction(spiConfig);
SPI.transfer(token);
SPI.writeBytes(const_cast<uint8_t*>(buf), 512);
SPI.endTransaction();
}
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
spiConfig = SPISettings(spiClock, bitOrder, dataMode);
SPI.beginTransaction(spiConfig);
}
#endif // !SOFTWARE_SPI
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,71 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "Servo.h"
// Adjacent channels (0/1, 2/3 etc.) share the same timer and therefore the same frequency and resolution settings on ESP32,
// so we only allocate servo channels up high to avoid side effects with regards to analogWrite (fans, leds, laser pwm etc.)
int Servo::channel_next_free = 12;
Servo::Servo() {
channel = channel_next_free++;
}
int8_t Servo::attach(const int inPin) {
if (channel >= CHANNEL_MAX_NUM) return -1;
if (inPin > 0) pin = inPin;
ledcSetup(channel, 50, 16); // channel X, 50 Hz, 16-bit depth
ledcAttachPin(pin, channel);
return true;
}
void Servo::detach() { ledcDetachPin(pin); }
int Servo::read() { return degrees; }
void Servo::write(int inDegrees) {
degrees = constrain(inDegrees, MIN_ANGLE, MAX_ANGLE);
int us = map(degrees, MIN_ANGLE, MAX_ANGLE, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
int duty = map(us, 0, TAU_USEC, 0, MAX_COMPARE);
ledcWrite(channel, duty);
}
void Servo::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(0) >= 0) {
write(value);
safe_delay(servo_delay[channel]);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
detach();
#endif
}
}
#endif // HAS_SERVOS
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,63 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
#include "../shared/eeprom_api.h"
#include "EEPROM.h"
#define EEPROM_SIZE 4096
bool PersistentStore::access_start() {
return EEPROM.begin(EEPROM_SIZE);
}
bool PersistentStore::access_finish() {
EEPROM.end();
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
for (size_t i = 0; i < size; i++) {
EEPROM.write(pos++, value[i]);
crc16(crc, &value[i], 1);
}
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
for (size_t i = 0; i < size; i++) {
uint8_t c = EEPROM.read(pos++);
if (writing) value[i] = c;
crc16(crc, &c, 1);
}
return false;
}
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
#endif // EEPROM_SETTINGS
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,84 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Endstop Interrupts
*
* Without endstop interrupts the endstop pins must be polled continually in
* the stepper-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 ICACHE_RAM_ATTR endstop_ISR() { endstops.update(); }
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
#if HAS_X_MAX
_ATTACH(X_MAX_PIN);
#endif
#if HAS_X_MIN
_ATTACH(X_MIN_PIN);
#endif
#if HAS_Y_MAX
_ATTACH(Y_MAX_PIN);
#endif
#if HAS_Y_MIN
_ATTACH(Y_MIN_PIN);
#endif
#if HAS_Z_MAX
_ATTACH(Z_MAX_PIN);
#endif
#if HAS_Z_MIN
_ATTACH(Z_MIN_PIN);
#endif
#if HAS_Z2_MAX
_ATTACH(Z2_MAX_PIN);
#endif
#if HAS_Z2_MIN
_ATTACH(Z2_MIN_PIN);
#endif
#if HAS_Z3_MAX
_ATTACH(Z3_MAX_PIN);
#endif
#if HAS_Z3_MIN
_ATTACH(Z3_MIN_PIN);
#endif
#if HAS_Z4_MAX
_ATTACH(Z4_MAX_PIN);
#endif
#if HAS_Z4_MIN
_ATTACH(Z4_MIN_PIN);
#endif
#if HAS_Z_MIN_PROBE_PIN
_ATTACH(Z_MIN_PROBE_PIN);
#endif
}

View File

@@ -1,27 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
// If no real EEPROM, Flash emulation, or SRAM emulation is available fall back to SD emulation
#if ENABLED(EEPROM_SETTINGS) && NONE(USE_WIRED_EEPROM, FLASH_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
#define SDCARD_EEPROM_EMULATION
#endif

View File

@@ -1,44 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#if BOTH(WIFISUPPORT, WEBSUPPORT)
#include "../../core/serial.h"
#include <FS.h>
#include <SPIFFS.h>
bool spiffs_initialized;
void spiffs_init() {
if (SPIFFS.begin(true)) // formatOnFail = true
spiffs_initialized = true;
else
SERIAL_ERROR_MSG("SPIFFS mount failed");
}
#endif // WIFISUPPORT && WEBSUPPORT
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,174 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include <stdio.h>
#include <esp_types.h>
#include <soc/timer_group_struct.h>
#include <driver/periph_ctrl.h>
#include <driver/timer.h>
#include "HAL.h"
#include "timers.h"
// ------------------------
// Local defines
// ------------------------
#define NUM_HARDWARE_TIMERS 4
// ------------------------
// Private Variables
// ------------------------
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
{ TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3
};
// ------------------------
// Public functions
// ------------------------
void IRAM_ATTR timer_isr(void *para) {
const tTimerConfig& timer = TimerConfig[(int)para];
// Retrieve the interrupt status and the counter value
// from the timer that reported the interrupt
uint32_t intr_status = TG[timer.group]->int_st_timers.val;
TG[timer.group]->hw_timer[timer.idx].update = 1;
// Clear the interrupt
if (intr_status & BIT(timer.idx)) {
switch (timer.idx) {
case TIMER_0: TG[timer.group]->int_clr_timers.t0 = 1; break;
case TIMER_1: TG[timer.group]->int_clr_timers.t1 = 1; break;
case TIMER_MAX: break;
}
}
timer.fn();
// After the alarm has been triggered
// Enable it again so it gets triggered the next time
TG[timer.group]->hw_timer[timer.idx].config.alarm_en = TIMER_ALARM_EN;
}
/**
* Enable and initialize the timer
* @param timer_num timer number to initialize
* @param frequency frequency of the timer
*/
void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
const tTimerConfig timer = TimerConfig[timer_num];
timer_config_t config;
config.divider = timer.divider;
config.counter_dir = TIMER_COUNT_UP;
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.intr_type = TIMER_INTR_LEVEL;
config.auto_reload = true;
// Select and initialize the timer
timer_init(timer.group, timer.idx, &config);
// Timer counter initial value and auto reload on alarm
timer_set_counter_value(timer.group, timer.idx, 0x00000000ULL);
// Configure the alam value and the interrupt on alarm
timer_set_alarm_value(timer.group, timer.idx, (HAL_TIMER_RATE) / timer.divider / frequency - 1);
timer_enable_intr(timer.group, timer.idx);
timer_isr_register(timer.group, timer.idx, timer_isr, (void*)(uint32_t)timer_num, 0, nullptr);
timer_start(timer.group, timer.idx);
}
/**
* Set the upper value of the timer, when the timer reaches this upper value the
* interrupt should be triggered and the counter reset
* @param timer_num timer number to set the count to
* @param count threshold at which the interrupt is triggered
*/
void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
const tTimerConfig timer = TimerConfig[timer_num];
timer_set_alarm_value(timer.group, timer.idx, count);
}
/**
* Get the current upper value of the timer
* @param timer_num timer number to get the count from
* @return the timer current threshold for the alarm to be triggered
*/
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
uint64_t alarm_value;
timer_get_alarm_value(timer.group, timer.idx, &alarm_value);
return alarm_value;
}
/**
* Get the current counter value between 0 and the maximum count (HAL_timer_set_count)
* @param timer_num timer number to get the current count
* @return the current counter of the alarm
*/
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
uint64_t counter_value;
timer_get_counter_value(timer.group, timer.idx, &counter_value);
return counter_value;
}
/**
* Enable timer interrupt on the timer
* @param timer_num timer number to enable interrupts on
*/
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
//const tTimerConfig timer = TimerConfig[timer_num];
//timer_enable_intr(timer.group, timer.idx);
}
/**
* Disable timer interrupt on the timer
* @param timer_num timer number to disable interrupts on
*/
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
//const tTimerConfig timer = TimerConfig[timer_num];
//timer_disable_intr(timer.group, timer.idx);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
return TG[timer.group]->int_ena.val | BIT(timer_num);
}
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,121 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
#include <driver/timer.h>
// Includes needed to get I2S_STEPPER_STREAM. Note that pins.h
// is included in case this header is being included early.
#include "../../inc/MarlinConfig.h"
#include "../../pins/pins.h"
// ------------------------
// Defines
// ------------------------
//
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL
#define STEP_TIMER_NUM 0 // index of timer to use for stepper
#define TEMP_TIMER_NUM 1 // index of timer to use for temperature
#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
#if ENABLED(I2S_STEPPER_STREAM)
#define STEPPER_TIMER_PRESCALE 1
#define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25
#else
#define STEPPER_TIMER_PRESCALE 40
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
#endif
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
#define PWM_TIMER_PRESCALE 10
#if ENABLED(FAST_PWM_FAN)
#define PWM_TIMER_FREQUENCY FAST_PWM_FAN_FREQUENCY
#else
#define PWM_TIMER_FREQUENCY (50*128) // 50Hz and 7bit resolution
#endif
#define MAX_PWM_PINS 32 // Number of PWM pin-slots
#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(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler()
#define HAL_STEP_TIMER_ISR() extern "C" void stepTC_Handler()
#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler()
extern "C" void tempTC_Handler();
extern "C" void stepTC_Handler();
extern "C" void pwmTC_Handler();
// ------------------------
// Types
// ------------------------
typedef struct {
timer_group_t group;
timer_idx_t idx;
uint32_t divider;
void (*fn)();
} tTimerConfig;
// ------------------------
// Public Variables
// ------------------------
extern const tTimerConfig TimerConfig[];
// ------------------------
// Public functions
// ------------------------
void HAL_timer_start (const uint8_t timer_num, uint32_t frequency);
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t count);
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)

View File

@@ -1,41 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
void watchdogSetup() {
// do whatever. don't remove this function.
}
void watchdog_init() {
// TODO
}
#endif // USE_WATCHDOG
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,48 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#if BOTH(WIFISUPPORT, WEBSUPPORT)
#include "../../inc/MarlinConfig.h"
#undef DISABLED // esp32-hal-gpio.h
#include <SPIFFS.h>
#include "wifi.h"
AsyncEventSource events("/events"); // event source (Server-Sent events)
void onNotFound(AsyncWebServerRequest *request) {
request->send(404);
}
void web_init() {
server.addHandler(&events); // attach AsyncEventSource
server.serveStatic("/", SPIFFS, "/www").setDefaultFile("index.html");
server.onNotFound(onNotFound);
}
#endif // WIFISUPPORT && WEBSUPPORT
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,67 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../core/serial.h"
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ESPAsyncWebServer.h>
#include "wifi.h"
AsyncWebServer server(80);
#ifndef WIFI_HOSTNAME
#define WIFI_HOSTNAME DEFAULT_WIFI_HOSTNAME
#endif
void wifi_init() {
SERIAL_ECHO_MSG("Starting WiFi...");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PWD);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
SERIAL_ERROR_MSG("Unable to connect to WiFi with SSID '" WIFI_SSID "', restarting.");
delay(5000);
ESP.restart();
}
delay(10);
if (!MDNS.begin(WIFI_HOSTNAME)) {
SERIAL_ERROR_MSG("Unable to start mDNS with hostname '" WIFI_HOSTNAME "', restarting.");
delay(5000);
ESP.restart();
}
MDNS.addService("http", "tcp", 80);
SERIAL_ECHOLNPAIR("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str());
}
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32

View File

@@ -1,34 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "platforms.h"
#include HAL_PATH(.,HAL.h)
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
inline void watchdog_refresh() {
#if ENABLED(USE_WATCHDOG)
HAL_watchdog_refresh();
#endif
}

View File

@@ -1,82 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
HalSerial usb_serial;
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
}
extern "C" void u8g_MicroDelay() {
u8g_xMicroDelay(1);
}
extern "C" void u8g_10MicroDelay() {
u8g_xMicroDelay(10);
}
extern "C" void u8g_Delay(uint16_t val) {
delay(val);
}
//************************//
// return free heap space
int freeMemory() {
return 0;
}
// ------------------------
// ADC
// ------------------------
void HAL_adc_init() {
}
void HAL_adc_enable_channel(const uint8_t ch) {
}
uint8_t active_ch = 0;
void HAL_adc_start_conversion(const uint8_t ch) {
active_ch = ch;
}
bool HAL_adc_finished() {
return true;
}
uint16_t HAL_adc_get_result() {
pin_t pin = analogInputToDigitalPin(active_ch);
if (!VALID_PIN(pin)) return 0;
uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
return data; // return 10bit value as Marlin expects
}
void HAL_pwm_init() {
}
#endif // __PLAT_LINUX__

View File

@@ -1,108 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define CPU_32_BIT
#define F_CPU 100000000
#define SystemCoreClock F_CPU
#include <iostream>
#include <stdint.h>
#include <stdarg.h>
#undef min
#undef max
#include <algorithm>
void _printf (const char *format, ...);
void _putc(uint8_t c);
uint8_t _getc();
//extern "C" volatile uint32_t _millis;
//arduino: Print.h
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
//arduino: binary.h (weird defines)
#define B01 1
#define B10 2
#include "hardware/Clock.h"
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "timers.h"
#include "serial.h"
#define SHARED_SERVOS HAS_SERVOS
extern HalSerial usb_serial;
#define MYSERIAL0 usb_serial
#define NUM_SERIAL 1
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
#define ST7920_DELAY_3 DELAY_NS(750)
//
// Interrupts
//
#define CRITICAL_SECTION_START()
#define CRITICAL_SECTION_END()
#define ISRS_ENABLED()
#define ENABLE_ISRS()
#define DISABLE_ISRS()
inline void HAL_init() {}
// Utility functions
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int freeMemory();
#pragma GCC diagnostic pop
// ADC
#define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch)
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
void HAL_adc_init();
void HAL_adc_enable_channel(const uint8_t ch);
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
// Reset source
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}

View File

@@ -1,116 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <iostream>
#include "../../inc/MarlinConfig.h"
#include "hardware/Clock.h"
#include "../shared/Delay.h"
// Interrupts
void cli() { } // Disable
void sei() { } // Enable
// Time functions
void _delay_ms(const int delay_ms) {
delay(delay_ms);
}
uint32_t millis() {
return (uint32_t)Clock::millis();
}
// This is required for some Arduino libraries we are using
void delayMicroseconds(uint32_t us) {
Clock::delayMicros(us);
}
extern "C" void delay(const int msec) {
Clock::delayMillis(msec);
}
// IO functions
// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2)
void pinMode(const pin_t pin, const uint8_t mode) {
if (!VALID_PIN(pin)) return;
Gpio::setMode(pin, mode);
}
void digitalWrite(pin_t pin, uint8_t pin_status) {
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pin_status);
}
bool digitalRead(pin_t pin) {
if (!VALID_PIN(pin)) return false;
return Gpio::get(pin);
}
void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pwm_value);
}
uint16_t analogRead(pin_t adc_pin) {
if (!VALID_PIN(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin))) return 0;
return Gpio::get(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin));
}
// **************************
// Persistent Config Storage
// **************************
void eeprom_write_byte(unsigned char *pos, unsigned char value) {
}
unsigned char eeprom_read_byte(uint8_t * pos) { return '\0'; }
void eeprom_read_block(void *__dst, const void *__src, size_t __n) { }
void eeprom_update_block(const void *__src, void *__dst, size_t __n) { }
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s) {
char format_string[20];
snprintf(format_string, 20, "%%%d.%df", __width, __prec);
sprintf(__s, format_string, __val);
return __s;
}
int32_t random(int32_t max) {
return rand() % max;
}
int32_t random(int32_t min, int32_t max) {
return min + rand() % (max - min);
}
void randomSeed(uint32_t value) {
srand(value);
}
int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
#endif // __PLAT_LINUX__

View File

@@ -1,102 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS)
#include "../shared/eeprom_api.h"
#include <stdio.h>
#define LINUX_EEPROM_SIZE (E2END + 1)
uint8_t buffer[LINUX_EEPROM_SIZE];
char filename[] = "eeprom.dat";
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;
FILE * eeprom_file = fopen(filename, "rb");
if (eeprom_file == nullptr) return false;
fseek(eeprom_file, 0L, SEEK_END);
std::size_t file_size = ftell(eeprom_file);
if (file_size < LINUX_EEPROM_SIZE) {
memset(buffer + file_size, eeprom_erase_value, LINUX_EEPROM_SIZE - file_size);
}
else {
fseek(eeprom_file, 0L, SEEK_SET);
fread(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
}
fclose(eeprom_file);
return true;
}
bool PersistentStore::access_finish() {
FILE * eeprom_file = fopen(filename, "wb");
if (eeprom_file == nullptr) return false;
fwrite(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
fclose(eeprom_file);
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
std::size_t bytes_written = 0;
for (std::size_t i = 0; i < size; i++) {
buffer[pos+i] = value[i];
bytes_written ++;
}
crc16(crc, value, size);
pos = pos + size;
return (bytes_written != size); // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
std::size_t bytes_read = 0;
if (writing) {
for (std::size_t i = 0; i < size; i++) {
value[i] = buffer[pos+i];
bytes_read ++;
}
crc16(crc, value, size);
}
else {
uint8_t temp[size];
for (std::size_t i = 0; i < size; i++) {
temp[i] = buffer[pos+i];
bytes_read ++;
}
crc16(crc, temp, size);
}
pos = pos + size;
return bytes_read != size; // return true for any error
}
size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM
#endif // EEPROM_SETTINGS
#endif // __PLAT_LINUX__

View File

@@ -1,32 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../../inc/MarlinConfig.h"
#include "Clock.h"
std::chrono::nanoseconds Clock::startup = std::chrono::high_resolution_clock::now().time_since_epoch();
uint32_t Clock::frequency = F_CPU;
double Clock::time_multiplier = 1.0;
#endif // __PLAT_LINUX__

View File

@@ -1,30 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Gpio.h"
pin_data Gpio::pin_map[Gpio::pin_count+1] = {};
IOLogger* Gpio::logger = nullptr;
#endif // __PLAT_LINUX__

View File

@@ -1,61 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Clock.h"
#include <stdio.h>
#include "../../../inc/MarlinConfig.h"
#include "Heater.h"
Heater::Heater(pin_t heater, pin_t adc) {
heater_state = 0;
room_temp_raw = 150;
last = Clock::micros();
heater_pin = heater;
adc_pin = adc;
heat = 0.0;
}
Heater::~Heater() {
}
void Heater::update() {
// crude pwm read and cruder heat simulation
auto now = Clock::micros();
double delta = (now - last);
if (delta > 1000 ) {
heater_state = pwmcap.update(0xFFFF * Gpio::pin_map[heater_pin].value);
last = now;
heat += (heater_state - heat) * (delta / 1000000000.0);
NOLESS(heat, room_temp_raw);
Gpio::pin_map[analogInputToDigitalPin(adc_pin)].value = 0xFFFF - (uint16_t)heat;
}
}
void Heater::interrupt(GpioEvent ev) {
// ununsed
}
#endif // __PLAT_LINUX__

View File

@@ -1,50 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "IOLoggerCSV.h"
IOLoggerCSV::IOLoggerCSV(std::string filename) {
file.open(filename);
}
IOLoggerCSV::~IOLoggerCSV() {
file.close();
}
void IOLoggerCSV::log(GpioEvent ev) {
std::lock_guard<std::mutex> lock(vector_lock);
events.push_back(ev); //minimal impact to signal handler
}
void IOLoggerCSV::flush() {
{ std::lock_guard<std::mutex> lock(vector_lock);
while (!events.empty()) {
file << events.front().timestamp << ", "<< events.front().pin_id << ", " << events.front().event << std::endl;
events.pop_front();
}
}
file.flush();
}
#endif // __PLAT_LINUX__

View File

@@ -1,66 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <random>
#include <stdio.h>
#include "Clock.h"
#include "LinearAxis.h"
LinearAxis::LinearAxis(pin_type enable, pin_type dir, pin_type step, pin_type end_min, pin_type end_max) {
enable_pin = enable;
dir_pin = dir;
step_pin = step;
min_pin = end_min;
max_pin = end_max;
min_position = 50;
max_position = (200*80) + min_position;
position = rand() % ((max_position - 40) - min_position) + (min_position + 20);
last_update = Clock::nanos();
Gpio::attachPeripheral(step_pin, this);
}
LinearAxis::~LinearAxis() {
}
void LinearAxis::update() {
}
void LinearAxis::interrupt(GpioEvent ev) {
if (ev.pin_id == step_pin && !Gpio::pin_map[enable_pin].value){
if (ev.event == GpioEvent::RISE) {
last_update = ev.timestamp;
position += -1 + 2 * Gpio::pin_map[dir_pin].value;
Gpio::pin_map[min_pin].value = (position < min_position);
//Gpio::pin_map[max_pin].value = (position > max_position);
//if (position < min_position) printf("axis(%d) endstop : pos: %d, mm: %f, min: %d\n", step_pin, position, position / 80.0, Gpio::pin_map[min_pin].value);
}
}
}
#endif // __PLAT_LINUX__

View File

@@ -1,118 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "Timer.h"
#include <stdio.h>
Timer::Timer() {
active = false;
compare = 0;
frequency = 0;
overruns = 0;
timerid = 0;
cbfn = nullptr;
period = 0;
start_time = 0;
avg_error = 0;
}
Timer::~Timer() {
timer_delete(timerid);
}
void Timer::init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn) {
struct sigaction sa;
struct sigevent sev;
frequency = sim_freq;
cbfn = fn;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = Timer::handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, nullptr) == -1) {
return; // todo: handle error
}
sigemptyset(&mask);
sigaddset(&mask, SIGRTMIN);
disable();
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = (void*)this;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
return; // todo: handle error
}
}
void Timer::start(uint32_t frequency) {
setCompare(this->frequency / frequency);
//printf("timer(%ld) started\n", getID());
}
void Timer::enable() {
if (sigprocmask(SIG_UNBLOCK, &mask, nullptr) == -1) {
return; // todo: handle error
}
active = true;
//printf("timer(%ld) enabled\n", getID());
}
void Timer::disable() {
if (sigprocmask(SIG_SETMASK, &mask, nullptr) == -1) {
return; // todo: handle error
}
active = false;
}
void Timer::setCompare(uint32_t compare) {
uint32_t nsec_offset = 0;
if (active) {
nsec_offset = Clock::nanos() - this->start_time; // calculate how long the timer would have been running for
nsec_offset = nsec_offset < 1000 ? nsec_offset : 0; // constrain, this shouldn't be needed but apparently Marlin enables interrupts on the stepper timer before initialising it, todo: investigate ?bug?
}
this->compare = compare;
uint64_t ns = Clock::ticksToNanos(compare, frequency) - nsec_offset;
struct itimerspec its;
its.it_value.tv_sec = ns / 1000000000;
its.it_value.tv_nsec = ns % 1000000000;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
if (timer_settime(timerid, 0, &its, nullptr) == -1) {
printf("timer(%ld) failed, compare: %d(%ld)\n", getID(), compare, its.it_value.tv_nsec);
return; // todo: handle error
}
//printf("timer(%ld) started, compare: %d(%d)\n", getID(), compare, its.it_value.tv_nsec);
this->period = its.it_value.tv_nsec;
this->start_time = Clock::nanos();
}
uint32_t Timer::getCount() {
return Clock::nanosToTicks(Clock::nanos() - this->start_time, frequency);
}
#endif // __PLAT_LINUX__

View File

@@ -1,121 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <math.h>
#include <cstring>
#include <pinmapping.h>
#define HIGH 0x01
#define LOW 0x00
#define INPUT 0x00
#define OUTPUT 0x01
#define INPUT_PULLUP 0x02
#define INPUT_PULLDOWN 0x03
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 0x02
#define FALLING 0x03
#define RISING 0x04
typedef uint8_t byte;
#define PROGMEM
#define PSTR(v) (v)
#define PGM_P const char *
// Used for libraries, preprocessor, and constants
#define abs(x) ((x)>0?(x):-(x))
#ifndef isnan
#define isnan std::isnan
#endif
#ifndef isinf
#define isinf std::isinf
#endif
#define sq(v) ((v) * (v))
#define square(v) sq(v)
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))
//Interrupts
void cli(); // Disable
void sei(); // Enable
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
void detachInterrupt(uint32_t pin);
extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
// Program Memory
#define pgm_read_ptr(addr) (*((void**)(addr)))
#define pgm_read_byte_near(addr) (*((uint8_t*)(addr)))
#define pgm_read_float_near(addr) (*((float*)(addr)))
#define pgm_read_word_near(addr) (*((uint16_t*)(addr)))
#define pgm_read_dword_near(addr) (*((uint32_t*)(addr)))
#define pgm_read_byte(addr) pgm_read_byte_near(addr)
#define pgm_read_float(addr) pgm_read_float_near(addr)
#define pgm_read_word(addr) pgm_read_word_near(addr)
#define pgm_read_dword(addr) pgm_read_dword_near(addr)
using std::memcpy;
#define memcpy_P memcpy
#define sprintf_P sprintf
#define strstr_P strstr
#define strncpy_P strncpy
#define vsnprintf_P vsnprintf
#define strcpy_P strcpy
#define snprintf_P snprintf
#define strlen_P strlen
// Time functions
extern "C" {
void delay(const int milis);
}
void _delay_ms(const int delay);
void delayMicroseconds(unsigned long);
uint32_t millis();
//IO functions
void pinMode(const pin_t, const uint8_t);
void digitalWrite(pin_t, uint8_t);
bool digitalRead(pin_t);
void analogWrite(pin_t, int);
uint16_t analogRead(pin_t);
// EEPROM
void eeprom_write_byte(unsigned char *pos, unsigned char value);
unsigned char eeprom_read_byte(unsigned char *pos);
void eeprom_read_block(void *__dst, const void *__src, size_t __n);
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
int32_t random(int32_t);
int32_t random(int32_t, int32_t);
void randomSeed(uint32_t);
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
int map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max);

View File

@@ -1,70 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include <pinmapping.h>
#include "../../../gcode/parser.h"
uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
// Get the digital pin for an analog index
pin_t analogInputToDigitalPin(const int8_t p) {
return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
}
// Return the index of a pin number
int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
return pin;
}
// Test whether the pin is valid
bool VALID_PIN(const pin_t p) {
return WITHIN(p, 0, NUM_DIGITAL_PINS);
}
// Get the analog index for a digital pin
int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
}
// Test whether the pin is PWM
bool PWM_PIN(const pin_t p) {
return false;
}
// Test whether the pin is interruptable
bool INTERRUPT_PIN(const pin_t p) {
return false;
}
// Get the pin number at the given index
pin_t GET_PIN_MAP_PIN(const int16_t ind) {
return ind;
}
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return parser.intval(code, dval);
}
#endif // __PLAT_LINUX__

View File

@@ -1,137 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
extern void setup();
extern void loop();
#include <thread>
#include <iostream>
#include <fstream>
#include "../../inc/MarlinConfig.h"
#include <stdio.h>
#include <stdarg.h>
#include "../shared/Delay.h"
#include "hardware/IOLoggerCSV.h"
#include "hardware/Heater.h"
#include "hardware/LinearAxis.h"
// simple stdout / stdin implementation for fake serial port
void write_serial_thread() {
for (;;) {
for (std::size_t i = usb_serial.transmit_buffer.available(); i > 0; i--) {
fputc(usb_serial.transmit_buffer.read(), stdout);
}
std::this_thread::yield();
}
}
void read_serial_thread() {
char buffer[255] = {};
for (;;) {
std::size_t len = _MIN(usb_serial.receive_buffer.free(), 254U);
if (fgets(buffer, len, stdin))
for (std::size_t i = 0; i < strlen(buffer); i++)
usb_serial.receive_buffer.write(buffer[i]);
std::this_thread::yield();
}
}
void simulation_loop() {
Heater hotend(HEATER_0_PIN, TEMP_0_PIN);
Heater bed(HEATER_BED_PIN, TEMP_BED_PIN);
LinearAxis x_axis(X_ENABLE_PIN, X_DIR_PIN, X_STEP_PIN, X_MIN_PIN, X_MAX_PIN);
LinearAxis y_axis(Y_ENABLE_PIN, Y_DIR_PIN, Y_STEP_PIN, Y_MIN_PIN, Y_MAX_PIN);
LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN);
LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC);
//#define GPIO_LOGGING // Full GPIO and Positional Logging
#ifdef GPIO_LOGGING
IOLoggerCSV logger("all_gpio_log.csv");
Gpio::attachLogger(&logger);
std::ofstream position_log;
position_log.open("axis_position_log.csv");
int32_t x,y,z;
#endif
for (;;) {
hotend.update();
bed.update();
x_axis.update();
y_axis.update();
z_axis.update();
extruder0.update();
#ifdef GPIO_LOGGING
if (x_axis.position != x || y_axis.position != y || z_axis.position != z) {
uint64_t update = MAX3(x_axis.last_update, y_axis.last_update, z_axis.last_update);
position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl;
position_log.flush();
x = x_axis.position;
y = y_axis.position;
z = z_axis.position;
}
// flush the logger
logger.flush();
#endif
std::this_thread::yield();
}
}
int main() {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
#if NUM_SERIAL > 0
MYSERIAL0.begin(BAUDRATE);
SERIAL_ECHOLNPGM("x86_64 Initialized");
SERIAL_FLUSHTX();
#endif
Clock::setFrequency(F_CPU);
Clock::setTimeMultiplier(1.0); // some testing at 10x
HAL_timer_init();
std::thread simulation (simulation_loop);
DELAY_US(10000);
setup();
for (;;) {
loop();
std::this_thread::yield();
}
simulation.join();
write_serial.join();
read_serial.join();
}
#endif // __PLAT_LINUX__

View File

@@ -1,54 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../core/macros.h"
#include "../../inc/MarlinConfigPre.h"
#if HAS_GRAPHICAL_LCD && ENABLED(SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == 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 SCK_PIN P0_07
//#define MISO_PIN P0_08
//#define MOSI_PIN P0_09
//#define SS_PIN P0_06
/** external */
#ifndef SCK_PIN
#define SCK_PIN 50
#endif
#ifndef MISO_PIN
#define MISO_PIN 51
#endif
#ifndef MOSI_PIN
#define MOSI_PIN 52
#endif
#ifndef SS_PIN
#define SS_PIN 53
#endif
#ifndef SDSS
#define SDSS SS_PIN
#endif

View File

@@ -1,73 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "hardware/Timer.h"
#include "../../inc/MarlinConfig.h"
#include "timers.h"
/**
* Use POSIX signals to attempt to emulate Interrupts
* This has many limitations and is not fit for the purpose
*/
HAL_STEP_TIMER_ISR();
HAL_TEMP_TIMER_ISR();
Timer timers[2];
void HAL_timer_init() {
timers[0].init(0, STEPPER_TIMER_RATE, TIMER0_IRQHandler);
timers[1].init(1, TEMP_TIMER_RATE, TIMER1_IRQHandler);
}
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timers[timer_num].start(frequency);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
timers[timer_num].enable();
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
timers[timer_num].disable();
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
return timers[timer_num].enabled();
}
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
timers[timer_num].setCompare(compare);
}
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return timers[timer_num].getCompare();
}
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
return timers[timer_num].getCount();
}
#endif // __PLAT_LINUX__

View File

@@ -1,87 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HAL timers for Linux X86_64
*/
#include <stdint.h>
// ------------------------
// Defines
// ------------------------
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#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(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
#define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler()
// PWM timer
#define HAL_PWM_TIMER
#define HAL_PWM_TIMER_ISR() extern "C" void TIMER3_IRQHandler()
#define HAL_PWM_TIMER_IRQn
void HAL_timer_init();
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare);
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_restrain(const uint8_t timer_num, const uint16_t interval_ticks) {
const hal_timer_t mincmp = HAL_timer_get_count(timer_num) + interval_ticks;
if (HAL_timer_get_compare(timer_num) < mincmp) HAL_timer_set_compare(timer_num, mincmp);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)

View File

@@ -1,36 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __PLAT_LINUX__
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
void watchdog_init() {}
void HAL_watchdog_refresh() {}
#endif
#endif // __PLAT_LINUX__

View File

@@ -1,327 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../core/macros.h"
#include "../../core/serial.h"
#include <stdarg.h>
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include "watchdog.h"
#include <debug_frmwrk.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
}
// Send character through UART with no interrupts
static void TX(char c) {
_DBC(c);
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
,UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Clear cause of reset to prevent entering smoothie bootstrap
HAL_clear_reset_source();
// Restart watchdog
#if ENABLED(USE_WATCHDOG)
//WDT_Restart(WDT);
watchdog_init();
#endif
// Reset controller
NVIC_SystemReset();
// Nothing below here is compiled because NVIC_SystemReset loops forever
for (;;) {
#if ENABLED(USE_WATCHDOG)
watchdog_init();
#endif
}
}
extern "C" {
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_IRQHandler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
}
#endif // TARGET_LPC1768

View File

@@ -1,85 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
#include "../../../gcode/parser.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
uint32_t HAL_adc_reading = 0;
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
}
extern "C" void u8g_MicroDelay() {
u8g_xMicroDelay(1);
}
extern "C" void u8g_10MicroDelay() {
u8g_xMicroDelay(10);
}
extern "C" 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;
}
// scan command line for 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;
}
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
void HAL_clear_reset_source(void) {
#if ENABLED(USE_WATCHDOG)
watchdog_clear_timeout_flag();
#endif
}
uint8_t HAL_get_reset_source(void) {
#if ENABLED(USE_WATCHDOG)
if (watchdog_timed_out()) return RST_WATCHDOG;
#endif
return RST_POWER_ON;
}
#endif // TARGET_LPC1768

View File

@@ -1,218 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HAL_LPC1768/HAL.h
* Hardware Abstraction Layer for NXP LPC1768
*/
#define CPU_32_BIT
void HAL_init();
#include <stdint.h>
#include <stdarg.h>
#include <algorithm>
extern "C" volatile uint32_t _millis;
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "timers.h"
#include "MarlinSerial.h"
#include <adc.h>
#include <pinmapping.h>
#include <CDCSerial.h>
//
// Default graphical display delays
//
#ifndef ST7920_DELAY_1
#define ST7920_DELAY_1 DELAY_NS(600)
#endif
#ifndef ST7920_DELAY_2
#define ST7920_DELAY_2 DELAY_NS(750)
#endif
#ifndef ST7920_DELAY_3
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
#if SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
#elif SERIAL_PORT == 0
#define MYSERIAL0 MSerial
#elif SERIAL_PORT == 1
#define MYSERIAL0 MSerial1
#elif SERIAL_PORT == 2
#define MYSERIAL0 MSerial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 MSerial3
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#elif SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 MSerial
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 MSerial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 MSerial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 MSerial3
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#ifdef DGUS_SERIAL_PORT
#if DGUS_SERIAL_PORT == SERIAL_PORT
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#elif DGUS_SERIAL_PORT == -1
#define DGUS_SERIAL UsbSerial
#elif DGUS_SERIAL_PORT == 0
#define DGUS_SERIAL MSerial
#elif DGUS_SERIAL_PORT == 1
#define DGUS_SERIAL MSerial1
#elif DGUS_SERIAL_PORT == 2
#define DGUS_SERIAL MSerial2
#elif DGUS_SERIAL_PORT == 3
#define DGUS_SERIAL MSerial3
#else
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
//
// Interrupts
//
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
#define ISRS_ENABLED() (!__get_PRIMASK())
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
//
// Utility functions
//
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int freeMemory();
#pragma GCC diagnostic pop
//
// ADC API
//
#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_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
using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
extern uint32_t HAL_adc_reading;
[[gnu::always_inline]] inline void HAL_start_adc(const pin_t pin) {
HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
}
[[gnu::always_inline]] inline uint16_t HAL_read_adc() {
return HAL_adc_reading;
}
#define HAL_adc_init()
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
#define HAL_START_ADC(pin) HAL_start_adc(pin)
#define HAL_READ_ADC() HAL_read_adc()
#define HAL_ADC_READY() (true)
// Test whether the pin is valid
constexpr bool VALID_PIN(const pin_t pin) {
return LPC176x::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 (LPC176x::pin_is_valid(pin) && LPC176x::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 LPC176x::pin_index(pin);
}
// Get the pin number at the given index
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
return LPC176x::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
#define HAL_IDLETASK 1
void HAL_idletask();
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);
/**
* set_pwm_frequency
* Set the frequency of the timer corresponding to the provided pin
* All Hardware PWM pins run at the same frequency and all
* Software PWM pins run at the same frequency
*/
void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
* Set the PWM duty cycle of the provided pin to the provided value
* Optionally allows inverting the duty cycle [default = false]
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
*/
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
// Reset source
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);

View File

@@ -1,240 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Software SPI functions originally from Arduino Sd2Card Library
* Copyright (c) 2009 by William Greiman
*/
/**
* For TARGET_LPC1768
*/
/**
* Hardware SPI and a 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_LPC1768
#include "../../inc/MarlinConfig.h"
#include <SPI.h>
// ------------------------
// Public functions
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
#include <SoftwareSPI.h>
// Software SPI
static uint8_t SPI_speed = 0;
static uint8_t spiTransfer(uint8_t b) {
return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN);
}
void spiBegin() {
swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN);
}
void spiInit(uint8_t spiRate) {
SPI_speed = swSpiInit(spiRate, SCK_PIN, 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
// Hardware SPI
#include <lpc17xx_pinsel.h>
#include <lpc17xx_ssp.h>
#include <lpc17xx_clkpwr.h>
// decide which HW SPI device to use
#ifndef LPC_HW_SPI_DEV
#if (SCK_PIN == P0_07 && MISO_PIN == P0_08 && MOSI_PIN == P0_09)
#define LPC_HW_SPI_DEV 1
#else
#if (SCK_PIN == P0_15 && MISO_PIN == P0_17 && MOSI_PIN == P0_18)
#define LPC_HW_SPI_DEV 0
#else
#error "Invalid pins selected for hardware SPI"
#endif
#endif
#endif
#if (LPC_HW_SPI_DEV == 0)
#define LPC_SSPn LPC_SSP0
#else
#define LPC_SSPn LPC_SSP1
#endif
void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
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_PIN);
PinCfg.Portnum = LPC176x::pin_port(SCK_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(SCK_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN);
PinCfg.Portnum = LPC176x::pin_port(MISO_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_INPUT(MISO_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN);
PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(MOSI_PIN);
// divide PCLK by 2 for SSP0
CLKPWR_SetPCLKDiv(LPC_HW_SPI_DEV == 0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
spiInit(0);
SSP_Cmd(LPC_SSPn, ENABLE); // start SSP running
}
void spiInit(uint8_t spiRate) {
// table to convert Marlin spiRates (0-5 plus default) into bit rates
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
// setup for SPI mode
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 = Marlin_speed[_MIN(spiRate, 6)]; // put in the specified bit rate
HW_SPI_init.Mode |= SSP_CR1_SSP_EN;
SSP_Init(LPC_SSPn, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
}
static uint8_t doio(uint8_t b) {
/* send and receive a single byte */
SSP_SendData(LPC_SSPn, b & 0x00FF);
while (SSP_GetStatus(LPC_SSPn, SSP_STAT_BUSY)); // wait for it to finish
return SSP_ReceiveData(LPC_SSPn) & 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);
}
static 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: to be implemented
}
#endif // ENABLED(LPC_SOFTWARE_SPI)
void SPIClass::begin() { spiBegin(); }
void SPIClass::beginTransaction(SPISettings cfg) {
uint8_t spiRate;
switch (cfg.spiRate()) {
case 8000000: spiRate = 0; break;
case 4000000: spiRate = 1; break;
case 2000000: spiRate = 2; break;
case 1000000: spiRate = 3; break;
case 500000: spiRate = 4; break;
case 250000: spiRate = 5; break;
case 125000: spiRate = 6; break;
default: spiRate = 2; break;
}
spiInit(spiRate);
}
uint8_t SPIClass::transfer(const uint8_t B) { return spiTransfer(B); }
uint16_t SPIClass::transfer16(const uint16_t data) {
return (transfer((data >> 8) & 0xFF) << 8)
| (transfer(data & 0xFF) & 0xFF);
}
SPIClass SPI;
#endif // TARGET_LPC1768

View File

@@ -1,56 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
#include "MarlinSerial.h"
#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0)
MarlinSerial MSerial(LPC_UART0);
extern "C" void UART0_IRQHandler() {
MSerial.IRQHandler();
}
#endif
#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() {
MSerial1.IRQHandler();
}
#endif
#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
MarlinSerial MSerial2(LPC_UART2);
extern "C" void UART2_IRQHandler() {
MSerial2.IRQHandler();
}
#endif
#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
MarlinSerial MSerial3(LPC_UART3);
extern "C" void UART3_IRQHandler() {
MSerial3.IRQHandler();
}
#endif
#endif // TARGET_LPC1768

View File

@@ -1,67 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <HardwareSerial.h>
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
#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 MarlinSerial : public HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE> {
public:
MarlinSerial(LPC_UART_TypeDef *UARTx) :
HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE>(UARTx)
#if ENABLED(EMERGENCY_PARSER)
, emergency_state(EmergencyParser::State::EP_RESET)
#endif
{
}
void end() {}
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override {
emergency_parser.update(emergency_state, c);
return true; // do not discard character
}
EmergencyParser::State emergency_state;
#endif
};
extern MarlinSerial MSerial;
extern MarlinSerial MSerial1;
extern MarlinSerial MSerial2;
extern MarlinSerial MSerial3;

View File

@@ -1,71 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* 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 <Servo.h>
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
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
detach();
#endif
}
}
};
#define HAL_SERVO_LIB libServo

View File

@@ -1,26 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../shared/eeprom_api.h"
#define FLASH_EEPROM_EMULATION

View File

@@ -1,128 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
/**
* 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 "levelling" 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"
#if ENABLED(FLASH_EEPROM_EMULATION)
#include "eeprom_api.h"
extern "C" {
#include <lpc17xx_iap.h>
}
#define SECTOR_START(sector) ((sector < 16) ? (sector * 0x1000) : ((sector - 14) * 0x8000))
#define EEPROM_SECTOR 29
#define EEPROM_SIZE (4096)
#define SECTOR_SIZE (32768)
#define EEPROM_SLOTS (SECTOR_SIZE/EEPROM_SIZE)
#define EEPROM_ERASE (0xFF)
#define SLOT_ADDRESS(sector, slot) (((uint8_t *)SECTOR_START(sector)) + slot * EEPROM_SIZE)
static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;
static int current_slot = 0;
bool PersistentStore::access_start() {
uint32_t first_nblank_loc, first_nblank_val;
IAP_STATUS_CODE status;
// discover which slot we are currently using.
__disable_irq();
status = BlankCheckSector(EEPROM_SECTOR, EEPROM_SECTOR, &first_nblank_loc, &first_nblank_val);
__enable_irq();
if (status == CMD_SUCCESS) {
// sector is blank so nothing stored yet
for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE;
current_slot = EEPROM_SLOTS;
}
else {
// current slot is the first non blank one
current_slot = first_nblank_loc / EEPROM_SIZE;
uint8_t *eeprom_data = SLOT_ADDRESS(EEPROM_SECTOR, current_slot);
// load current settings
for (int i = 0; i < EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i];
}
eeprom_dirty = false;
return true;
}
bool PersistentStore::access_finish() {
if (eeprom_dirty) {
IAP_STATUS_CODE status;
if (--current_slot < 0) {
// all slots have been used, erase everything and start again
__disable_irq();
status = EraseSector(EEPROM_SECTOR, EEPROM_SECTOR);
__enable_irq();
current_slot = EEPROM_SLOTS - 1;
}
__disable_irq();
status = CopyRAM2Flash(SLOT_ADDRESS(EEPROM_SECTOR, current_slot), ram_eeprom, IAP_WRITE_4096);
__enable_irq();
if (status != CMD_SUCCESS) return false;
eeprom_dirty = false;
}
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
for (size_t i = 0; i < size; i++) ram_eeprom[pos + i] = value[i];
eeprom_dirty = true;
crc16(crc, value, size);
pos += 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*/) {
const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
crc16(crc, buff, size);
pos += size;
return false; // return true for any error
}
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
#endif // FLASH_EEPROM_EMULATION
#endif // TARGET_LPC1768

View File

@@ -1,179 +0,0 @@
/**
* 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
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.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 <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDCARD_EEPROM_EMULATION)
#include "eeprom_api.h"
#include <chanfs/diskio.h>
#include <chanfs/ff.h>
extern uint32_t MSC_Aquire_Lock();
extern uint32_t MSC_Release_Lock();
FATFS fat_fs;
FIL eeprom_file;
bool eeprom_file_open = false;
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;
MSC_Aquire_Lock();
if (f_mount(&fat_fs, "", 1)) {
MSC_Release_Lock();
return false;
}
FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
if (res) MSC_Release_Lock();
if (res == FR_OK) {
UINT bytes_written;
FSIZE_t file_size = f_size(&eeprom_file);
f_lseek(&eeprom_file, file_size);
while (file_size < capacity() && res == FR_OK) {
res = f_write(&eeprom_file, &eeprom_erase_value, 1, &bytes_written);
file_size++;
}
}
if (res == FR_OK) {
f_lseek(&eeprom_file, 0);
f_sync(&eeprom_file);
eeprom_file_open = true;
}
return res == FR_OK;
}
bool PersistentStore::access_finish() {
f_close(&eeprom_file);
f_unmount("");
MSC_Release_Lock();
eeprom_file_open = false;
return true;
}
// This extra chit-chat goes away soon, but is helpful for now
// to see errors that are happening in read_data / write_data
static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
PGM_P const rw_str = write ? PSTR("write") : PSTR("read");
SERIAL_CHAR(' ');
serialprintPGM(rw_str);
SERIAL_ECHOPAIR("_data(", pos);
SERIAL_ECHOPAIR(",", (int)value);
SERIAL_ECHOPAIR(",", (int)size);
SERIAL_ECHOLNPGM(", ...)");
if (total) {
SERIAL_ECHOPGM(" f_");
serialprintPGM(rw_str);
SERIAL_ECHOPAIR("()=", (int)s);
SERIAL_ECHOPAIR("\n size=", size);
SERIAL_ECHOPGM("\n bytes_");
serialprintPGM(write ? PSTR("written=") : PSTR("read="));
SERIAL_ECHOLN(total);
}
else
SERIAL_ECHOLNPAIR(" f_lseek()=", (int)s);
}
// File function return codes for type FRESULT. This goes away soon, but
// is helpful right now to see any errors in read_data and write_data.
//
// typedef enum {
// FR_OK = 0, /* (0) Succeeded */
// FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
// FR_INT_ERR, /* (2) Assertion failed */
// FR_NOT_READY, /* (3) The physical drive cannot work */
// FR_NO_FILE, /* (4) Could not find the file */
// FR_NO_PATH, /* (5) Could not find the path */
// FR_INVALID_NAME, /* (6) The path name format is invalid */
// FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
// FR_EXIST, /* (8) Access denied due to prohibited access */
// FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
// FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
// FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
// FR_NOT_ENABLED, /* (12) The volume has no work area */
// FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
// FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
// FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
// FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
// FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
// FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
// FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
// } FRESULT;
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
if (!eeprom_file_open) return true;
FRESULT s;
UINT bytes_written = 0;
s = f_lseek(&eeprom_file, pos);
if (s) {
debug_rw(true, pos, value, size, s);
return s;
}
s = f_write(&eeprom_file, (void*)value, size, &bytes_written);
if (s) {
debug_rw(true, pos, value, size, s, bytes_written);
return s;
}
crc16(crc, value, size);
pos += size;
return bytes_written != size; // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
if (!eeprom_file_open) return true;
UINT bytes_read = 0;
FRESULT s;
s = f_lseek(&eeprom_file, pos);
if (s) {
debug_rw(false, pos, value, size, s);
return true;
}
if (writing) {
s = f_read(&eeprom_file, (void*)value, size, &bytes_read);
crc16(crc, value, size);
}
else {
uint8_t temp[size];
s = f_read(&eeprom_file, (void*)temp, size, &bytes_read);
crc16(crc, temp, size);
}
if (s) {
debug_rw(false, pos, value, size, s, bytes_read);
return true;
}
pos += size;
return bytes_read != size; // return true for any error
}
size_t PersistentStore::capacity() { return 4096; } // 4KiB of Emulated EEPROM
#endif // SDCARD_EEPROM_EMULATION
#endif // TARGET_LPC1768

View File

@@ -1,40 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
#include <pwm.h>
void set_pwm_frequency(const pin_t pin, int f_desired) {
LPC176x::pwm_set_frequency(pin, f_desired);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
}
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
#endif // TARGET_LPC1768

View File

@@ -1,26 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#if USE_FALLBACK_EEPROM && NONE(SDCARD_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
#define FLASH_EEPROM_EMULATION
#endif

View File

@@ -1,253 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#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 < 2002
#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 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3
#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.");
/**
* Test LPC176x-specific configuration values for errors at compile-time.
*/
//#if ENABLED(SPINDLE_LASER_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 ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && 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 |
*/
#if (defined(SERIAL_PORT) && SERIAL_PORT == 0) || (defined(SERIAL_PORT_2) && SERIAL_PORT_2 == 0) || (defined(DGUS_SERIAL_PORT) && DGUS_SERIAL_PORT == 0)
#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 ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
#error "Serial port pins (0) conflict with MK2 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 SERIAL_PORT == 1 || SERIAL_PORT_2 == 1 || DGUS_SERIAL_PORT == 1
#define IS_TX1(P) (P == P0_15)
#define IS_RX1(P) (P == P0_16)
#if IS_TX1(TMC_SW_SCK)
#error "Serial port pins (1) conflict with other pins!"
#elif HAS_SPI_LCD
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
#elif IS_TX1(SCK_PIN) || IS_TX1(LCD_PINS_D4) || IS_TX1(DOGLCD_SCK) || IS_TX1(LCD_RESET_PIN) || IS_TX1(LCD_PINS_RS) || IS_TX1(SHIFT_CLK) \
|| IS_RX1(LCD_SDSS) || IS_RX1(LCD_PINS_RS) || IS_RX1(MISO_PIN) || IS_RX1(DOGLCD_A0) || IS_RX1(SS_PIN) || IS_RX1(LCD_SDSS) || IS_RX1(DOGLCD_CS) || IS_RX1(LCD_RESET_PIN) || IS_RX1(LCD_BACKLIGHT_PIN)
#error "Serial port pins (1) conflict with LCD pins!"
#endif
#endif
#undef IS_TX1
#undef IS_RX1
#endif
#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2 || DGUS_SERIAL_PORT == 2
#define IS_TX2(P) (P == P0_10)
#define IS_RX2(P) (P == P0_11)
#if IS_TX2(X2_ENABLE_PIN) || IS_RX2(X2_DIR_PIN) || IS_RX2(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) || IS_RX2(Y2_DIR_PIN) || IS_RX2(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) || IS_RX2(Z2_DIR_PIN) || IS_RX2(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) || IS_RX2(Z3_DIR_PIN) || IS_RX2(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) || IS_RX2(Z4_DIR_PIN) || IS_RX2(Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN))
#error "Serial port pins (2) conflict with Z4 pins!"
#elif IS_RX2(X_DIR_PIN) || IS_RX2(Y_DIR_PIN)
#error "Serial port pins (2) conflict with other pins!"
#elif Y_HOME_DIR < 0 && IS_TX2(Y_STOP_PIN)
#error "Serial port pins (2) conflict with Y endstop pin!"
#elif HAS_CUSTOM_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN)
#error "Serial port pins (2) conflict with probe pin!"
#elif IS_TX2(X_ENABLE_PIN) || IS_RX2(X_DIR_PIN) || IS_TX2(Y_ENABLE_PIN) || IS_RX2(Y_DIR_PIN)
#error "Serial port pins (2) conflict with X/Y stepper pins!"
#elif EXTRUDERS > 1 && (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 && (IS_RX2(E0_DIR_PIN) || IS_RX2(E0_STEP_PIN))
#error "Serial port pins (2) conflict with E stepper pins!"
#endif
#undef IS_TX2
#undef IS_RX2
#endif
#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3 || DGUS_SERIAL_PORT == 3
#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 EXTRUDERS > 1 && (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
//
// Flag any i2c pin conflicts
//
#if ANY(DIGIPOT_I2C, DIGIPOT_MCP4018, DAC_STEPPER_CURRENT, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
#define USEDI2CDEV_M 1 // <Arduino>/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(SS_PIN)
#error "SCL0 overlaps with 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 EXTRUDERS > 1 && (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 HAS_CUSTOM_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 EXTRUDERS > 1 && PIN_IS_SDA2(E1_ENABLE)
#error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals."
#elif EXTRUDERS > 1 && 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

View File

@@ -1,48 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../shared/HAL_SPI.h"
#include <stdint.h>
#define MSBFIRST 1
#define SPI_MODE3 0
class SPISettings {
public:
SPISettings(uint32_t speed, int, int) : spi_speed(speed) {};
uint32_t spiRate() { return spi_speed; }
private:
uint32_t spi_speed;
};
class SPIClass {
public:
void begin();
void beginTransaction(SPISettings);
void endTransaction() {};
uint8_t transfer(uint8_t data);
uint16_t transfer16(uint16_t data);
};
extern SPIClass SPI;

View File

@@ -1,162 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include <usb/usb.h>
#include <usb/usbcfg.h>
#include <usb/usbhw.h>
#include <usb/usbcore.h>
#include <usb/cdc.h>
#include <usb/cdcuser.h>
#include <usb/mscuser.h>
#include <CDCSerial.h>
#include <usb/mscuser.h>
extern "C" {
#include <debug_frmwrk.h>
}
#include "../../sd/cardreader.h"
#include "../../inc/MarlinConfig.h"
#include "../../core/millis_t.h"
#include "HAL.h"
#include "timers.h"
extern uint32_t MSC_SD_Init(uint8_t pdrv);
extern "C" int isLPC1769();
extern "C" void disk_timerproc();
void SysTick_Callback() { disk_timerproc(); }
void HAL_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
LOOP_L_N(i, 6) {
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
//debug_frmwrk_init();
//_DBG("\n\nDebug running\n");
// Initialize the SD card chip select pins as soon as possible
#if PIN_EXISTS(SS)
OUT_WRITE(SS_PIN, HIGH);
#endif
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SS_PIN
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
#endif
#ifdef LPC1768_ENABLE_CLKOUT_12M
/**
* CLKOUTCFG register
* bit 8 (CLKOUT_EN) = enables CLKOUT signal. Disabled for now to prevent glitch when enabling GPIO.
* bits 7:4 (CLKOUTDIV) = set to 0 for divider setting of /1
* bits 3:0 (CLKOUTSEL) = set to 1 to select main crystal oscillator as CLKOUT source
*/
LPC_SC->CLKOUTCFG = (0<<8)|(0<<4)|(1<<0);
// set P1.27 pin to function 01 (CLKOUT)
PINSEL_CFG_Type PinCfg;
PinCfg.Portnum = 1;
PinCfg.Pinnum = 27;
PinCfg.Funcnum = 1; // function 01 (CLKOUT)
PinCfg.OpenDrain = 0; // not open drain
PinCfg.Pinmode = 2; // no pull-up/pull-down
PINSEL_ConfigPin(&PinCfg);
// now set CLKOUT_EN bit
LPC_SC->CLKOUTCFG |= (1<<8);
#endif
USB_Init(); // USB Initialization
USB_Connect(FALSE); // USB clear connection
delay(1000); // Give OS time to notice
USB_Connect(TRUE);
#if !BOTH(SHARED_SD_CARD, INIT_SDCARD_ON_BOOT) && DISABLED(NO_SD_HOST_DRIVE)
MSC_SD_Init(0); // Enable USB SD card access
#endif
const millis_t usb_timeout = millis() + 2000;
while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
delay(50);
HAL_idletask();
#if PIN_EXISTS(LED)
TOGGLE(LED_PIN); // Flash quickly during USB initialization
#endif
}
HAL_timer_init();
}
// HAL idle task
void HAL_idletask() {
#if ENABLED(SHARED_SD_CARD)
// 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())
MSC_Aquire_Lock();
else
MSC_Release_Lock();
#endif
// Perform USB stack housekeeping
MSC_RunDeferredCommands();
}
#endif // TARGET_LPC1768

View File

@@ -1,54 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../core/macros.h"
#if ENABLED(SDSUPPORT) && HAS_GRAPHICAL_LCD && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == 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 SCK_PIN P0_07
//#define MISO_PIN P0_08
//#define MOSI_PIN P0_09
//#define SS_PIN P0_06
/** external */
#ifndef SCK_PIN
#define SCK_PIN P0_15
#endif
#ifndef MISO_PIN
#define MISO_PIN P0_17
#endif
#ifndef MOSI_PIN
#define MOSI_PIN P0_18
#endif
#ifndef SS_PIN
#define SS_PIN P1_23
#endif
#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h
#undef SDSS
#define SDSS SS_PIN
#endif

View File

@@ -1,66 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
/**
* Description:
*
* Timers for LPC1768
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#include "timers.h"
void HAL_timer_init() {
SBI(LPC_SC->PCONP, SBIT_TIMER0); // Power ON Timer 0
LPC_TIM0->PR = (HAL_TIMER_RATE) / (STEPPER_TIMER_RATE) - 1; // Use prescaler to set frequency if needed
SBI(LPC_SC->PCONP, SBIT_TIMER1); // Power ON Timer 1
LPC_TIM1->PR = (HAL_TIMER_RATE) / 1000000 - 1;
}
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
case 0:
LPC_TIM0->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM0->MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency
LPC_TIM0->TCR = _BV(SBIT_CNTEN); // Counter Enable
NVIC_SetPriority(TIMER0_IRQn, NVIC_EncodePriority(0, 1, 0));
NVIC_EnableIRQ(TIMER0_IRQn);
break;
case 1:
LPC_TIM1->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM1->MR0 = uint32_t(TEMP_TIMER_RATE) / frequency;
LPC_TIM1->TCR = _BV(SBIT_CNTEN); // Counter Enable
NVIC_SetPriority(TIMER1_IRQn, NVIC_EncodePriority(0, 2, 0));
NVIC_EnableIRQ(TIMER1_IRQn);
break;
default: break;
}
}
#endif // TARGET_LPC1768

View File

@@ -1,162 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
*
* HAL For LPC1768
*/
#include <stdint.h>
#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(LPC_TIM, 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) / 4) // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define PWM_TIMER_NUM 3 // Timer Index for PWM
#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(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM)
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM)
// Timer references by index
#define STEP_TIMER _HAL_TIMER(STEP_TIMER_NUM)
#define TEMP_TIMER _HAL_TIMER(TEMP_TIMER_NUM)
// ------------------------
// 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 0: STEP_TIMER->MR0 = compare; break; // Stepper Timer Match Register 0
case 1: TEMP_TIMER->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 0: return STEP_TIMER->MR0; // Stepper Timer Match Register 0
case 1: return TEMP_TIMER->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 0: return STEP_TIMER->TC; // Stepper Timer Count
case 1: return TEMP_TIMER->TC; // Temp Timer Count
}
return 0;
}
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler
case 1: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler
}
}
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
case 0: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler
case 1: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler
}
// 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();
}
// This function is missing from CMSIS
FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[((uint32_t)IRQn) >> 5] & (1 << ((uint32_t)IRQn) & 0x1F)) != 0;
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
switch (timer_num) {
case 0: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not
case 1: return NVIC_GetEnableIRQ(TIMER1_IRQn); // 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 0: SBI(STEP_TIMER->IR, SBIT_CNTEN); break;
case 1: SBI(TEMP_TIMER->IR, SBIT_CNTEN); break;
}
}
#define HAL_timer_isr_epilogue(TIMER_NUM)

View File

@@ -1,37 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
EmergencyParser::State emergency_state;
bool CDC_RecvCallback(const char buffer) {
emergency_parser.update(emergency_state, buffer);
return true;
}
#endif // EMERGENCY_PARSER
#endif // TARGET_LPC1768

View File

@@ -1,71 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include <lpc17xx_wdt.h>
#include "watchdog.h"
void 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();
// Configure WDT to only trigger an interrupt
// Initialize WDT with the given parameters
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY);
// 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
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
#endif
WDT_Start(WDT_TIMEOUT);
}
void HAL_watchdog_refresh() {
WDT_Feed();
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
TOGGLE(LED_PIN); // heartbeat indicator
#endif
}
// Timeout state
bool watchdog_timed_out() { return TEST(WDT_ReadTimeOutFlag(), 0); }
void watchdog_clear_timeout_flag() { WDT_ClrTimeOutFlag(); }
#endif // USE_WATCHDOG
#endif // TARGET_LPC1768

View File

@@ -1,527 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#include <Adafruit_ZeroDMA.h>
#include <wiring_private.h>
// ------------------------
// Local defines
// ------------------------
#if HAS_TEMP_ADC_0
#define GET_TEMP_0_ADC() PIN_TO_ADC(TEMP_0_PIN)
#else
#define GET_TEMP_0_ADC() -1
#endif
#if HAS_TEMP_ADC_1
#define GET_TEMP_1_ADC() PIN_TO_ADC(TEMP_1_PIN)
#else
#define GET_TEMP_1_ADC() -1
#endif
#if HAS_TEMP_ADC_2
#define GET_TEMP_2_ADC() PIN_TO_ADC(TEMP_2_PIN)
#else
#define GET_TEMP_2_ADC() -1
#endif
#if HAS_TEMP_ADC_3
#define GET_TEMP_3_ADC() PIN_TO_ADC(TEMP_3_PIN)
#else
#define GET_TEMP_3_ADC() -1
#endif
#if HAS_TEMP_ADC_4
#define GET_TEMP_4_ADC() PIN_TO_ADC(TEMP_4_PIN)
#else
#define GET_TEMP_4_ADC() -1
#endif
#if HAS_TEMP_ADC_5
#define GET_TEMP_5_ADC() PIN_TO_ADC(TEMP_5_PIN)
#else
#define GET_TEMP_5_ADC() -1
#endif
#if HAS_TEMP_ADC_6
#define GET_TEMP_6_ADC() PIN_TO_ADC(TEMP_6_PIN)
#else
#define GET_TEMP_6_ADC() -1
#endif
#if HAS_TEMP_ADC_7
#define GET_TEMP_7_ADC() PIN_TO_ADC(TEMP_7_PIN)
#else
#define GET_TEMP_7_ADC() -1
#endif
#if HAS_TEMP_PROBE
#define GET_PROBE_ADC() PIN_TO_ADC(TEMP_PROBE_PIN)
#else
#define GET_PROBE_ADC() -1
#endif
#if HAS_TEMP_ADC_BED
#define GET_BED_ADC() PIN_TO_ADC(TEMP_BED_PIN)
#else
#define GET_BED_ADC() -1
#endif
#if HAS_TEMP_ADC_CHAMBER
#define GET_CHAMBER_ADC() PIN_TO_ADC(TEMP_CHAMBER_PIN)
#else
#define GET_CHAMBER_ADC() -1
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
#define GET_FILAMENT_WIDTH_ADC() PIN_TO_ADC(FILWIDTH_PIN)
#else
#define GET_FILAMENT_WIDTH_ADC() -1
#endif
#if HAS_ADC_BUTTONS
#define GET_BUTTONS_ADC() PIN_TO_ADC(ADC_KEYPAD_PIN)
#else
#define GET_BUTTONS_ADC() -1
#endif
#define IS_ADC_REQUIRED(n) ( \
GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \
|| GET_TEMP_4_ADC() == n || GET_TEMP_5_ADC() == n || GET_TEMP_6_ADC() == n || GET_TEMP_7_ADC() == n \
|| GET_PROBE_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_BUTTONS_ADC() == n \
)
#define ADC0_IS_REQUIRED IS_ADC_REQUIRED(0)
#define ADC1_IS_REQUIRED IS_ADC_REQUIRED(1)
#define ADC_IS_REQUIRED (ADC0_IS_REQUIRED || ADC1_IS_REQUIRED)
#if ADC0_IS_REQUIRED
#define FIRST_ADC 0
#else
#define FIRST_ADC 1
#endif
#if ADC1_IS_REQUIRED
#define LAST_ADC 1
#else
#define LAST_ADC 0
#endif
#define DMA_IS_REQUIRED ADC_IS_REQUIRED
// ------------------------
// Types
// ------------------------
#if DMA_IS_REQUIRED
// Struct must be 32 bits aligned because of DMA accesses but fields needs to be 8 bits packed
typedef struct __attribute__((aligned(4), packed)) {
ADC_INPUTCTRL_Type INPUTCTRL;
} HAL_DMA_DAC_Registers; // DMA transfered registers
#endif
// ------------------------
// Private Variables
// ------------------------
uint16_t HAL_adc_result;
#if ADC_IS_REQUIRED
// Pins used by ADC inputs. Order must be ADC0 inputs first then ADC1
const uint8_t adc_pins[] = {
// ADC0 pins
#if GET_TEMP_0_ADC() == 0
TEMP_0_PIN,
#endif
#if GET_TEMP_1_ADC() == 0
TEMP_1_PIN,
#endif
#if GET_TEMP_2_ADC() == 0
TEMP_2_PIN,
#endif
#if GET_TEMP_3_ADC() == 0
TEMP_3_PIN,
#endif
#if GET_TEMP_4_ADC() == 0
TEMP_4_PIN,
#endif
#if GET_TEMP_5_ADC() == 0
TEMP_5_PIN,
#endif
#if GET_TEMP_6_ADC() == 0
TEMP_6_PIN,
#endif
#if GET_TEMP_7_ADC() == 0
TEMP_7_PIN,
#endif
#if GET_PROBE_ADC() == 0
TEMP_PROBE_PIN,
#endif
#if GET_BED_ADC() == 0
TEMP_BED_PIN,
#endif
#if GET_CHAMBER_ADC() == 0
TEMP_CHAMBER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
#if GET_BUTTONS_ADC() == 0
ADC_KEYPAD_PIN,
#endif
// ADC1 pins
#if GET_TEMP_0_ADC() == 1
TEMP_0_PIN,
#endif
#if GET_TEMP_1_ADC() == 1
TEMP_1_PIN,
#endif
#if GET_TEMP_2_ADC() == 1
TEMP_2_PIN,
#endif
#if GET_TEMP_3_ADC() == 1
TEMP_3_PIN,
#endif
#if GET_TEMP_4_ADC() == 1
TEMP_4_PIN,
#endif
#if GET_TEMP_5_ADC() == 1
TEMP_5_PIN,
#endif
#if GET_TEMP_6_ADC() == 1
TEMP_6_PIN,
#endif
#if GET_TEMP_7_ADC() == 1
TEMP_7_PIN,
#endif
#if GET_PROBE_ADC() == 1
TEMP_PROBE_PIN,
#endif
#if GET_BED_ADC() == 1
TEMP_BED_PIN,
#endif
#if GET_CHAMBER_ADC() == 1
TEMP_CHAMBER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
#if GET_BUTTONS_ADC() == 1
ADC_KEYPAD_PIN,
#endif
};
uint16_t HAL_adc_results[COUNT(adc_pins)];
#if ADC0_IS_REQUIRED
Adafruit_ZeroDMA adc0DMAProgram,
adc0DMARead;
const HAL_DMA_DAC_Registers adc0_dma_regs_list[] = {
#if GET_TEMP_0_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_0_PIN) },
#endif
#if GET_TEMP_1_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_1_PIN) },
#endif
#if GET_TEMP_2_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_2_PIN) },
#endif
#if GET_TEMP_3_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_3_PIN) },
#endif
#if GET_TEMP_4_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_4_PIN) },
#endif
#if GET_TEMP_5_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_5_PIN) },
#endif
#if GET_TEMP_6_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_6_PIN) },
#endif
#if GET_TEMP_7_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
#endif
#if GET_PROBE_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_BED_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
#endif
#if GET_CHAMBER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#if GET_BUTTONS_ADC() == 0
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
#endif
};
#define ADC0_AINCOUNT COUNT(adc0_dma_regs_list)
#endif // ADC0_IS_REQUIRED
#if ADC1_IS_REQUIRED
Adafruit_ZeroDMA adc1DMAProgram,
adc1DMARead;
const HAL_DMA_DAC_Registers adc1_dma_regs_list[] = {
#if GET_TEMP_0_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_0_PIN) },
#endif
#if GET_TEMP_1_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_1_PIN) },
#endif
#if GET_TEMP_2_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_2_PIN) },
#endif
#if GET_TEMP_3_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_3_PIN) },
#endif
#if GET_TEMP_4_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_4_PIN) },
#endif
#if GET_TEMP_5_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_5_PIN) },
#endif
#if GET_TEMP_6_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_6_PIN) },
#endif
#if GET_TEMP_7_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
#endif
#if GET_PROBE_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
#endif
#if GET_BED_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
#endif
#if GET_CHAMBER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#if GET_BUTTONS_ADC() == 1
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
#endif
};
#define ADC1_AINCOUNT COUNT(adc1_dma_regs_list)
#endif // ADC1_IS_REQUIRED
#endif // ADC_IS_REQUIRED
// ------------------------
// Private functions
// ------------------------
#if DMA_IS_REQUIRED
void dma_init() {
DmacDescriptor *descriptor;
#if ADC0_IS_REQUIRED
adc0DMAProgram.setTrigger(ADC0_DMAC_ID_SEQ);
adc0DMAProgram.setAction(DMA_TRIGGER_ACTON_BEAT);
adc0DMAProgram.loop(true);
if (adc0DMAProgram.allocate() == DMA_STATUS_OK) {
descriptor = adc0DMAProgram.addDescriptor(
(void *)adc0_dma_regs_list, // SRC
(void *)&ADC0->DSEQDATA.reg, // DEST
sizeof(adc0_dma_regs_list) / 4, // CNT
DMA_BEAT_SIZE_WORD,
true, // SRCINC
false, // DSTINC
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
if (descriptor != nullptr)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc0DMAProgram.startJob();
}
adc0DMARead.setTrigger(ADC0_DMAC_ID_RESRDY);
adc0DMARead.setAction(DMA_TRIGGER_ACTON_BEAT);
adc0DMARead.loop(true);
if (adc0DMARead.allocate() == DMA_STATUS_OK) {
adc0DMARead.addDescriptor(
(void *)&ADC0->RESULT.reg, // SRC
&HAL_adc_results, // DEST
ADC0_AINCOUNT, // CNT
DMA_BEAT_SIZE_HWORD,
false, // SRCINC
true, // DSTINC
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_DST // STEPSEL
);
adc0DMARead.startJob();
}
#endif
#if ADC1_IS_REQUIRED
adc1DMAProgram.setTrigger(ADC1_DMAC_ID_SEQ);
adc1DMAProgram.setAction(DMA_TRIGGER_ACTON_BEAT);
adc1DMAProgram.loop(true);
if (adc1DMAProgram.allocate() == DMA_STATUS_OK) {
descriptor = adc1DMAProgram.addDescriptor(
(void *)adc1_dma_regs_list, // SRC
(void *)&ADC1->DSEQDATA.reg, // DEST
sizeof(adc1_dma_regs_list) / 4, // CNT
DMA_BEAT_SIZE_WORD,
true, // SRCINC
false, // DSTINC
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
if (descriptor != nullptr)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc1DMAProgram.startJob();
}
adc1DMARead.setTrigger(ADC1_DMAC_ID_RESRDY);
adc1DMARead.setAction(DMA_TRIGGER_ACTON_BEAT);
adc1DMARead.loop(true);
if (adc1DMARead.allocate() == DMA_STATUS_OK) {
adc1DMARead.addDescriptor(
(void *)&ADC1->RESULT.reg, // SRC
&HAL_adc_results[ADC0_AINCOUNT], // DEST
ADC1_AINCOUNT, // CNT
DMA_BEAT_SIZE_HWORD,
false, // SRCINC
true, // DSTINC
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_DST // STEPSEL
);
adc1DMARead.startJob();
}
#endif
DMAC->PRICTRL0.bit.RRLVLEN0 = true; // Activate round robin for DMA channels required by ADCs
}
#endif // DMA_IS_REQUIRED
// ------------------------
// Public functions
// ------------------------
// HAL initialization task
void HAL_init() {
#if DMA_IS_REQUIRED
dma_init();
#endif
#if ENABLED(SDSUPPORT)
#if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)
SET_INPUT_PULLUP(SD_DETECT_PIN);
#endif
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
}
// HAL idle task
/*
void HAL_idletask() {
}
*/
void HAL_clear_reset_source() { }
#pragma push_macro("WDT")
#undef WDT // Required to be able to use '.bit.WDT'. Compiler wrongly replace struct field with WDT define
uint8_t HAL_get_reset_source() {
RSTC_RCAUSE_Type resetCause;
resetCause.reg = REG_RSTC_RCAUSE;
if (resetCause.bit.POR) return RST_POWER_ON;
else if (resetCause.bit.EXT) return RST_EXTERNAL;
else if (resetCause.bit.BODCORE || resetCause.bit.BODVDD) return RST_BROWN_OUT;
else if (resetCause.bit.WDT) return RST_WATCHDOG;
else if (resetCause.bit.SYST || resetCause.bit.NVM) return RST_SOFTWARE;
else if (resetCause.bit.BACKUP) return RST_BACKUP;
return 0;
}
#pragma pop_macro("WDT")
extern "C" {
void * _sbrk(int incr);
extern unsigned int __bss_end__; // end of bss section
}
// Return free memory between end of heap (or end bss) and whatever is current
int freeMemory() {
int free_memory, heap_end = (int)_sbrk(0);
return (int)&free_memory - (heap_end ?: (int)&__bss_end__);
}
// ------------------------
// ADC
// ------------------------
void HAL_adc_init() {
#if ADC_IS_REQUIRED
memset(HAL_adc_results, 0xFF, sizeof(HAL_adc_results)); // Fill result with invalid values
LOOP_L_N(pi, COUNT(adc_pins))
pinPeripheral(adc_pins[pi], PIO_ANALOG);
LOOP_S_LE_N(ai, FIRST_ADC, LAST_ADC) {
Adc* adc = ((Adc*[])ADC_INSTS)[ai];
// ADC clock setup
GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN = false;
SYNC(GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN);
GCLK->PCHCTRL[ADC0_GCLK_ID + ai].reg = GCLK_PCHCTRL_GEN_GCLK1 | GCLK_PCHCTRL_CHEN; // 48MHz startup code programmed
SYNC(!GCLK->PCHCTRL[ADC0_GCLK_ID + ai].bit.CHEN);
adc->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV32_Val; // 1.5MHZ adc clock
// ADC setup
// Preloaded data (fixed for all ADC instances hence not loaded by DMA)
adc->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // VRefA pin
SYNC(adc->SYNCBUSY.bit.REFCTRL);
adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; // ... ADC_CTRLB_RESSEL_16BIT_Val
SYNC(adc->SYNCBUSY.bit.CTRLB);
adc->SAMPCTRL.bit.SAMPLEN = (6 - 1); // Sampling clocks
//adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_16 | ADC_AVGCTRL_ADJRES(4); // 16 Accumulated conversions and shift 4 to get oversampled 12 bits result
//SYNC(adc->SYNCBUSY.bit.AVGCTRL);
// Registers loaded by DMA
adc->DSEQCTRL.bit.INPUTCTRL = true;
adc->DSEQCTRL.bit.AUTOSTART = true; // Start conversion after DMA sequence
adc->CTRLA.bit.ENABLE = true; // Enable ADC
SYNC(adc->SYNCBUSY.bit.ENABLE);
}
#endif // ADC_IS_REQUIRED
}
void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if ADC_IS_REQUIRED
LOOP_L_N(pi, COUNT(adc_pins)) {
if (adc_pin == adc_pins[pi]) {
HAL_adc_result = HAL_adc_results[pi];
return;
}
}
#endif
HAL_adc_result = 0xFFFF;
}
#endif // __SAMD51__

View File

@@ -1,177 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define CPU_32_BIT
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "timers.h"
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
#include "MarlinSerial_AGCM4.h"
// Serial ports
// MYSERIAL0 required before MarlinSerial includes!
#if SERIAL_PORT == -1
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 0
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial3
#elif SERIAL_PORT == 3
#define MYSERIAL0 Serial4
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#elif SERIAL_PORT_2 == -1
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial3
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial4
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#ifdef DGUS_SERIAL_PORT
#if DGUS_SERIAL_PORT == SERIAL_PORT
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#elif DGUS_SERIAL_PORT == -1
#define DGUS_SERIAL Serial
#elif DGUS_SERIAL_PORT == 0
#define DGUS_SERIAL Serial1
#elif DGUS_SERIAL_PORT == 1
#define DGUS_SERIAL Serial2
#elif DGUS_SERIAL_PORT == 2
#define DGUS_SERIAL Serial3
#elif DGUS_SERIAL_PORT == 2
#define DGUS_SERIAL Serial4
#else
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
#endif // ADAFRUIT_GRAND_CENTRAL_M4
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
#define HAL_SERVO_LIB Servo
//
// Interrupts
//
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
#define ISRS_ENABLED() (!__get_PRIMASK())
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
#define cli() __disable_irq() // Disable interrupts
#define sei() __enable_irq() // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
//
// EEPROM
//
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
//
// ADC
//
extern uint16_t HAL_adc_result; // Most recent ADC conversion
#define HAL_ANALOG_SELECT(pin)
void HAL_adc_init();
//#define HAL_ADC_FILTERED // Disable Marlin's oversampling. The HAL filters ADC values.
#define HAL_ADC_RESOLUTION 10 // ... 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
void HAL_adc_start_conversion(const uint8_t adc_pin);
inline uint16_t HAL_adc_get_result() { return HAL_adc_result; }
//
// Pin Map
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
//
// Tone
//
void toneInit();
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
void noTone(const pin_t _pin);
// Enable hooks into idle and setup for HAL
void HAL_init();
/*
#define HAL_IDLETASK 1
void HAL_idletask();
*/
//
// Utility functions
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
int freeMemory();
#pragma GCC diagnostic pop
#ifdef __cplusplus
extern "C" {
#endif
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
#ifdef __cplusplus
}
#endif

View File

@@ -1,55 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
/**
* Framework doesn't define some serial to save sercom resources
* hence if these are used I need to define them
*/
#include "../../inc/MarlinConfig.h"
#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
Uart Serial2(&sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
void SERCOM4_0_Handler() { Serial2.IrqHandler(); }
void SERCOM4_1_Handler() { Serial2.IrqHandler(); }
void SERCOM4_2_Handler() { Serial2.IrqHandler(); }
void SERCOM4_3_Handler() { Serial2.IrqHandler(); }
#endif
#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2
Uart Serial3(&sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
void SERCOM1_0_Handler() { Serial3.IrqHandler(); }
void SERCOM1_1_Handler() { Serial3.IrqHandler(); }
void SERCOM1_2_Handler() { Serial3.IrqHandler(); }
void SERCOM1_3_Handler() { Serial3.IrqHandler(); }
#endif
#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3
Uart Serial4(&sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
void SERCOM5_0_Handler() { Serial4.IrqHandler(); }
void SERCOM5_1_Handler() { Serial4.IrqHandler(); }
void SERCOM5_2_Handler() { Serial4.IrqHandler(); }
void SERCOM5_3_Handler() { Serial4.IrqHandler(); }
#endif
#endif // ADAFRUIT_GRAND_CENTRAL_M4

View File

@@ -1,51 +0,0 @@
/**
* @file QSPIFlash.h
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach and Dean Miller for Adafruit Industries LLC
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* Derived from Adafruit_SPIFlash class with no SdFat references
*
*/
#pragma once
#include "Adafruit_SPIFlashBase.h"
// This class extends Adafruit_SPIFlashBase by adding caching support.
//
// This class will use 4096 Bytes of RAM as a block cache.
class QSPIFlash {
public:
static void begin();
static size_t size();
static uint8_t readByte(const uint32_t address);
static void writeByte(const uint32_t address, const uint8_t v);
static void flush();
private:
static Adafruit_SPIFlashBase * _flashBase;
static uint8_t _buf[SFLASH_SECTOR_SIZE];
static uint32_t _addr;
};
extern QSPIFlash qspi;

View File

@@ -1,226 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* This comes from Arduino library which at the moment is buggy and uncompilable
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "../shared/Marduino.h"
#include "../shared/servo.h"
#include "../shared/servo_private.h"
#include "SAMD51.h"
#include "timers.h"
#define __TC_GCLK_ID(t) TC##t##_GCLK_ID
#define _TC_GCLK_ID(t) __TC_GCLK_ID(t)
#define TC_GCLK_ID _TC_GCLK_ID(SERVO_TC)
#define _TC_PRESCALER(d) TC_CTRLA_PRESCALER_DIV##d##_Val
#define TC_PRESCALER(d) _TC_PRESCALER(d)
#define __SERVO_IRQn(t) TC##t##_IRQn
#define _SERVO_IRQn(t) __SERVO_IRQn(t)
#define SERVO_IRQn _SERVO_IRQn(SERVO_TC)
#define HAL_SERVO_TIMER_ISR() TC_HANDLER(SERVO_TC)
#define TIMER_TCCHANNEL(t) ((t) & 1)
#define TC_COUNTER_START_VAL 0xFFFF
static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)
FORCE_INLINE static uint16_t getTimerCount() {
Tc * const tc = TimerConfig[SERVO_TC].pTimer;
tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB || tc->COUNT16.SYNCBUSY.bit.COUNT);
return tc->COUNT16.COUNT.reg;
}
// ----------------------------
// Interrupt handler for the TC
// ----------------------------
HAL_SERVO_TIMER_ISR() {
Tc * const tc = TimerConfig[SERVO_TC].pTimer;
const timer16_Sequence_t timer =
#ifndef _useTimer1
_timer2
#elif !defined(_useTimer2)
_timer1
#else
(tc->COUNT16.INTFLAG.reg & tc->COUNT16.INTENSET.reg & TC_INTFLAG_MC0) ? _timer1 : _timer2
#endif
;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
if (currentServoIndex[timer] < 0) {
#if defined(_useTimer1) && defined(_useTimer2)
if (currentServoIndex[timer ^ 1] >= 0) {
// Wait for both channels
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = (tcChannel == 0) ? TC_INTFLAG_MC0 : TC_INTFLAG_MC1;
return;
}
#endif
tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL;
SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT);
}
else if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive)
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
// Select the next servo controlled by this timer
currentServoIndex[timer]++;
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive) // check if activated
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)SERVO(timer, currentServoIndex[timer]).ticks;
}
else {
// finished all channels so wait for the refresh period to expire before starting over
currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
const uint16_t tcCounterValue = getTimerCount();
if ((TC_COUNTER_START_VAL - tcCounterValue) + 4UL < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
tc->COUNT16.CC[tcChannel].reg = TC_COUNTER_START_VAL - (uint16_t)usToTicks(REFRESH_INTERVAL);
else
tc->COUNT16.CC[tcChannel].reg = (uint16_t)(tcCounterValue - 4UL); // at least REFRESH_INTERVAL has elapsed
}
if (tcChannel == 0) {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0;
}
else {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
// Clear the interrupt
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1;
}
}
void initISR(timer16_Sequence_t timer) {
Tc * const tc = TimerConfig[SERVO_TC].pTimer;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
static bool initialized = false; // Servo TC has been initialized
if (!initialized) {
NVIC_DisableIRQ(SERVO_IRQn);
// Disable the timer
tc->COUNT16.CTRLA.bit.ENABLE = false;
SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE);
// Select GCLK0 as timer/counter input clock source
GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN = false;
SYNC(GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN);
GCLK->PCHCTRL[TC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; // 120MHz startup code programmed
SYNC(!GCLK->PCHCTRL[TC_GCLK_ID].bit.CHEN);
// Reset the timer
tc->COUNT16.CTRLA.bit.SWRST = true;
SYNC(tc->COUNT16.SYNCBUSY.bit.SWRST);
SYNC(tc->COUNT16.CTRLA.bit.SWRST);
// Set timer counter mode to 16 bits
tc->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16;
// Set timer counter mode as normal PWM
tc->COUNT16.WAVE.bit.WAVEGEN = TCC_WAVE_WAVEGEN_NPWM_Val;
// Set the prescaler factor
tc->COUNT16.CTRLA.bit.PRESCALER = TC_PRESCALER(SERVO_TIMER_PRESCALER);
// Count down
tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_DIR;
SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB);
// Reset all servo indexes
memset((void *)currentServoIndex, 0xFF, sizeof(currentServoIndex));
// Configure interrupt request
NVIC_ClearPendingIRQ(SERVO_IRQn);
NVIC_SetPriority(SERVO_IRQn, 5);
NVIC_EnableIRQ(SERVO_IRQn);
initialized = true;
}
if (!tc->COUNT16.CTRLA.bit.ENABLE) {
// Reset the timer counter
tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL;
SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT);
// Enable the timer and start it
tc->COUNT16.CTRLA.bit.ENABLE = true;
SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE);
}
// First interrupt request after 1 ms
tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)usToTicks(1000UL);
if (tcChannel == 0 ) {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
// Clear pending match interrupt
tc->COUNT16.INTFLAG.reg = TC_INTENSET_MC0;
// Enable the match channel interrupt request
tc->COUNT16.INTENSET.reg = TC_INTENSET_MC0;
}
else {
SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
// Clear pending match interrupt
tc->COUNT16.INTFLAG.reg = TC_INTENSET_MC1;
// Enable the match channel interrupt request
tc->COUNT16.INTENSET.reg = TC_INTENSET_MC1;
}
}
void finISR(timer16_Sequence_t timer) {
Tc * const tc = TimerConfig[SERVO_TC].pTimer;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
// Disable the match channel interrupt request
tc->COUNT16.INTENCLR.reg = (tcChannel == 0) ? TC_INTENCLR_MC0 : TC_INTENCLR_MC1;
if (true
#if defined(_useTimer1) && defined(_useTimer2)
&& (tc->COUNT16.INTENCLR.reg & (TC_INTENCLR_MC0|TC_INTENCLR_MC1)) == 0
#endif
) {
// Disable the timer if not used
tc->COUNT16.CTRLA.bit.ENABLE = false;
SYNC(tc->COUNT16.SYNCBUSY.bit.ENABLE);
}
}
#endif // HAS_SERVOS
#endif // __SAMD51__

View File

@@ -1,66 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#if ENABLED(EEPROM_SETTINGS) && NONE(QSPI_EEPROM, FLASH_EEPROM_EMULATION)
#include "../shared/eeprom_api.h"
size_t PersistentStore::capacity() { return E2END + 1; }
bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
const uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
if (v != eeprom_read_byte(p)) {
eeprom_write_byte(p, v);
delay(2);
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
}
}
crc16(crc, &v, 1);
pos++;
value++;
}
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
}
return false;
}
#endif // EEPROM_SETTINGS && !(QSPI_EEPROM || FLASH_EEPROM_EMULATION)
#endif // __SAMD51__

View File

@@ -1,96 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#if ENABLED(FLASH_EEPROM_EMULATION)
#include "../shared/eeprom_api.h"
#define NVMCTRL_CMD(c) do{ \
SYNC(!NVMCTRL->STATUS.bit.READY); \
NVMCTRL->INTFLAG.bit.DONE = true; \
NVMCTRL->CTRLB.reg = c | NVMCTRL_CTRLB_CMDEX_KEY; \
SYNC(NVMCTRL->INTFLAG.bit.DONE); \
}while(0)
#define NVMCTRL_FLUSH() do{ \
if (NVMCTRL->SEESTAT.bit.LOAD) \
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_SEEFLUSH); \
}while(0)
size_t PersistentStore::capacity() {
const uint8_t psz = NVMCTRL->SEESTAT.bit.PSZ,
sblk = NVMCTRL->SEESTAT.bit.SBLK;
return (!psz && !sblk) ? 0
: (psz <= 2) ? (0x200 << psz)
: (sblk == 1 || psz == 3) ? 4096
: (sblk == 2 || psz == 4) ? 8192
: (sblk <= 4 || psz == 5) ? 16384
: (sblk >= 9 && psz == 7) ? 65536
: 32768;
}
bool PersistentStore::access_start() {
NVMCTRL->SEECFG.reg = NVMCTRL_SEECFG_WMODE_BUFFERED; // Buffered mode and segment reallocation active
if (NVMCTRL->SEESTAT.bit.RLOCK)
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_USEE); // Unlock E2P data write access
return true;
}
bool PersistentStore::access_finish() {
NVMCTRL_FLUSH();
if (!NVMCTRL->SEESTAT.bit.LOCK)
NVMCTRL_CMD(NVMCTRL_CTRLB_CMD_LSEE); // Lock E2P data write access
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
while (size--) {
const uint8_t v = *value;
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
if (NVMCTRL->INTFLAG.bit.SEESFULL)
NVMCTRL_FLUSH(); // Next write will trigger a sector reallocation. I need to flush 'pagebuffer'
((volatile uint8_t *)SEEPROM_ADDR)[pos] = v;
SYNC(!NVMCTRL->INTFLAG.bit.SEEWRC);
crc16(crc, &v, 1);
pos++;
value++;
}
return false;
}
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
value++;
}
return false;
}
#endif // FLASH_EEPROM_EMULATION
#endif // __SAMD51__

View File

@@ -1,26 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#if USE_FALLBACK_EEPROM && NONE(SDCARD_EEPROM_EMULATION, SRAM_EEPROM_EMULATION)
#define FLASH_EEPROM_EMULATION
#endif

View File

@@ -1,48 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Test SAMD51 specific configuration values for errors at compile-time.
*/
#if ENABLED(FLASH_EEPROM_EMULATION)
#warning "Did you activate the SmartEEPROM? See https://github.com/GMagician/SAMD51-SmartEEprom-Manager/releases"
#endif
#if defined(ADAFRUIT_GRAND_CENTRAL_M4) && SD_CONNECTION_IS(CUSTOM_CABLE)
#error "No custom SD drive cable defined for this board."
#endif
#if defined(MAX6675_SCK_PIN) && defined(MAX6675_DO_PIN) && (MAX6675_SCK_PIN == SCK1 || MAX6675_DO_PIN == MISO1)
#error "OnBoard SPI BUS can't be shared with other devices."
#endif
#if ENABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is not yet implemented for SAMD51. Disable EMERGENCY_PARSER to continue."
#endif
#if ENABLED(SDIO_SUPPORT)
#error "SDIO_SUPPORT is not supported on SAMD51."
#endif
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif

View File

@@ -1,167 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __SAMD51__
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "../../inc/MarlinConfig.h"
#include "timers.h"
// --------------------------------------------------------------------------
// Local defines
// --------------------------------------------------------------------------
#define NUM_HARDWARE_TIMERS 8
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS+1] = {
{ {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper
{ {.pTc=TC1}, TC1_IRQn, TC_PRIORITY(1) }, // 1 - stepper (needed by 32 bit timers)
{ {.pTc=TC2}, TC2_IRQn, TC_PRIORITY(2) }, // 2 - tone (framework)
{ {.pTc=TC3}, TC3_IRQn, TC_PRIORITY(3) }, // 3 - servo
{ {.pTc=TC4}, TC4_IRQn, TC_PRIORITY(4) }, // 4 - software serial
{ {.pTc=TC5}, TC5_IRQn, TC_PRIORITY(5) },
{ {.pTc=TC6}, TC6_IRQn, TC_PRIORITY(6) },
{ {.pTc=TC7}, TC7_IRQn, TC_PRIORITY(7) },
{ {.pRtc=RTC}, RTC_IRQn, TC_PRIORITY(8) } // 8 - temperature
};
// --------------------------------------------------------------------------
// Private functions
// --------------------------------------------------------------------------
FORCE_INLINE void Disable_Irq(IRQn_Type irq) {
NVIC_DisableIRQ(irq);
// 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();
}
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
// Disable interrupt, just in case it was already enabled
Disable_Irq(irq);
if (timer_num == RTC_TIMER_NUM) {
Rtc * const rtc = TimerConfig[timer_num].pRtc;
// Disable timer interrupt
rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
// RTC clock setup
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768KHz oscillator
// Stop timer, just in case, to be able to reconfigure it
rtc->MODE0.CTRLA.bit.ENABLE = false;
SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
// Mode, reset counter on match
rtc->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_MODE_COUNT32 | RTC_MODE0_CTRLA_MATCHCLR;
// Set compare value
rtc->MODE0.COMP[0].reg = (32768 + frequency / 2) / frequency;
SYNC(rtc->MODE0.SYNCBUSY.bit.COMP0);
// Enable interrupt on compare
rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0; // reset pending interrupt
rtc->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0; // enable compare 0 interrupt
// And start timer
rtc->MODE0.CTRLA.bit.ENABLE = true;
SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
}
else {
Tc * const tc = TimerConfig[timer_num].pTc;
// Disable timer interrupt
tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
// TCn clock setup
const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num]; // TC clock are preceeded by TCC ones
GCLK->PCHCTRL[clockID].bit.CHEN = false;
SYNC(GCLK->PCHCTRL[clockID].bit.CHEN);
GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; // 120MHz startup code programmed
SYNC(!GCLK->PCHCTRL[clockID].bit.CHEN);
// Stop timer, just in case, to be able to reconfigure it
tc->COUNT32.CTRLA.bit.ENABLE = false;
SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
// Reset timer
tc->COUNT32.CTRLA.bit.SWRST = true;
SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST);
// Wave mode, reset counter on overflow on 0 (I use count down to prevent double buffer use)
tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1;
tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_DIR;
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
// Set compare value
tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency;
// Enable interrupt on compare
tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF; // reset pending interrupt
tc->COUNT32.INTENSET.reg = TC_INTENSET_OVF; // enable overflow interrupt
// And start timer
tc->COUNT32.CTRLA.bit.ENABLE = true;
SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
}
// Finally, enable IRQ
NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
NVIC_EnableIRQ(irq);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
Disable_Irq(irq);
}
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
#endif // __SAMD51__

View File

@@ -1,134 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
#define RTC_TIMER_NUM 8 // This is not a TC but a RTC
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // index of timer to use for stepper (also +1 for 32bits counter)
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TEMP_TIMER_NUM RTC_TIMER_NUM // index of timer to use for temperature
#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
#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(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#define TC_PRIORITY(t) (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2 \
: (t == TEMP_TIMER_NUM) ? 6 \
: 7
#define _TC_HANDLER(t) void TC##t##_Handler()
#define TC_HANDLER(t) _TC_HANDLER(t)
#define HAL_STEP_TIMER_ISR() TC_HANDLER(STEP_TIMER_NUM)
#if STEP_TIMER_NUM != PULSE_TIMER_NUM
#define HAL_PULSE_TIMER_ISR() TC_HANDLER(PULSE_TIMER_NUM)
#endif
#if TEMP_TIMER_NUM == RTC_TIMER_NUM
#define HAL_TEMP_TIMER_ISR() void RTC_Handler()
#else
#define HAL_TEMP_TIMER_ISR() TC_HANDLER(TEMP_TIMER_NUM)
#endif
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
typedef struct {
union {
Tc *pTc;
Rtc *pRtc;
};
IRQn_Type IRQ_Id;
uint8_t priority;
} tTimerConfig;
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
extern const tTimerConfig TimerConfig[];
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
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) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
tc->COUNT32.CC[0].reg = HAL_TIMER_TYPE_MAX - compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
return (hal_timer_t)(HAL_TIMER_TYPE_MAX - tc->COUNT32.CC[0].reg);
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
// Should never be called with timer RTC_TIMER_NUM
Tc * const tc = TimerConfig[timer_num].pTc;
tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
return HAL_TIMER_TYPE_MAX - tc->COUNT32.COUNT.reg;
}
void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
if (timer_num == RTC_TIMER_NUM) {
Rtc * const rtc = TimerConfig[timer_num].pRtc;
// Clear interrupt flag
rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
}
else {
Tc * const tc = TimerConfig[timer_num].pTc;
// Clear interrupt flag
tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
}
}
#define HAL_timer_isr_epilogue(timer_num)

View File

@@ -1,53 +0,0 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
void watchdog_init() {
// The low-power oscillator used by the WDT runs at 32,768 Hz with
// a 1:32 prescale, thus 1024 Hz, though probably not super precise.
// Setup WDT clocks
MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
MCLK->APBAMASK.bit.WDT_ = true;
OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
SYNC(WDT->SYNCBUSY.bit.ENABLE);
WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
WDT->CONFIG.reg = WDT_CONFIG_PER_CYC4096; // Set at least 4s period for chip reset
HAL_watchdog_refresh();
WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
SYNC(WDT->SYNCBUSY.bit.ENABLE);
}
#endif // USE_WATCHDOG
#endif // __SAMD51__

View File

@@ -1,138 +0,0 @@
/**
* 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
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "HAL.h"
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
#if HAS_TMC_SW_SERIAL
#include "SoftwareSerial.h"
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
#include <stm32f7xx_ll_pwr.h>
#elif STM32F4xx
#include <stm32f4xx_ll_pwr.h>
#else
#error "SRAM_EEPROM_EMULATION is currently only supported for STM32F4xx and STM32F7xx"
#endif
#endif
// ------------------------
// Public Variables
// ------------------------
uint16_t HAL_adc_result;
// ------------------------
// Public functions
// ------------------------
// Needed for DELAY_NS() / DELAY_US() on CORTEX-M7
#if (defined(__arm__) || defined(__thumb__)) && __CORTEX_M == 7
// HAL pre-initialization task
// Force the preinit function to run between the premain() and main() function
// of the STM32 arduino core
__attribute__((constructor (102)))
void HAL_preinit() {
enableCycleCounter();
}
#endif
// HAL initialization task
void HAL_init() {
FastIO_init();
#if ENABLED(SDSUPPORT)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
#if PIN_EXISTS(LED)
OUT_WRITE(LED_PIN, LOW);
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
// Enable access to backup SRAM
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_BKPSRAM_CLK_ENABLE();
// Enable backup regulator
LL_PWR_EnableBkUpRegulator();
// Wait until backup regulator is initialized
while (!LL_PWR_IsActiveFlag_BRR());
#endif // EEPROM_EMULATED_SRAM
#if HAS_TMC_SW_SERIAL
SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0);
#endif
}
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
uint8_t HAL_get_reset_source() {
return
#ifdef RCC_FLAG_IWDGRST // Some sources may not exist...
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG :
#endif
#ifdef RCC_FLAG_IWDG1RST
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDG1RST) ? RST_WATCHDOG :
#endif
#ifdef RCC_FLAG_IWDG2RST
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDG2RST) ? RST_WATCHDOG :
#endif
#ifdef RCC_FLAG_SFTRST
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST) ? RST_SOFTWARE :
#endif
#ifdef RCC_FLAG_PINRST
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) ? RST_EXTERNAL :
#endif
#ifdef RCC_FLAG_PORRST
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) ? RST_POWER_ON :
#endif
0
;
}
void _delay_ms(const int delay_ms) { delay(delay_ms); }
extern "C" {
extern unsigned int _ebss; // end of bss section
}
// ------------------------
// ADC
// ------------------------
// TODO: Make sure this doesn't cause any delay
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
void flashFirmware(const int16_t) { NVIC_SystemReset(); }
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC

View File

@@ -1,226 +0,0 @@
/**
* 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
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#define CPU_32_BIT
#include "../../core/macros.h"
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "../../inc/MarlinConfigPre.h"
#include <stdint.h>
#ifdef USBCON
#include <USBSerial.h>
#endif
// ------------------------
// Defines
// ------------------------
#if SERIAL_PORT == 0
#error "SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
#elif SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 Serial3
#elif SERIAL_PORT == 4
#define MYSERIAL0 Serial4
#elif SERIAL_PORT == 5
#define MYSERIAL0 Serial5
#elif SERIAL_PORT == 6
#define MYSERIAL0 Serial6
#else
#error "SERIAL_PORT must be from -1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#define NUM_SERIAL 2
#if SERIAL_PORT_2 == 0
#error "SERIAL_PORT_2 cannot be 0. (Port 0 does not exist.) Please update your configuration."
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
#elif SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#elif SERIAL_PORT_2 == 4
#define MYSERIAL1 Serial4
#elif SERIAL_PORT_2 == 5
#define MYSERIAL1 Serial5
#elif SERIAL_PORT_2 == 6
#define MYSERIAL1 Serial6
#else
#error "SERIAL_PORT_2 must be from -1 to 6. Please update your configuration."
#endif
#else
#define NUM_SERIAL 1
#endif
#if HAS_DGUS_LCD
#if DGUS_SERIAL_PORT == 0
#error "DGUS_SERIAL_PORT cannot be 0. (Port 0 does not exist.) Please update your configuration."
#elif DGUS_SERIAL_PORT == SERIAL_PORT
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
#elif DGUS_SERIAL_PORT == -1
#define DGUS_SERIAL SerialUSB
#elif DGUS_SERIAL_PORT == 1
#define DGUS_SERIAL Serial1
#elif DGUS_SERIAL_PORT == 2
#define DGUS_SERIAL Serial2
#elif DGUS_SERIAL_PORT == 3
#define DGUS_SERIAL Serial3
#elif DGUS_SERIAL_PORT == 4
#define DGUS_SERIAL Serial4
#elif DGUS_SERIAL_PORT == 5
#define DGUS_SERIAL Serial5
#elif DGUS_SERIAL_PORT == 6
#define DGUS_SERIAL Serial6
#else
#error "DGUS_SERIAL_PORT must be from -1 to 6. Please update your configuration."
#endif
#define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.availableForWrite
#endif
#include "timers.h"
/**
* TODO: review this to return 1 for pins that are not analog input
*/
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) (p)
#endif
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
#define ISRS_ENABLED() (!__get_PRIMASK())
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
#define cli() __disable_irq()
#define sei() __enable_irq()
// On AVR this is in math.h?
#define square(x) ((x)*(x))
#ifndef strncpy_P
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
#endif
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*(addr))
// ------------------------
// Types
// ------------------------
typedef int16_t pin_t;
#define HAL_SERVO_LIB libServo
// ------------------------
// Public Variables
// ------------------------
// result of last ADC conversion
extern uint16_t HAL_adc_result;
// ------------------------
// Public functions
// ------------------------
// Memory related
#define __bss_end __bss_end__
// Enable hooks into setup for HAL
void HAL_init();
// Clear reset reason
void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
void _delay_ms(const int delay);
extern "C" char* _sbrk(int incr);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static inline int freeMemory() {
volatile char top;
return &top - reinterpret_cast<char*>(_sbrk(0));
}
#pragma GCC diagnostic pop
//
// EEPROM
//
// Wire library should work for i2c EEPROMs
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
void eeprom_read_block(void *__dst, const void *__src, size_t __n);
void eeprom_update_block(const void *__src, void *__dst, size_t __n);
//
// ADC
//
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
inline void HAL_adc_init() {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define PLATFORM_M997_SUPPORT
void flashFirmware(const int16_t);

View File

@@ -1,274 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC)
#include <stdint.h>
#include <stdbool.h>
//#include "SdMscDriver.h"
//#include "usbd_msc_bot.h"
//#include "usbd_msc_scsi.h"
//#include "usbd_msc_composite.h"
//#include "usbd_msc_cdc_composite.h"
//#include "usbd_msc_data.h"
#if defined(STM32F103xE) || defined(STM32F103xG)
#include <stm32f1xx_hal_rcc_ex.h>
#include <stm32f1xx_hal_sd.h>
#elif defined(STM32F4xx)
#include <stm32f4xx_hal_rcc.h>
#include <stm32f4xx_hal_dma.h>
#include <stm32f4xx_hal_gpio.h>
#include <stm32f4xx_hal_sd.h>
#elif defined(STM32F7xx)
#include <stm32f7xx_hal_rcc.h>
#include <stm32f7xx_hal_dma.h>
#include <stm32f7xx_hal_gpio.h>
#include <stm32f7xx_hal_sd.h>
#else
#error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
#endif
SD_HandleTypeDef hsd; // create SDIO structure
#define TRANSFER_CLOCK_DIV ((uint8_t)SDIO_INIT_CLK_DIV/40)
#ifndef USBD_OK
#define USBD_OK 0
#endif
void go_to_transfer_speed() {
SD_InitTypeDef Init;
/* Default SDIO peripheral configuration for SD card initialization */
Init.ClockEdge = hsd.Init.ClockEdge;
Init.ClockBypass = hsd.Init.ClockBypass;
Init.ClockPowerSave = hsd.Init.ClockPowerSave;
Init.BusWide = hsd.Init.BusWide;
Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
Init.ClockDiv = TRANSFER_CLOCK_DIV;
/* Initialize SDIO peripheral interface with default configuration */
SDIO_Init(hsd.Instance, Init);
}
void SD_LowLevel_Init(void) {
uint32_t tempreg;
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
__HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // define D1-D3 only if have a four bit wide SDIO bus
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
#endif
// Configure PD.02 CMD line
GPIO_InitStruct.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
RCC->APB2RSTR &= ~RCC_APB2RSTR_SDIORST_Msk; // take SDIO out of reset
RCC->APB2ENR |= RCC_APB2RSTR_SDIORST_Msk; // enable SDIO clock
// Enable the DMA2 Clock
//Initialize the SDIO (with initial <400Khz Clock)
tempreg = 0; //Reset value
tempreg |= SDIO_CLKCR_CLKEN; //Clock is enabled
tempreg |= (uint32_t)0x76; //Clock Divider. Clock = 48000/(118+2) = 400Khz
//Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
SDIO->CLKCR = tempreg;
//Power up the SDIO
SDIO->POWER = 0x03;
}
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
UNUSED(hsd); /* Prevent unused argument(s) compilation warning */
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock
}
constexpr uint8_t SD_RETRY_COUNT = (1
#if ENABLED(SD_CHECK_AND_RETRY)
+ 2
#endif
);
bool SDIO_Init() {
//init SDIO and get SD card info
uint8_t retryCnt = SD_RETRY_COUNT;
bool status;
hsd.Instance = SDIO;
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
SD_LowLevel_Init();
uint8_t retry_Cnt = retryCnt;
for (;;) {
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
}
go_to_transfer_speed();
#if defined(SDIO_D1_PIN) && defined(SDIO_D2_PIN) && defined(SDIO_D3_PIN) // go to 4 bit wide mode if pins are defined
retry_Cnt = retryCnt;
for (;;) {
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required
if (!--retry_Cnt) break;
}
if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
SD_LowLevel_Init();
retry_Cnt = retryCnt;
for (;;) {
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
}
}
#endif
return true;
}
void init_SDIO_pins(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/**SDIO GPIO Configuration
PC8 ------> SDIO_D0
PC12 ------> SDIO_CK
PD2 ------> SDIO_CMD
*/
GPIO_InitStruct.Pin = GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
//bool SDIO_init() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
//bool SDIO_Init_C() { return (bool) (SD_SDIO_Init() ? 1 : 0);}
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
bool status;
hsd.Instance = SDIO;
uint8_t retryCnt = SD_RETRY_COUNT;
for (;;) {
bool status = (bool) HAL_SD_ReadBlocks(&hsd, (uint8_t*)dst, block, 1, 1000); // read one 512 byte block with 500mS timeout
status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK
if (!status) return false; // return passing status
if (!--retryCnt) return true; // return failing status if retries are exhausted
}
/*
return (bool) ((status_read | status_card) ? 1 : 0);
if (SDIO_GetCardState() != SDIO_CARD_TRANSFER) return false;
if (blockAddress >= SdCard.LogBlockNbr) return false;
if ((0x03 & (uint32_t)data)) return false; // misaligned data
if (SdCard.CardType != CARD_SDHC_SDXC) { blockAddress *= 512U; }
if (!SDIO_CmdReadSingleBlock(blockAddress)) {
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS);
dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL);
return false;
}
while (!SDIO_GET_FLAG(SDIO_STA_DATAEND | SDIO_STA_TRX_ERROR_FLAGS)) {}
dma_disable(SDIO_DMA_DEV, SDIO_DMA_CHANNEL);
if (SDIO->STA & SDIO_STA_RXDAVL) {
while (SDIO->STA & SDIO_STA_RXDAVL) (void)SDIO->FIFO;
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
return false;
}
if (SDIO_GET_FLAG(SDIO_STA_TRX_ERROR_FLAGS)) {
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
return false;
}
SDIO_CLEAR_FLAG(SDIO_ICR_CMD_FLAGS | SDIO_ICR_DATA_FLAGS);
*/
return true;
}
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
bool status;
hsd.Instance = SDIO;
uint8_t retryCnt = SD_RETRY_COUNT;
for (;;) {
status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout
status |= (bool) HAL_SD_GetCardState(&hsd); // make sure all is OK
if (!status) return (bool) status; // return passing status
if (!--retryCnt) return (bool) status; // return failing status if retries are exhausted
}
}
#endif // SDIO_SUPPORT

View File

@@ -1,62 +0,0 @@
/**
* 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
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
#if HAS_SERVOS
#include "Servo.h"
static uint_fast8_t servoCount = 0;
constexpr millis_t servoDelay[] = SERVO_DELAY;
static_assert(COUNT(servoDelay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
libServo::libServo()
: delay(servoDelay[servoCount++])
{}
int8_t libServo::attach(const int pin) {
if (servoCount >= MAX_SERVOS) return -1;
if (pin > 0) servo_pin = pin;
return super::attach(servo_pin);
}
int8_t libServo::attach(const int pin, const int min, const int max) {
if (servoCount >= MAX_SERVOS) return -1;
if (pin > 0) servo_pin = pin;
return super::attach(servo_pin, min, max);
}
void libServo::move(const int value) {
if (attach(0) >= 0) {
write(value);
safe_delay(delay);
#if ENABLED(DEACTIVATE_SERVOS_AFTER_MOVE)
detach();
#endif
}
}
#endif // HAS_SERVOS
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC

View File

@@ -1,41 +0,0 @@
/**
* 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
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <Servo.h>
#include "../../core/millis_t.h"
// Inherit and expand on the official library
class libServo : public Servo {
public:
libServo();
int8_t attach(const int pin);
int8_t attach(const int pin, const int min, const int max);
void move(const int value);
private:
typedef Servo super;
int servo_pin = 0;
millis_t delay = 0;
};

View File

@@ -1,395 +0,0 @@
/*
* SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (http://ladyada.net)
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
* -- STM32 support by Armin van der Togt
*
* 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
*
* The latest version of this library can always be found at
* http://arduiniana.org.
*/
//
// Includes
//
#if defined(PLATFORMIO) && defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "SoftwareSerial.h"
#include "timers.h"
#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge).
// defined in bit-periods
#define HALFDUPLEX_SWITCH_DELAY 5
// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
// The order is based on (lack of) features and compare channels, we choose the simplest available
// because we only need an update interrupt
#if !defined(TIMER_SERIAL)
#if defined (TIM18_BASE)
#define TIMER_SERIAL TIM18
#elif defined (TIM7_BASE)
#define TIMER_SERIAL TIM7
#elif defined (TIM6_BASE)
#define TIMER_SERIAL TIM6
#elif defined (TIM22_BASE)
#define TIMER_SERIAL TIM22
#elif defined (TIM21_BASE)
#define TIMER_SERIAL TIM21
#elif defined (TIM17_BASE)
#define TIMER_SERIAL TIM17
#elif defined (TIM16_BASE)
#define TIMER_SERIAL TIM16
#elif defined (TIM15_BASE)
#define TIMER_SERIAL TIM15
#elif defined (TIM14_BASE)
#define TIMER_SERIAL TIM14
#elif defined (TIM13_BASE)
#define TIMER_SERIAL TIM13
#elif defined (TIM11_BASE)
#define TIMER_SERIAL TIM11
#elif defined (TIM10_BASE)
#define TIMER_SERIAL TIM10
#elif defined (TIM12_BASE)
#define TIMER_SERIAL TIM12
#elif defined (TIM19_BASE)
#define TIMER_SERIAL TIM19
#elif defined (TIM9_BASE)
#define TIMER_SERIAL TIM9
#elif defined (TIM5_BASE)
#define TIMER_SERIAL TIM5
#elif defined (TIM4_BASE)
#define TIMER_SERIAL TIM4
#elif defined (TIM3_BASE)
#define TIMER_SERIAL TIM3
#elif defined (TIM2_BASE)
#define TIMER_SERIAL TIM2
#elif defined (TIM20_BASE)
#define TIMER_SERIAL TIM20
#elif defined (TIM8_BASE)
#define TIMER_SERIAL TIM8
#elif defined (TIM1_BASE)
#define TIMER_SERIAL TIM1
#else
#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
#endif
#endif
//
// Statics
//
HardwareTimer SoftwareSerial::timer(TIMER_SERIAL);
const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast<IRQn_Type>(getTimerUpIrq(TIMER_SERIAL));
uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO);
SoftwareSerial *SoftwareSerial::active_listener = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
uint32_t SoftwareSerial::tx_buffer = 0;
int32_t SoftwareSerial::tx_bit_cnt = 0;
uint32_t SoftwareSerial::rx_buffer = 0;
int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
uint32_t SoftwareSerial::cur_speed = 0;
void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) {
timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority);
}
//
// Private methods
//
void SoftwareSerial::setSpeed(uint32_t speed) {
if (speed != cur_speed) {
timer.pause();
if (speed != 0) {
// Disable the timer
uint32_t clock_rate, cmp_value;
// Get timer clock
clock_rate = timer.getTimerClkFreq();
int pre = 1;
// Calculate prescale an compare value
do {
cmp_value = clock_rate / (speed * OVERSAMPLE);
if (cmp_value >= UINT16_MAX) {
clock_rate /= 2;
pre *= 2;
}
} while (cmp_value >= UINT16_MAX);
timer.setPrescaleFactor(pre);
timer.setOverflow(cmp_value);
timer.setCount(0);
timer.attachInterrupt(&handleInterrupt);
timer.resume();
NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority);
}
else
timer.detachInterrupt();
cur_speed = speed;
}
}
// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen() {
if (active_listener != this) {
// wait for any transmit to complete as we may change speed
while (active_out);
active_listener->stopListening();
rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
setSpeed(_speed);
active_listener = this;
if (!_half_duplex) active_in = this;
return true;
}
return false;
}
// Stop listening. Returns true if we were actually listening.
bool SoftwareSerial::stopListening() {
if (active_listener == this) {
// wait for any output to complete
while (active_out);
if (_half_duplex) setRXTX(false);
active_listener = nullptr;
active_in = nullptr;
// turn off ints
setSpeed(0);
return true;
}
return false;
}
inline void SoftwareSerial::setTX() {
if (_inverse_logic)
LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
else
LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
pinMode(_transmitPin, OUTPUT);
}
inline void SoftwareSerial::setRX() {
pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
}
inline void SoftwareSerial::setRXTX(bool input) {
if (_half_duplex) {
if (input) {
if (active_in != this) {
setRX();
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
active_in = this;
}
}
else {
if (active_in == this) {
setTX();
active_in = nullptr;
}
}
}
}
inline void SoftwareSerial::send() {
if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set.
if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop)
// Send data (including start and stop bits)
if (tx_buffer & 1)
LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
else
LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
tx_buffer >>= 1;
tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit
}
else { // Transmission finished
tx_tick_cnt = 1;
if (_output_pending) {
active_out = nullptr;
// In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
// been transmitted before allowing the switch to RX mode
}
else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
if (_half_duplex && active_listener == this) setRXTX(true);
active_out = nullptr;
}
}
}
}
//
// The receive routine called by the interrupt handler
//
inline void SoftwareSerial::recv() {
if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered
bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
if (!inbit) {
// got start bit
rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
rx_buffer = 0;
}
else
rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level
}
else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
if (inbit) {
// Stop-bit read complete. Add to buffer.
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
if (next != _receive_buffer_head) {
// save new data in buffer: tail points to byte destination
_receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
_receive_buffer_tail = next;
}
else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
_buffer_overflow = true;
}
// Full trame received. Restart waiting for start bit at next interrupt
rx_tick_cnt = 1;
rx_bit_cnt = -1;
}
else {
// data bits
rx_buffer >>= 1;
if (inbit) rx_buffer |= 0x80;
rx_bit_cnt++; // Prepare for next bit
rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
}
}
}
//
// Interrupt handling
//
/* static */
inline void SoftwareSerial::handleInterrupt(HardwareTimer*) {
if (active_in) active_in->recv();
if (active_out) active_out->send();
}
//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
_receivePin(receivePin),
_transmitPin(transmitPin),
_receivePinPort(digitalPinToPort(receivePin)),
_receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))),
_transmitPinPort(digitalPinToPort(transmitPin)),
_transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))),
_speed(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic),
_half_duplex(receivePin == transmitPin),
_output_pending(0),
_receive_buffer_tail(0),
_receive_buffer_head(0)
{
if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) {
/* Enable GPIO clock for tx and rx pin*/
set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin)));
set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin)));
}
else
_Error_Handler("ERROR: invalid pin number\n", -1);
}
//
// Destructor
//
SoftwareSerial::~SoftwareSerial() { end(); }
//
// Public methods
//
void SoftwareSerial::begin(long speed) {
#ifdef FORCE_BAUD_RATE
speed = FORCE_BAUD_RATE;
#endif
_speed = speed;
if (!_half_duplex) {
setTX();
setRX();
listen();
}
else
setTX();
}
void SoftwareSerial::end() {
stopListening();
}
// Read data from buffer
int SoftwareSerial::read() {
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) return -1;
// Read from "head"
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
return d;
}
int SoftwareSerial::available() {
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
size_t SoftwareSerial::write(uint8_t b) {
// wait for previous transmit to complete
_output_pending = 1;
while (active_out) { /* nada */ }
// add start and stop bits.
tx_buffer = b << 1 | 0x200;
if (_inverse_logic) tx_buffer = ~tx_buffer;
tx_bit_cnt = 0;
tx_tick_cnt = OVERSAMPLE;
setSpeed(_speed);
if (_half_duplex) setRXTX(false);
_output_pending = 0;
// make us active
active_out = this;
return 1;
}
void SoftwareSerial::flush() {
noInterrupts();
_receive_buffer_head = _receive_buffer_tail = 0;
interrupts();
}
int SoftwareSerial::peek() {
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) return -1;
// Read from "head"
return _receive_buffer[_receive_buffer_head];
}
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC

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